From 7dd48f78d490fe80039798ce3d59435a704ce9fb Mon Sep 17 00:00:00 2001 From: Andrey Klimov Date: Fri, 10 Jan 2020 00:45:32 +0300 Subject: [PATCH] JSON string type control. Relability fix --- lighthub/abstractin.cpp | 2 +- lighthub/dmx.cpp | 6 ++++-- lighthub/inputs.cpp | 41 +++++++++++++++++++++------------------ lighthub/item.cpp | 23 ++++++++++++++-------- lighthub/main.cpp | 43 +++++++++++++++++++++++++++++++---------- lighthub/utils.cpp | 4 ++-- 6 files changed, 77 insertions(+), 42 deletions(-) diff --git a/lighthub/abstractin.cpp b/lighthub/abstractin.cpp index 8956bbb..4404f71 100644 --- a/lighthub/abstractin.cpp +++ b/lighthub/abstractin.cpp @@ -30,7 +30,7 @@ int abstractIn::publish(char * value, const char* subtopic) if (in) { aJsonObject *emit = aJson.getObjectItem(in->inputObj, "emit"); - if (emit) + if (emit && emit->type == aJson_String) { return publishTopic(emit->valuestring,value,subtopic); } diff --git a/lighthub/dmx.cpp b/lighthub/dmx.cpp index 0bcc0f9..41d86bc 100644 --- a/lighthub/dmx.cpp +++ b/lighthub/dmx.cpp @@ -85,7 +85,7 @@ int itemCtrl2(char* name,int r,int g, int b, int w) { aJsonObject *i =groupArr->child; while (i) { //Serial.println(i->valuestring); - itemCtrl2(i->valuestring,r,g,b,w); + if (i->type == aJson_String) itemCtrl2(i->valuestring,r,g,b,w); i=i->next;} } } //itemtype @@ -100,7 +100,9 @@ void DMXImmediateUpdate(short tch,short r, short g, short b, short w) { if (dmxArr && (dmxArr->type==aJson_Array)) { - char* itemname = aJson.getArrayItem(dmxArr,tch)->valuestring; + aJsonObject *DMXch = aJson.getArrayItem(dmxArr,tch); + char* itemname = NULL; + if (DMXch->type == aJson_String) itemname=DMXch->valuestring; if (itemname) itemCtrl2(itemname,r,g,b,w); } } diff --git a/lighthub/inputs.cpp b/lighthub/inputs.cpp index 41b1846..ea028d0 100644 --- a/lighthub/inputs.cpp +++ b/lighthub/inputs.cpp @@ -268,7 +268,7 @@ void Input::counterPoll() { debugSerial<type == aJson_String) { char valstr[10]; char addrstr[MQTT_TOPIC_LENGTH]; strncpy(addrstr,emit->valuestring,sizeof(addrstr)); @@ -327,7 +327,7 @@ void Input::uptimePoll() { if (nextPollTime() > millis()) return; aJsonObject *emit = aJson.getObjectItem(inputObj, "emit"); - if (emit) { + if (emit && emit->type == aJson_String) { #ifdef WITH_DOMOTICZ if(getIdxField()){ publishDataToDomoticz(DHT_POLL_DELAY_DEFAULT, emit, "{\"idx\":%s,\"svalue\":\"%d\"}", getIdxField(), millis()); @@ -422,9 +422,9 @@ void Input::dht22Poll() { #endif aJsonObject *emit = aJson.getObjectItem(inputObj, "emit"); aJsonObject *item = aJson.getObjectItem(inputObj, "item"); - if (item) thermoSetCurTemp(item->valuestring, temp); + if (item && item->type == aJson_String) thermoSetCurTemp(item->valuestring, temp); debugSerial << F("IN:") << pin << F(" DHT22 type. T=") << temp << F("°C H=") << humidity << F("%")<type == aJson_String && temp && humidity && temp == temp && humidity == humidity) { char addrstr[MQTT_TOPIC_LENGTH] = ""; #ifdef WITH_DOMOTICZ if(getIdxField()){ @@ -480,13 +480,13 @@ bool Input::executeCommand(aJsonObject* cmd, int8_t toggle, char* defCmd) aJsonObject *emit = aJson.getObjectItem(cmd, "emit"); char * itemCommand; - if (irev && toggle) itemCommand = irev->valuestring; - else if(icmd) itemCommand = icmd->valuestring; + if (irev && toggle && irev->type == aJson_String) itemCommand = irev->valuestring; + else if(icmd && icmd->type == aJson_String) itemCommand = icmd->valuestring; else itemCommand = defCmd; char * emitCommand; - if (erev && toggle) itemCommand = erev->valuestring; - else if(ecmd) emitCommand = ecmd->valuestring; + if (erev && toggle && erev->type == aJson_String) itemCommand = erev->valuestring; + else if(ecmd && ecmd->type == aJson_String) emitCommand = ecmd->valuestring; else emitCommand = defCmd; debugSerial << F("IN:") << (pin) << F(" : ") <valuestring<< F(" -> ")<type == aJson_String) { /* TODO implement #ifdef WITH_DOMOTICZ @@ -520,7 +520,7 @@ if (mqttClient.connected() && !ethernetIdleCount) } } } // emit - if (item && itemCommand) { + if (item && itemCommand && item->type == aJson_String) { //debugSerial <valuestring <valuestring); if (it.isValid()) it.Ctrl(itemCommand, true); @@ -895,7 +895,7 @@ void Input::onContactChanged(int newValue) { aJsonObject *scmd = aJson.getObjectItem(inputObj, "scmd"); aJsonObject *rcmd = aJson.getObjectItem(inputObj, "rcmd"); debugSerial << F("LEGACY IN:") << (pin) << F("=") << newValue << endl; - if (emit) { + if (emit && emit->type == aJson_String) { #ifdef WITH_DOMOTICZ if (getIdxField()) { (newValue) ? publishDataToDomoticz(0, emit, "{\"command\":\"switchlight\",\"idx\":%s,\"switchcmd\":\"On\"}", @@ -912,26 +912,26 @@ if (mqttClient.connected() && !ethernetIdleCount) { if (!strchr(addrstr,'/')) setTopic(addrstr,sizeof(addrstr),T_OUT,emit->valuestring); if (newValue) { //send set command - if (!scmd) mqttClient.publish(addrstr, "ON", true); + if (!scmd || scmd->type != aJson_String) mqttClient.publish(addrstr, "ON", true); else if (strlen(scmd->valuestring)) mqttClient.publish(addrstr, scmd->valuestring, true); } else { //send reset command - if (!rcmd) mqttClient.publish(addrstr, "OFF", true); + if (!rcmd || rcmd->type == aJson_String) mqttClient.publish(addrstr, "OFF", true); else if (strlen(rcmd->valuestring))mqttClient.publish(addrstr, rcmd->valuestring, true); } } } } // emit - if (item) { + if (item && item->type == aJson_String) { //debugSerial <valuestring <valuestring); if (it.isValid()) { if (newValue) { //send set command - if (!scmd) it.Ctrl(CMD_ON, 0, NULL, true); + if (!scmd || scmd->type != aJson_String) it.Ctrl(CMD_ON, 0, NULL, true); else if (strlen(scmd->valuestring)) it.Ctrl(scmd->valuestring, true); } else { //send reset command - if (!rcmd) it.Ctrl(CMD_OFF, 0, NULL, true); + if (!rcmd || rcmd->type == aJson_String) it.Ctrl(CMD_OFF, 0, NULL, true); else if (strlen(rcmd->valuestring)) it.Ctrl(rcmd->valuestring, true); } @@ -945,7 +945,7 @@ void Input::onAnalogChanged(float newValue) { aJsonObject *emit = aJson.getObjectItem(inputObj, "emit"); - if (emit) { + if (emit && emit->type == aJson_String) { //#ifdef WITH_DOMOTICZ // if (getIdxField()) { @@ -963,7 +963,7 @@ void Input::onAnalogChanged(float newValue) { mqttClient.publish(addrstr, strVal, true); } - if (item) { + if (item && item->type == aJson_String) { int intNewValue = round(newValue); Item it(item->valuestring); if (it.isValid()) { @@ -976,6 +976,8 @@ void Input::onAnalogChanged(float newValue) { bool Input::publishDataToDomoticz(int pollTimeIncrement, aJsonObject *emit, const char *format, ...) { #ifdef WITH_DOMOTICZ +if (emit && emit->type == aJson_String) +{ debugSerial << F("\nDomoticz valstr:"); char valstr[50]; va_list args; @@ -988,6 +990,7 @@ bool Input::publishDataToDomoticz(int pollTimeIncrement, aJsonObject *emit, cons if (pollTimeIncrement) setNextPollTime(millis() + pollTimeIncrement); // debugSerial << F(" NextPollMillis=") << nextPollTime() << endl; +} #endif return true; @@ -995,7 +998,7 @@ bool Input::publishDataToDomoticz(int pollTimeIncrement, aJsonObject *emit, cons char* Input::getIdxField() { aJsonObject *idx = aJson.getObjectItem(inputObj, "idx"); - if(idx&&idx->valuestring) + if(idx&& idx->type == aJson_String && idx->valuestring) return idx->valuestring; return nullptr; } diff --git a/lighthub/item.cpp b/lighthub/item.cpp index 4dc9f77..e723a82 100644 --- a/lighthub/item.cpp +++ b/lighthub/item.cpp @@ -663,7 +663,7 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int suffixCode st.h = Par[0]; Par[1] = st.s; Par[2] = st.v; - + n=3; setVal(st.aslong); } @@ -1021,8 +1021,11 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int suffixCode if (itemArg->type == aJson_Array) { aJsonObject *i = itemArg->child; while (i) { - Item it(i->valuestring); - it.Ctrl(cmd, n, Par, send,suffixCode,subItem); //// was true + if (i->type == aJson_String) + { + Item it(i->valuestring); + it.Ctrl(cmd, n, Par, send,suffixCode,subItem); //// was true + } i = i->next; } //while } //if @@ -1142,11 +1145,14 @@ int Item::isActive() { debugSerial<child; while (i) { - Item it(i->valuestring); + if (i->type == aJson_String) + { + Item it(i->valuestring); - if (it.isValid() && it.isActive()>0) { - debugSerial<0) { + debugSerial<next; } //while @@ -1319,6 +1325,7 @@ int Item::VacomSetFan(int8_t val, int8_t cmd) { int Item::VacomSetHeat(int8_t val, int8_t cmd) { uint8_t result; int addr; + if (itemArg->type != aJson_String) return 0; Item it(itemArg->valuestring); if (it.isValid() && it.itemType == CH_VC) addr=it.getArg(); @@ -1448,7 +1455,7 @@ int Item::checkFM() { aJson.addNumberToObject(out, "sw", (int) node.getResponseBuffer(0)); if (RPM && itemArg->type == aJson_Array) { aJsonObject *airGateObj = aJson.getArrayItem(itemArg, 1); - if (airGateObj) { + if (airGateObj && airGateObj->type == aJson_String) { int val = 100; Item item(airGateObj->valuestring); if (item.isValid()) diff --git a/lighthub/main.cpp b/lighthub/main.cpp index 9ae6055..3a7a2cb 100644 --- a/lighthub/main.cpp +++ b/lighthub/main.cpp @@ -517,6 +517,29 @@ void onMQTTConnect(){ #endif } +char* getStringFromConfig(aJsonObject * a, int i) +{ +aJsonObject * element = NULL; +if (!a) return NULL; +if (a->type == aJson_Array) + element = aJson.getArrayItem(a, i); +// TODO - human readable JSON objects as alias + + if (element && element->type == aJson_String) return element->valuestring; + return NULL; +} + +char* getStringFromConfig(aJsonObject * a, char * name) +{ +aJsonObject * element = NULL; +if (!a) return NULL; +if (a->type == aJson_Object) + element = aJson.getObjectItem(a, name); + if (element && element->type == aJson_String) return element->valuestring; + return NULL; +} + + void ip_ready_config_loaded_connecting_to_broker() { short n = 0; int port = 1883; @@ -528,15 +551,15 @@ void ip_ready_config_loaded_connecting_to_broker() { char syslogDeviceHostname[16]; if (mqttArr && (aJson.getArraySize(mqttArr))) { - deviceName = aJson.getArrayItem(mqttArr, 0)->valuestring; + deviceName = getStringFromConfig(mqttArr, 0); debugSerial<valuestring; - if (n>1) syslogPort = aJson.getArrayItem(udpSyslogArr, 1)->valueint; + char *syslogServer = getStringFromConfig(udpSyslogArr, 0); + if (n>1) syslogPort = getStringFromConfig(udpSyslogArr, 1); inet_ntoa_r(Ethernet.localIP(),syslogDeviceHostname,sizeof(syslogDeviceHostname)); /* @@ -555,11 +578,11 @@ void ip_ready_config_loaded_connecting_to_broker() { if (!mqttClient.connected() && mqttArr && ((n = aJson.getArraySize(mqttArr)) > 1)) { // char *client_id = aJson.getArrayItem(mqttArr, 0)->valuestring; - char *servername = aJson.getArrayItem(mqttArr, 1)->valuestring; - if (n >= 3) port = aJson.getArrayItem(mqttArr, 2)->valueint; - if (n >= 4) user = aJson.getArrayItem(mqttArr, 3)->valuestring; + char *servername = getStringFromConfig(mqttArr, 1); + if (n >= 3) port = getStringFromConfig(mqttArr, 2); + if (n >= 4) user = getStringFromConfig(mqttArr, 3); if (!loadFlash(OFFSET_MQTT_PWD, passwordBuf, sizeof(passwordBuf)) && (n >= 5)) { - password = aJson.getArrayItem(mqttArr, 4)->valuestring; + password = getStringFromConfig(mqttArr, 4); debugSerial<valuestring; + owEmitString = getStringFromConfig(owObj, "emit"); debugSerial<")<valuestring) {//DOMOTICZ json format support + if (idx && && idx->type ==aJson_String && idx->valuestring) {//DOMOTICZ json format support debugSerial << endl << idx->valuestring << F(" Domoticz valstr:"); char valstr[50]; sprintf(valstr, "{\"idx\":%s,\"svalue\":\"%.1f\"}", idx->valuestring, currentTemp); @@ -819,7 +842,7 @@ void Changed(int i, DeviceAddress addr, float currentTemp) { mqttClient.publish(addrstr, valstr); } // And translate temp to internal items - owItem = aJson.getObjectItem(owObj, "item")->valuestring; + owItem = getStringFromConfig(owObj, "item"); if (owItem) thermoSetCurTemp(owItem, currentTemp); ///TODO: Refactore using Items interface } // if valid temperature diff --git a/lighthub/utils.cpp b/lighthub/utils.cpp index 08a3f44..124a927 100644 --- a/lighthub/utils.cpp +++ b/lighthub/utils.cpp @@ -396,11 +396,11 @@ if (topics && topics->type == aJson_Object) } -if (_root) strncpy(buf,_root->valuestring,buflen); +if (_root && _root->type == aJson_String) strncpy(buf,_root->valuestring,buflen); else strncpy_P(buf,homeTopic,buflen); strncat(buf,"/",buflen); -if (_l2) strncat(buf,_l2->valuestring,buflen); +if (_l2 && _l2->type == aJson_String) strncat(buf,_l2->valuestring,buflen); else switch (tt) { case T_DEV: