From 38a7ad898658eba474a716df6f6fd914c5e87d4b Mon Sep 17 00:00:00 2001 From: mvdbro Date: Fri, 11 Aug 2017 17:28:17 +0200 Subject: [PATCH] Fixed syslog and some memory reductions --- src/ArduinoEasy.ino | 21 +++-- src/Command.ino | 10 ++- src/Controller.ino | 8 +- src/WebServer.ino | 201 +++++++++++++++++++++++++++++++++++++++++++- src/_C001.ino | 21 +++-- src/_C002.ino | 52 ++++++------ src/_C005.ino | 10 +-- src/_P005_DHT.ino | 5 +- src/_P034_DHT12.ino | 104 +++++++++++++++++++++++ 9 files changed, 374 insertions(+), 58 deletions(-) create mode 100644 src/_P034_DHT12.ino diff --git a/src/ArduinoEasy.ino b/src/ArduinoEasy.ino index 0cc23d5..74f5b5a 100644 --- a/src/ArduinoEasy.ino +++ b/src/ArduinoEasy.ino @@ -428,14 +428,6 @@ void setup() if (Settings.Build != BUILD) BuildFixes(); - String log = F("\nINIT : Booting Build nr:"); - log += BUILD; - addLog(LOG_LEVEL_INFO, log); - - hardwareInit(); - PluginInit(); - CPluginInit(); - mac[5] = Settings.Unit; // make sure every unit has a unique mac address if (Settings.IP[0] == 0) Ethernet.begin(mac); @@ -445,6 +437,10 @@ void setup() // setup UDP if (Settings.UDPPort != 0) portUDP.begin(Settings.UDPPort); + + hardwareInit(); + PluginInit(); + CPluginInit(); #if FEATURE_MQTT // Setup MQTT Client @@ -453,11 +449,12 @@ void setup() MQTTConnect(); #endif - sendSysInfoUDP(3); - - log = F("INIT : Boot OK"); + String log = F("\nINIT : Booting Build nr:"); + log += BUILD; addLog(LOG_LEVEL_INFO, log); + sendSysInfoUDP(3); + // Setup timers byte bootMode = 0; if (bootMode == 0) @@ -488,6 +485,8 @@ void setup() rulesProcessing(event); } + log = F("INIT : Boot OK"); + addLog(LOG_LEVEL_INFO, log); } else { diff --git a/src/Command.ino b/src/Command.ino index afd4172..ba2bd53 100644 --- a/src/Command.ino +++ b/src/Command.ino @@ -20,6 +20,14 @@ void ExecuteCommand(byte source, const char *Line) // commands for debugging // **************************************** + if (strcasecmp_P(Command, PSTR("Syslog")) == 0) + { + success = true; + String event = Line; + event = event.substring(6); + syslog(event.c_str()); + } + if (strcasecmp_P(Command, PSTR("w5100")) == 0) { success = true; @@ -177,7 +185,7 @@ void ExecuteCommand(byte source, const char *Line) while (client.available()) { String line = client.readStringUntil('\n'); - if (line.substring(0, 15) == "HTTP/1.1 200 OK") + if (line.substring(0, 15) == F("HTTP/1.1 200 OK")) addLog(LOG_LEVEL_DEBUG, line); delay(1); } diff --git a/src/Controller.ino b/src/Controller.ino index 0cec61f..2325d14 100644 --- a/src/Controller.ino +++ b/src/Controller.ino @@ -93,13 +93,13 @@ void MQTTConnect() MQTTclient.setCallback(callback); // MQTT needs a unique clientname to subscribe to broker - String clientid = "ESPClient"; + String clientid = F("ESPClient"); clientid += Settings.Unit; String subscribeTo = ""; String LWTTopic = Settings.MQTTsubscribe; LWTTopic.replace("/#", "/status"); - LWTTopic.replace("%sysname%", Settings.Name); + LWTTopic.replace(F("%sysname%"), Settings.Name); for (byte x = 1; x < 3; x++) { @@ -116,7 +116,7 @@ void MQTTConnect() log = F("MQTT : Connected to broker"); addLog(LOG_LEVEL_INFO, log); subscribeTo = Settings.MQTTsubscribe; - subscribeTo.replace("%sysname%", Settings.Name); + subscribeTo.replace(F("%sysname%"), Settings.Name); MQTTclient.subscribe(subscribeTo.c_str()); log = F("Subscribed to: "); log += subscribeTo; @@ -162,7 +162,7 @@ void MQTTStatus(String& status) { String pubname = Settings.MQTTsubscribe; pubname.replace("/#", "/status"); - pubname.replace("%sysname%", Settings.Name); + pubname.replace(F("%sysname%"), Settings.Name); MQTTclient.publish(pubname.c_str(), status.c_str(),Settings.MQTTRetainFlag); } #endif diff --git a/src/WebServer.ino b/src/WebServer.ino index 9f1ca44..ec2d747 100644 --- a/src/WebServer.ino +++ b/src/WebServer.ino @@ -202,7 +202,7 @@ void addHeader(boolean showMenu, EthernetClient client) str += F("h1 {font-size:16pt; color:black;}"); str += F("h6 {font-size:10pt; color:black; text-align:center;}"); str += F(".button-menu {background-color:#ffffff; color:blue; margin: 10px; text-decoration:none}"); - str += F(".button-link {padding:5px 15px; background-color:#0077dd; color:#fff; border:solid 1px #fff; text-decoration:none}"); + str += F(".button-link {margin:4px; padding:4px 16px; background-color:#07D; color:#FFF; text-decoration:none; border-radius:4px}"); str += F(".button-menu:hover {background:#ddddff;}"); str += F(".button-link:hover {background:#369;}"); str += F("th {padding:10px; background-color:black; color:#ffffff;}"); @@ -329,7 +329,8 @@ void handle_root(EthernetClient client, String &post) { if (Nodes[x].ip[0] != 0) { char url[80]; - sprintf_P(url, PSTR("%u.%u.%u.%u"), Nodes[x].ip[0], Nodes[x].ip[1], Nodes[x].ip[2], Nodes[x].ip[3], Nodes[x].ip[0], Nodes[x].ip[1], Nodes[x].ip[2], Nodes[x].ip[3]); +// sprintf_P(url, PSTR("%u.%u.%u.%u"), Nodes[x].ip[0], Nodes[x].ip[1], Nodes[x].ip[2], Nodes[x].ip[3], Nodes[x].ip[0], Nodes[x].ip[1], Nodes[x].ip[2], Nodes[x].ip[3]); + sprintf_P(url, PSTR("%u.%u.%u.%u"), Nodes[x].ip[0], Nodes[x].ip[1], Nodes[x].ip[2], Nodes[x].ip[3], Nodes[x].ip[0], Nodes[x].ip[1], Nodes[x].ip[2], Nodes[x].ip[3]); reply += F("Unit "); reply += x; reply += F(""); @@ -1832,7 +1833,8 @@ bool handle_unknown(EthernetClient client, String path) { else if (path.endsWith(F(".ico"))) dataType = F("image/x-icon"); else if (path.endsWith(F(".txt"))) dataType = F("application/octet-stream"); else if (path.endsWith(F(".dat"))) dataType = F("application/octet-stream"); - + else if (path.endsWith(".esp")) return handle_custom(client, path); + File dataFile = SD.open(path.c_str()); if (!dataFile) return false; @@ -1856,6 +1858,132 @@ bool handle_unknown(EthernetClient client, String path) { return true; } +//******************************************************************************** +// Web Interface custom page handler +//******************************************************************************** +boolean handle_custom(EthernetClient client, String path) { + //path = path.substring(1); + String reply = ""; + if (path.startsWith(F("dashboard"))) // for the dashboard page, create a default unit dropdown selector + { + reply += F(""); + + reply += F("
"); + + // handle page redirects to other unit's as requested by the unit dropdown selector + byte unit = WebServerarg(F("unit")).toInt(); + byte btnunit = WebServerarg(F("btnunit")).toInt(); + if(!unit) unit = btnunit; // unit element prevails, if not used then set to btnunit + if (unit && unit != Settings.Unit) + { + char url[20]; + sprintf_P(url, PSTR("http://%u.%u.%u.%u/dashboard.esp"), Nodes[unit].ip[0], Nodes[unit].ip[1], Nodes[unit].ip[2], Nodes[unit].ip[3]); + reply = F(""); + client.print(reply); + return true; + } + + // create unit selector dropdown + addSelector_Head(reply, F("unit"), true); + byte choice = Settings.Unit; + for (byte x = 0; x < UNIT_MAX; x++) + { + if (Nodes[x].ip[0] != 0 || x == Settings.Unit) + { + String name = String(x); + addSelector_Item(reply, name, x, choice == x, false, F("")); + } + } + addSelector_Foot(reply); + + // create <> navigation buttons + byte prev=Settings.Unit; + byte next=Settings.Unit; + for (byte x = Settings.Unit-1; x > 0; x--) + if (Nodes[x].ip[0] != 0) {prev = x; break;} + for (byte x = Settings.Unit+1; x < UNIT_MAX; x++) + if (Nodes[x].ip[0] != 0) {next = x; break;} + + reply += F("<"); + reply += F(">"); + } + + // handle commands from a custom page + String webrequest = WebServerarg(F("cmd")); + if (webrequest.length() > 0){ + struct EventStruct TempEvent; + parseCommandString(&TempEvent, webrequest); + TempEvent.Source = VALUE_SOURCE_HTTP; + + if (PluginCall(PLUGIN_WRITE, &TempEvent, webrequest)); + //else if (remoteConfig(&TempEvent, webrequest)); + else if (webrequest.startsWith(F("event"))) + ExecuteCommand(VALUE_SOURCE_HTTP, webrequest.c_str()); + + // handle some update processes first, before returning page update... + PluginCall(PLUGIN_TEN_PER_SECOND, 0, dummyString); + } + + // create a dynamic custom page, parsing task values into [#] placeholders and parsing %xx% system variables + File dataFile = SD.open(path.c_str(), FILE_READ); + if (dataFile) + { + String page = ""; + while (dataFile.available()) + page += ((char)dataFile.read()); + + reply += parseTemplate(page,0); + dataFile.close(); + } + else // if the requestef file does not exist, create a default action in case the page is named "dashboard*" + { + if (path.startsWith(F("dashboard"))) + { + // if the custom page does not exist, create a basic task value overview page in case of dashboard request... + reply += F(""); + reply += F(""); + for (byte x = 0; x < TASKS_MAX; x++) + { + if (Settings.TaskDeviceNumber[x] != 0) + { + LoadTaskSettings(x); + byte DeviceIndex = getDeviceIndex(Settings.TaskDeviceNumber[x]); + reply += F("
"); + reply += ExtraTaskSettings.TaskDeviceName; + for (byte varNr = 0; varNr < VARS_PER_TASK; varNr++) + { + if ((Settings.TaskDeviceNumber[x] != 0) && (varNr < Device[DeviceIndex].ValueCount) && ExtraTaskSettings.TaskDeviceValueNames[varNr][0] !=0) + { + if (varNr > 0) + reply += F("
"); + reply += F(""); + reply += ExtraTaskSettings.TaskDeviceValueNames[varNr]; + reply += F(""); + reply += String(UserVar[x * VARS_PER_TASK + varNr], ExtraTaskSettings.TaskDeviceValueDecimals[varNr]); + } + } + } + } + } + else + return false; // unknown file that does not exist... + } + client.print(reply); + return true; +} + //******************************************************************************** // Web Interface I2C scanner @@ -2125,3 +2253,70 @@ String URLDecode(const char *src) return rString; } +void addSelector(String& str, const String& id, int optionCount, const String options[], const int indices[], const String attr[], int selectedIndex, boolean reloadonchange) +{ + int index; + + str += F(""); +} + + +void addSelector_Head(String& str, const String& id, boolean reloadonchange) +{ + str += F(""); +} + diff --git a/src/_C001.ino b/src/_C001.ino index 9c6b405..495285d 100644 --- a/src/_C001.ino +++ b/src/_C001.ino @@ -114,16 +114,16 @@ boolean CPlugin_001(byte function, struct EventStruct *event, String& string) url += event->idx; url += F("&switchcmd="); if (UserVar[event->BaseVarIndex] == 0) - url += "Off"; + url += F("Off"); else - url += "On"; + url += F("On"); break; case SENSOR_TYPE_DIMMER: url = F("/json.htm?type=command¶m=switchlight&idx="); url += event->idx; url += F("&switchcmd="); if (UserVar[event->BaseVarIndex] == 0) - url += "Off"; + url += F("Off"); else { url += F("Set%20Level&level="); @@ -136,9 +136,18 @@ boolean CPlugin_001(byte function, struct EventStruct *event, String& string) addLog(LOG_LEVEL_DEBUG_MORE, log); // This will send the request to the server - client.print(String("GET ") + url + " HTTP/1.1\r\n" + - "Host: " + host + "\r\n" + authHeader + - "Connection: close\r\n\r\n"); + String request = F("GET "); + request += url; + request += F(" HTTP/1.1\r\n"); + request += F("Host: "); + request += host; + request += F("\r\n"); + request += authHeader; + request += F("Connection: close\r\n\r\n"); + client.print(request); +// client.print(String("GET ") + url + " HTTP/1.1\r\n" + +// "Host: " + host + "\r\n" + authHeader + +// "Connection: close\r\n\r\n"); unsigned long timer = millis() + 200; while (!client.available() && millis() < timer) diff --git a/src/_C002.ino b/src/_C002.ino index 6f6fea9..417ee86 100644 --- a/src/_C002.ino +++ b/src/_C002.ino @@ -48,15 +48,15 @@ boolean CPlugin_002(byte function, struct EventStruct *event, String& string) if (root.success()) { - long idx = root["idx"]; - float nvalue = root["nvalue"]; - long nvaluealt = root["nvalue"]; + long idx = root[F("idx")]; + float nvalue = root[F("nvalue")]; + long nvaluealt = root[F("nvalue")]; //const char* name = root["name"]; // Not used //const char* svalue = root["svalue"]; // Not used - const char* svalue1 = root["svalue1"]; + const char* svalue1 = root[F("svalue1")]; //const char* svalue2 = root["svalue2"]; // Not used //const char* svalue3 = root["svalue3"]; // Not used - const char* switchtype = root["switchType"]; // Expect "On/Off" or "dimmer" + const char* switchtype = root[F("switchType")]; // Expect "On/Off" or "dimmer" if (nvalue == 0) nvalue = nvaluealt; if ((int)switchtype == 0) @@ -133,45 +133,45 @@ boolean CPlugin_002(byte function, struct EventStruct *event, String& string) switch (event->sensorType) { case SENSOR_TYPE_SINGLE: // single value sensor, used for Dallas, BH1750, etc - root["nvalue"] = 0; + root[F("nvalue")] = 0; values = toString(UserVar[event->BaseVarIndex],ExtraTaskSettings.TaskDeviceValueDecimals[0]); values.toCharArray(str, 80); - root["svalue"] = str; + root[F("svalue")] = str; break; case SENSOR_TYPE_LONG: // single LONG value, stored in two floats (rfid tags) - root["nvalue"] = 0; + root[F("nvalue")] = 0; values = (unsigned long)UserVar[event->BaseVarIndex] + ((unsigned long)UserVar[event->BaseVarIndex + 1] << 16); values.toCharArray(str, 80); - root["svalue"] = str; + root[F("svalue")] = str; break; case SENSOR_TYPE_DUAL: // any sensor that uses two simple values - root["nvalue"] = 0; + root[F("nvalue")] = 0; values = toString(UserVar[event->BaseVarIndex ],ExtraTaskSettings.TaskDeviceValueDecimals[0]); values += ";"; values += toString(UserVar[event->BaseVarIndex + 1],ExtraTaskSettings.TaskDeviceValueDecimals[1]); values.toCharArray(str, 80); - root["svalue"] = str; + root[F("svalue")] = str; break; case SENSOR_TYPE_TEMP_HUM: // temp + hum + hum_stat, used for DHT11 - root["nvalue"] = 0; + root[F("nvalue")] = 0; values = toString(UserVar[event->BaseVarIndex],ExtraTaskSettings.TaskDeviceValueDecimals[0]); values += ";"; values += toString(UserVar[event->BaseVarIndex + 1],ExtraTaskSettings.TaskDeviceValueDecimals[1]); values += ";0"; values.toCharArray(str, 80); - root["svalue"] = str; + root[F("svalue")] = str; break; case SENSOR_TYPE_TEMP_BARO: // temp + hum + hum_stat + bar + bar_fore, used for BMP085 - root["nvalue"] = 0; + root[F("nvalue")] = 0; values = toString(UserVar[event->BaseVarIndex],ExtraTaskSettings.TaskDeviceValueDecimals[0]); values += ";0;0;"; values += toString(UserVar[event->BaseVarIndex + 1],ExtraTaskSettings.TaskDeviceValueDecimals[1]); values += ";0"; values.toCharArray(str, 80); - root["svalue"] = str; + root[F("svalue")] = str; break; case SENSOR_TYPE_TEMP_HUM_BARO: // temp + hum + hum_stat + bar + bar_fore, used for BME280 - root["nvalue"] = 0; + root[F("nvalue")] = 0; values = toString(UserVar[event->BaseVarIndex],ExtraTaskSettings.TaskDeviceValueDecimals[0]); values += ";"; values += toString(UserVar[event->BaseVarIndex + 1],ExtraTaskSettings.TaskDeviceValueDecimals[1]); @@ -179,21 +179,21 @@ boolean CPlugin_002(byte function, struct EventStruct *event, String& string) values += toString(UserVar[event->BaseVarIndex + 2],ExtraTaskSettings.TaskDeviceValueDecimals[2]); values += ";0"; values.toCharArray(str, 80); - root["svalue"] = str; + root[F("svalue")] = str; break; case SENSOR_TYPE_SWITCH: - root["command"] = "switchlight"; + root[F("command")] = String(F("switchlight")); if (UserVar[event->BaseVarIndex] == 0) - root["switchcmd"] = "Off"; + root[F("switchcmd")] = "Off"; else - root["switchcmd"] = "On"; + root[F("switchcmd")] = "On"; break; case SENSOR_TYPE_DIMMER: - root["command"] = "switchlight"; + root[F("command")] = String(F("switchlight")); if (UserVar[event->BaseVarIndex] == 0) - root["switchcmd"] = "Off"; + root[F("switchcmd")] = String(F("Off")); else - root["Set%20Level"] = UserVar[event->BaseVarIndex]; + root[F("Set%20Level")] = UserVar[event->BaseVarIndex]; break; } @@ -204,9 +204,9 @@ boolean CPlugin_002(byte function, struct EventStruct *event, String& string) addLog(LOG_LEVEL_DEBUG, json); String pubname = Settings.MQTTpublish; - pubname.replace("%sysname%", Settings.Name); - pubname.replace("%tskname%", ExtraTaskSettings.TaskDeviceName); - pubname.replace("%id%", String(event->idx)); + pubname.replace(F("%sysname%"), Settings.Name); + pubname.replace(F("%tskname%"), ExtraTaskSettings.TaskDeviceName); + pubname.replace(F("%id%"), String(event->idx)); if (!MQTTclient.publish(pubname.c_str(), json, Settings.MQTTRetainFlag)) { diff --git a/src/_C005.ino b/src/_C005.ino index 57c7f15..75e8578 100644 --- a/src/_C005.ino +++ b/src/_C005.ino @@ -55,7 +55,7 @@ boolean CPlugin_005(byte function, struct EventStruct *event, String& string) String cmd = ""; struct EventStruct TempEvent; - if (topicSplit[count] == "cmd") + if (topicSplit[count] == F("cmd")) { cmd = event->String2; parseCommandString(&TempEvent, cmd); @@ -85,9 +85,9 @@ boolean CPlugin_005(byte function, struct EventStruct *event, String& string) PluginCall(PLUGIN_GET_DEVICEVALUENAMES, event, dummyString); String pubname = Settings.MQTTpublish; - pubname.replace("%sysname%", Settings.Name); - pubname.replace("%tskname%", ExtraTaskSettings.TaskDeviceName); - pubname.replace("%id%", String(event->idx)); + pubname.replace(F("%sysname%"), Settings.Name); + pubname.replace(F("%tskname%"), ExtraTaskSettings.TaskDeviceName); + pubname.replace(F("%id%"), String(event->idx)); String value = ""; byte DeviceIndex = getDeviceIndex(Settings.TaskDeviceNumber[event->TaskIndex]); @@ -95,7 +95,7 @@ boolean CPlugin_005(byte function, struct EventStruct *event, String& string) for (byte x = 0; x < valueCount; x++) { String tmppubname = pubname; - tmppubname.replace("%valname%", ExtraTaskSettings.TaskDeviceValueNames[x]); + tmppubname.replace(F("%valname%"), ExtraTaskSettings.TaskDeviceValueNames[x]); if (event->sensorType == SENSOR_TYPE_LONG) value = (unsigned long)UserVar[event->BaseVarIndex] + ((unsigned long)UserVar[event->BaseVarIndex + 1] << 16); else diff --git a/src/_P005_DHT.ino b/src/_P005_DHT.ino index 8f403f2..e9fa82d 100644 --- a/src/_P005_DHT.ino +++ b/src/_P005_DHT.ino @@ -117,7 +117,8 @@ boolean Plugin_005(byte function, struct EventStruct *event, String& string) dht_dat[i] = data; else { - addLog(LOG_LEVEL_ERROR, (char*)"DHT : protocol timeout!"); + String log = F("DHT : protocol timeout!"); + addLog(LOG_LEVEL_ERROR, log); error = true; } } @@ -172,7 +173,7 @@ boolean Plugin_005(byte function, struct EventStruct *event, String& string) if(!success) { String log = F("DHT : No reading!"); - addLog(LOG_LEVEL_INFO, log); + addLog(LOG_LEVEL_ERROR, log); UserVar[event->BaseVarIndex] = NAN; UserVar[event->BaseVarIndex + 1] = NAN; } diff --git a/src/_P034_DHT12.ino b/src/_P034_DHT12.ino new file mode 100644 index 0000000..a8a647e --- /dev/null +++ b/src/_P034_DHT12.ino @@ -0,0 +1,104 @@ +//####################################################################################################### +//######################## Plugin 034: Temperature and Humidity sensor DHT 12 (I2C) ##################### +//####################################################################################################### + +#define PLUGIN_034 +#define PLUGIN_ID_034 34 +#define PLUGIN_NAME_034 "Temperature & Humidity - DHT12 (I2C)" +#define PLUGIN_VALUENAME1_034 "Temperature" +#define PLUGIN_VALUENAME2_034 "Humidity" + +boolean Plugin_034_init = false; + +#define DHT12_I2C_ADDRESS 0x5C // I2C address for the sensor + +boolean Plugin_034(byte function, struct EventStruct *event, String& string) +{ + boolean success = false; + + switch (function) + { + case PLUGIN_DEVICE_ADD: + { + Device[++deviceCount].Number = PLUGIN_ID_034; + Device[deviceCount].Type = DEVICE_TYPE_I2C; + Device[deviceCount].VType = SENSOR_TYPE_TEMP_HUM; + Device[deviceCount].Ports = 0; + Device[deviceCount].PullUpOption = false; + Device[deviceCount].InverseLogicOption = false; + Device[deviceCount].FormulaOption = true; + Device[deviceCount].ValueCount = 2; + Device[deviceCount].SendDataOption = true; + Device[deviceCount].TimerOption = true; + Device[deviceCount].GlobalSyncOption = true; + break; + } + + case PLUGIN_GET_DEVICENAME: + { + string = F(PLUGIN_NAME_034); + break; + } + + case PLUGIN_GET_DEVICEVALUENAMES: + { + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_034)); + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_034)); + break; + } + + case PLUGIN_READ: + { + byte dht_dat[5]; + byte dht_in; + byte i; + byte Retry = 0; + boolean error = false; + + Wire.beginTransmission(DHT12_I2C_ADDRESS); // start transmission to device + Wire.write(0); // sends register address to read from + Wire.endTransmission(); // end transmission + + Wire.beginTransmission(DHT12_I2C_ADDRESS); // start transmission to device + if (Wire.requestFrom(DHT12_I2C_ADDRESS, 5) == 5) { // send data n-bytes read + for (i = 0; i < 5; i++) + { + dht_dat[i] = Wire.read(); // receive DATA + } + } else { + error = true; + } + if (!error) + { + // Checksum calculation is a Rollover Checksum by design! + byte dht_check_sum = dht_dat[0] + dht_dat[1] + dht_dat[2] + dht_dat[3]; // check check_sum + + if (dht_dat[4] == dht_check_sum) + { + float temperature = float(dht_dat[2]*10 + (dht_dat[3] & 0x7f)) / 10.0; // Temperature + if (dht_dat[3] & 0x80) { temperature = -temperature; } + float humidity = float(dht_dat[0]*10+dht_dat[1]) / 10.0; // Humidity + + UserVar[event->BaseVarIndex] = temperature; + UserVar[event->BaseVarIndex + 1] = humidity; + String log = F("DHT12: Temperature: "); + log += UserVar[event->BaseVarIndex]; + addLog(LOG_LEVEL_INFO, log); + log = F("DHT12: Humidity: "); + log += UserVar[event->BaseVarIndex + 1]; + addLog(LOG_LEVEL_INFO, log); + success = true; + } // checksum + } // error + if(!success) + { + String log = F("DHT12: No reading!"); + addLog(LOG_LEVEL_INFO, log); + UserVar[event->BaseVarIndex] = NAN; + UserVar[event->BaseVarIndex + 1] = NAN; + } + break; + } + } + return success; +}