Add command entered to command error and command unknown message

This commit is contained in:
Theo Arends 2024-09-17 16:24:45 +02:00
parent 4f2b24f53d
commit a5730a76f9
14 changed files with 82 additions and 112 deletions

View File

@ -16,7 +16,7 @@ All notable changes to this project will be documented in this file.
### Changed
- Refactored I2C drivers HTU21, BH1750 and HYT
- Add entered command to MQTT command unknown message
- Add command entered to command error and command unknown message
### Fixed
- Shutter missing HOLD on shutterbutton (#22108)

View File

@ -144,7 +144,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
- ESP32 platform update from 2024.08.10 to 2024.08.11 [#22021](https://github.com/arendst/Tasmota/issues/22021)
- ESP32 LVGL library from v9.1.0 to v9.2.0 [#22031](https://github.com/arendst/Tasmota/issues/22031)
- GPIOViewer from v1.5.5 to v1.5.6
- Add entered command to MQTT command unknown message
- Add command entered to command error and command unknown message
- Energy BL09xx command ``CurrentSet`` input changed from Ampere to milliAmpere
- Energy force Apparent Power equals Active Power when (Calculated) Apparent Power is less than Active Power [#20653](https://github.com/arendst/Tasmota/issues/20653)
- Refactored I2C drivers HTU21, BH1750 and HYT

View File

@ -901,6 +901,8 @@
#endif
// Common
const char S_JSON_COMMAND_ERROR[] PROGMEM = "{\"" D_JSON_COMMAND "\":\"" D_JSON_ERROR "\"";
const char S_JSON_COMMAND_NVALUE_SPACE_UNIT[] PROGMEM = "{\"%s\":\"%d %s\"}";
const char S_JSON_COMMAND_LVALUE_SPACE_UNIT[] PROGMEM = "{\"%s\":\"%lu %s\"}";
const char S_JSON_COMMAND_SVALUE_SPACE_UNIT[] PROGMEM = "{\"%s\":\"%s %s\"}";

View File

@ -1321,6 +1321,14 @@ void ResponseClear(void) {
// TasmotaGlobal.mqtt_data = (const char*) nullptr; // Doesn't work on ESP32 as strlen() (in MqttPublishPayload) will fail (for obvious reasons)
}
void ResponseReplace(const char* rold, const char* rnew) {
TasmotaGlobal.mqtt_data.replace(rold, rnew);
}
bool ResponseStartsWith(const char* start_with) {
return TasmotaGlobal.mqtt_data.startsWith(start_with);
}
void ResponseJsonStart(void) {
// Insert a JSON start bracket {
TasmotaGlobal.mqtt_data.setCharAt(0,'{');

View File

@ -167,7 +167,7 @@ void CmndWifiTest(void)
// at the same time for testing the connection.
#ifdef USE_WEBSERVER
if (!WifiIsInManagerMode()) { ResponseCmndError(); return; }
if (!WifiIsInManagerMode()) { return; } // Command Error
if ( (XdrvMailbox.data_len > 0) ) {
@ -245,7 +245,7 @@ void CmndWifiTest(void)
}
}
#else
ResponseCmndError();
return; // Command Error
#endif //USE_WEBSERVER
}
@ -299,10 +299,6 @@ void ResponseCmndIdxChar(const char* value) {
Response_P(S_JSON_COMMAND_INDEX_SVALUE, XdrvMailbox.command, XdrvMailbox.index, EscapeJSONString(value).c_str());
}
void ResponseCmndIdxError(void) {
ResponseCmndIdxChar(PSTR(D_JSON_ERROR));
}
void ResponseCmndAll(uint32_t text_index, uint32_t count) {
uint32_t real_index = text_index;
ResponseClear();
@ -379,7 +375,6 @@ void CommandHandler(char* topicBuf, char* dataBuf, uint32_t data_len) {
char *type = strrchr(topicBuf, '/'); // Last part of received topic is always the command (type)
bool command_unknown = false;
uint32_t index = 1;
bool user_index = false;
if (type != nullptr) {
@ -405,34 +400,44 @@ void CommandHandler(char* topicBuf, char* dataBuf, uint32_t data_len) {
type++; // Skip leading _ in command
TasmotaGlobal.no_mqtt_response = true;
}
} else { // type = nullptr
type = (char*)EmptyStr; // Unknown command
}
bool binary_data = (index > 299); // Suppose binary data on topic index > 299
if (!binary_data) {
bool keep_spaces = ((strstr_P(type, PSTR("SERIALSEND")) != nullptr) && (index > 9)); // Do not skip leading spaces on (s)serialsend10 and up
if (!keep_spaces) {
while (*dataBuf && isspace(*dataBuf)) {
dataBuf++; // Skip leading spaces in data
data_len--;
}
bool binary_data = (index > 299); // Suppose binary data on topic index > 299
if (!binary_data) {
bool keep_spaces = ((strstr_P(type, PSTR("SERIALSEND")) != nullptr) && (index > 9)); // Do not skip leading spaces on (s)serialsend10 and up
if (!keep_spaces) {
while (*dataBuf && isspace(*dataBuf)) {
dataBuf++; // Skip leading spaces in data
data_len--;
}
}
}
int32_t payload = -99;
if (!binary_data) {
if (!strcmp(dataBuf,"?")) { data_len = 0; }
Response_P(S_JSON_COMMAND_ERROR); // Prep error message for either Command Error or Command Unknown
char number[12];
ResponseAppend_P(PSTR(",\"Input\":\"%s%s%s%s\"}"),
type,
(index != 1) ? itoa(index, number, 10) : "",
(data_len) ? " " : "",
(data_len) ? (binary_data) ? HexToString((uint8_t*)dataBuf, data_len).c_str() : EscapeJSONString(dataBuf).c_str() : "");
char *p;
payload = strtol(dataBuf, &p, 0); // decimal, octal (0) or hex (0x)
if (p == dataBuf) { payload = -99; }
int temp_payload = GetStateNumber(dataBuf);
if (temp_payload > -1) { payload = temp_payload; }
}
int32_t payload = -99;
if (!binary_data) {
if (!strcmp(dataBuf,"?")) { data_len = 0; }
AddLog(LOG_LEVEL_DEBUG, PSTR("CMD: Grp %d, Cmd '%s', Idx %d, Len %d, Pld %d, Data '%s'"),
grpflg, type, index, data_len, payload, (binary_data) ? HexToString((uint8_t*)dataBuf, data_len).c_str() : dataBuf);
char *p;
payload = strtol(dataBuf, &p, 0); // decimal, octal (0) or hex (0x)
if (p == dataBuf) { payload = -99; }
int temp_payload = GetStateNumber(dataBuf);
if (temp_payload > -1) { payload = temp_payload; }
}
Response_P(PSTR("{\"" D_JSON_COMMAND "\":\"" D_JSON_ERROR "\"}"));
AddLog(LOG_LEVEL_DEBUG, PSTR("CMD: Grp %d, Cmd '%s', Idx %d, Len %d, Pld %d, Data '%s'"),
grpflg, type, index, data_len, payload, (binary_data) ? HexToString((uint8_t*)dataBuf, data_len).c_str() : dataBuf);
if (strlen(type)) {
if (Settings->ledstate &0x02) { TasmotaGlobal.blinks++; }
// TasmotaGlobal.backlog_timer = millis() + (100 * MIN_BACKLOG_DELAY);
@ -454,29 +459,24 @@ void CommandHandler(char* topicBuf, char* dataBuf, uint32_t data_len) {
if (!DecodeCommand(kTasmotaCommands, TasmotaCommand, kTasmotaSynonyms)) {
if (!XdrvCall(FUNC_COMMAND)) {
if (!XsnsCall(FUNC_COMMAND)) {
command_unknown = true; // Unknown command
type = (char*)EmptyStr; // Unknown command
}
}
}
#ifdef USE_SCRIPT_SUB_COMMAND
}
#endif // USE_SCRIPT_SUB_COMMAND
} else { // type = nullptr
stemp1[0] = '\0';
type = (char*)stemp1;
command_unknown = true; // Unknown command
}
if (command_unknown) {
TasmotaGlobal.blinks = 201;
Response_P(PSTR("{\"" D_JSON_COMMAND "\":\"" D_JSON_UNKNOWN "\""));
if (strlen(type)) {
ResponseAppend_P(PSTR(",\"Input\":\"%s\""), type);
if (ResponseStartsWith(S_JSON_COMMAND_ERROR)) {
// No calls to Response_P performed if got here so it's either Command Error or Unknown
TasmotaGlobal.no_mqtt_response = false; // Make sure to report commands starting with underline
if (!strlen(type)) {
TasmotaGlobal.blinks = 201;
ResponseReplace("\"" D_JSON_ERROR "\"", "\"" D_JSON_UNKNOWN "\""); // Need quotes to make sure only the first Error is replaceds by Unknown
snprintf_P(stemp1, sizeof(stemp1), PSTR(D_JSON_COMMAND));
type = (char*)stemp1;
}
ResponseJsonEnd();
snprintf_P(stemp1, sizeof(stemp1), PSTR(D_JSON_COMMAND));
type = (char*)stemp1;
}
if (ResponseLength()) {

View File

@ -2468,8 +2468,7 @@ void CmndScale(void)
dtostrfd(value, Settings->flag2.calc_resolution, rules_vars[XdrvMailbox.index -1]);
bitSet(Rules.vars_event, XdrvMailbox.index -1);
} else {
ResponseCmndIdxError();
return;
return; // Command Error
}
}
ResponseCmndIdxChar(rules_vars[XdrvMailbox.index -1]);

View File

@ -1395,8 +1395,7 @@ void CmndKnxPa(void)
if ( ((pa_area == 0) && (pa_line == 0) && (pa_member == 0))
|| (pa_area > 15) || (pa_line > 15) || (pa_member > 255) ) {
ResponseCmndError();
return;
return; // Command Error
} // Invalid command
KNX_addr.pa.area = pa_area;
@ -1426,8 +1425,7 @@ void CmndKnxGa(void)
|| (ga_area > 31) || (ga_line > 7) || (ga_member > 255)
|| (ga_option < 0) || ((ga_option > KNX_MAX_device_param ) && (ga_option != KNX_Empty))
|| (!device_param[ga_option-1].show) ) {
ResponseCmndIdxError();
return;
return; // Command Error
} // Invalid command
KNX_addr.ga.area = ga_area;
@ -1445,8 +1443,7 @@ void CmndKnxGa(void)
if ( (XdrvMailbox.payload <= Settings->knx_GA_registered) && (XdrvMailbox.payload > 0) ) {
XdrvMailbox.index = XdrvMailbox.payload;
} else {
ResponseCmndIdxError();
return;
return; // Command Error
}
}
if ( XdrvMailbox.index <= Settings->knx_GA_registered ) {
@ -1477,8 +1474,7 @@ void CmndKnxCb(void)
|| (cb_area > 31) || (cb_line > 7) || (cb_member > 255)
|| (cb_option < 0) || ((cb_option > KNX_MAX_device_param ) && (cb_option != KNX_Empty))
|| (!device_param[cb_option-1].show) ) {
ResponseCmndIdxError();
return;
return; // Command Error
} // Invalid command
KNX_addr.ga.area = cb_area;
@ -1496,8 +1492,7 @@ void CmndKnxCb(void)
if ( (XdrvMailbox.payload <= Settings->knx_CB_registered) && (XdrvMailbox.payload > 0) ) {
XdrvMailbox.index = XdrvMailbox.payload;
} else {
ResponseCmndIdxError();
return;
return; // Command Error
}
}
if ( XdrvMailbox.index <= Settings->knx_CB_registered ) {

View File

@ -1393,8 +1393,6 @@ void CmndZbLoad(void) {
}
if (ret) {
ResponseCmndDone();
} else {
ResponseCmndError();
}
}
@ -1409,8 +1407,6 @@ void CmndZbUnload(void) {
bool ret = ZbUnload(XdrvMailbox.data);
if (ret) {
ResponseCmndDone();
} else {
ResponseCmndError();
}
}
@ -1504,8 +1500,6 @@ void CmndZbenroll(void) {
Z_SendCIEZoneEnrollResponse(device.shortaddr, 0, 500, enrollEndpoint, 1);
ResponseCmndDone();
} else {
ResponseCmndError();
}
}
@ -1522,8 +1516,6 @@ void CmndZbCIE(void) {
Z_WriteCIEAddress(device.shortaddr, 0, 500, enrollEndpoint, 0);
ResponseCmndDone();
} else {
ResponseCmndError();
}
}
@ -1554,8 +1546,6 @@ void CmndZbEmulation(void) {
}
ResponseCmndDone();
} else {
ResponseCmndError();
}
}

View File

@ -179,9 +179,6 @@ void CmndSetPower(void) {
timeprops[XdrvMailbox.index].setPower(newPower, Tprop.current_time_secs );
ResponseCmndFloat(newPower, 2);
}
else {
ResponseCmndError();
}
}
}
@ -204,9 +201,6 @@ void CmndSetCycleTime(void) {
Tprop.timeprops[XdrvMailbox.index].initialise(cycleTimes[XdrvMailbox.index], deadTimes[XdrvMailbox.index], opInverts[XdrvMailbox.index], fallbacks[XdrvMailbox.index], maxIntervals[XdrvMailbox.index], Tprop.current_time_secs);
ResponseCmndNumber(newCycleTime);
}
else {
ResponseCmndError();
}
}
else {
ResponseCmndNumber(cycleTimes[XdrvMailbox.index]);
@ -223,9 +217,6 @@ void CmndSetDeadTime(void) {
Tprop.timeprops[XdrvMailbox.index].initialise(cycleTimes[XdrvMailbox.index], deadTimes[XdrvMailbox.index], opInverts[XdrvMailbox.index], fallbacks[XdrvMailbox.index], maxIntervals[XdrvMailbox.index], Tprop.current_time_secs);
ResponseCmndNumber(newDeadTime);
}
else {
ResponseCmndError();
}
}
else {
ResponseCmndNumber(deadTimes[XdrvMailbox.index]);
@ -256,9 +247,6 @@ void CmndSetFallbackPower(void) {
Tprop.timeprops[XdrvMailbox.index].initialise(cycleTimes[XdrvMailbox.index], deadTimes[XdrvMailbox.index], opInverts[XdrvMailbox.index], fallbacks[XdrvMailbox.index], maxIntervals[XdrvMailbox.index], Tprop.current_time_secs);
ResponseCmndFloat(newPower, 2);
}
else {
ResponseCmndError();
}
}
else {
ResponseCmndFloat(fallbacks[XdrvMailbox.index], 2);
@ -275,9 +263,6 @@ void CmndSetMaxUpdateInterval(void) {
Tprop.timeprops[XdrvMailbox.index].initialise(cycleTimes[XdrvMailbox.index], deadTimes[XdrvMailbox.index], opInverts[XdrvMailbox.index], fallbacks[XdrvMailbox.index], maxIntervals[XdrvMailbox.index], Tprop.current_time_secs);
ResponseCmndNumber(newInterval);
}
else {
ResponseCmndError();
}
}
else {
ResponseCmndNumber(maxIntervals[XdrvMailbox.index]);

View File

@ -131,8 +131,6 @@ void CmndHDMISendRaw(void) {
} else {
ResponseCmndChar_P(PSTR("Buffer too large"));
}
} else {
ResponseCmndError();
}
}
@ -211,8 +209,6 @@ void CmndHDMISend(void) {
}
}
}
} else {
ResponseCmndError();
}
}

View File

@ -2519,8 +2519,7 @@ void CmndWebcamGetPicStore(void) {
bnum = XdrvMailbox.index;
}
if (bnum < 0 || bnum > MAX_PICSTORE) {
ResponseCmndError();
return;
return; // Command Error
}
// if given 0, then get frame 1 first, and use frame 1 (the first frame, index 0).
@ -2616,11 +2615,15 @@ int WebcamSavePic(int append) {
}
// "WCSAVEPIC1 /temp.jpg" "WCSAVEPIC2 /temp.jpg"
void CmdWebcamSavePic(){
WebcamSavePic(0)? ResponseCmndDone(): ResponseCmndError();
if (WebcamSavePic(0)) {
ResponseCmndDone();
}
}
// "WCAPPENDPIC1 /temp.jpg" "WCAPPENDPIC2 /temp.jpg"
void CmdWebcamAppendPic(){
WebcamSavePic(1)? ResponseCmndDone(): ResponseCmndError();
if (WebcamSavePic(1)) {
ResponseCmndDone();
}
}
void CmndWebcamMenuVideoDisable(void) {

View File

@ -950,7 +950,7 @@ void CmndWebcamConvertFrame(void){
int bnum = XdrvMailbox.index;
// bnum is 1-4
if ((bnum < 1) || (bnum > MAX_PICSTORE)){
ResponseCmndError(); return;
return; // Command Error
}
int format = 0;
int scale = 0;
@ -974,22 +974,23 @@ void CmndWebcamConvertFrame(void){
}
if (!wc_check_format(format)){
AddLog(LOG_LEVEL_ERROR, PSTR("CAM: Invalid format %d"), format+1);
ResponseCmndError(); return;
return; // Command Error
}
struct PICSTORE *ps = &Wc.picstore[bnum-1];
if (!ps->buff){
AddLog(LOG_LEVEL_ERROR, PSTR("CAM: No pic at %d"), bnum);
ResponseCmndError(); return;
return; // Command Error
}
if (ps->format != PIXFORMAT_JPEG && format != PIXFORMAT_JPEG){
AddLog(LOG_LEVEL_ERROR, PSTR("CAM: ConvertFrame only go to or from JPEG"));
ResponseCmndError(); return;
return; // Command Error
}
// takes INDEX into store
bool res = WcConvertFrame(bnum-1, format, scale);
res? ResponseCmndDone(): ResponseCmndError();
return;
if (res) {
ResponseCmndDone();
}
}
// Allows Berry to send native address, len, format, optional width, height
@ -998,8 +999,7 @@ void CmndWebcamConvertFrame(void){
void CmndWebcamSetPicture(void){
int bnum = XdrvMailbox.index;
if (!XdrvMailbox.data_len || bnum < 1 || bnum > MAX_PICSTORE) {
ResponseCmndError();
return;
return; // Command Error
}
struct PICSTORE *p = &Wc.picstore[bnum-1];
@ -1025,22 +1025,21 @@ void CmndWebcamSetPicture(void){
if (res < 2){
AddLog(LOG_LEVEL_ERROR, PSTR("CAM: SetPicture expects 'addr len format [width height]'"));
ResponseCmndError(); return;
return; // Command Error
}
if (!wc_check_format(format)){
AddLog(LOG_LEVEL_ERROR, PSTR("CAM: Invalid format %d"), format+1);
ResponseCmndError(); return;
return; // Command Error
}
if (format != PIXFORMAT_JPEG && (!width || !height)){
AddLog(LOG_LEVEL_ERROR, PSTR("CAM: SetPicture: format %d needs width and height"), format+1);
ResponseCmndError(); return;
return; // Command Error
}
bool allocres = pic_alloc(p, width, height, len, format, 1);
if (!allocres){
AddLog(LOG_LEVEL_ERROR, PSTR("CAM: SetPicture alloc failed"));
ResponseCmndError();
return;
return; // Command Error
}
AddLog(LOG_LEVEL_DEBUG, PSTR("CAM: SetPicture addr:%u len:%d format%d [width%d height%d]"), addr, len, format, width, height);
@ -1052,7 +1051,6 @@ void CmndWebcamSetPicture(void){
// copy Berry data. We can't free it, and Berry will
memcpy(p->buff, (void *)addr, copylen);
ResponseCmndDone();
return;
}
@ -1192,8 +1190,7 @@ void CmndWebcamGetMotionPixels(void) {
if (-99 != XdrvMailbox.payload){
bnum = XdrvMailbox.payload;
if (bnum < 1 || bnum > MAX_PICSTORE) {
ResponseCmndError();
return;
return; // Command Error
}
}
@ -1217,8 +1214,7 @@ void CmndWebcamGetMotionPixels(void) {
}
if (!p){
ResponseCmndError();
return;
return; // Command Error
}
if (bnum > 1){
@ -1227,8 +1223,7 @@ void CmndWebcamGetMotionPixels(void) {
memcpy(Wc.picstore[bnum-1].buff, p->buff, p->len);
p = &Wc.picstore[bnum-1];
} else {
ResponseCmndError();
return;
return; // Command Error
}
}

View File

@ -2611,8 +2611,7 @@ void CmndMi32Option(void){
}
} break;
default:{
ResponseCmndIdxError();
return;
return; // Command Error
} break;
}
ResponseCmndIdxNumber(value);

View File

@ -246,8 +246,6 @@ bool Rg15Command(void) {
}
ResponseCmndIdxChar(XdrvMailbox.data);
} else {
ResponseCmndIdxError();
}
return serviced;