Fixed syslog and some memory reductions

This commit is contained in:
mvdbro
2017-08-11 17:28:17 +02:00
parent bf6da2fa21
commit 38a7ad8986
9 changed files with 374 additions and 58 deletions

View File

@@ -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
{

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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("<a href='http://%u.%u.%u.%u'>%u.%u.%u.%u</a>"), 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("<a href='http://%u.%u.%u.%u'>%u.%u.%u.%u</a>"), 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("<a class='button-link' href='http://%u.%u.%u.%u'>%u.%u.%u.%u</a>"), 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("<TR><TD>Unit ");
reply += x;
reply += F("<TD>");
@@ -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("<script><!--\n"
"function dept_onchange(frmselect) {frmselect.submit();}"
"\n//--></script>");
reply += F("<form name='frmselect' method='post'>");
// 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("<meta http-equiv=\"refresh\" content=\"0; URL=");
reply += url;
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("<a class='button link' href=");
reply += path;
reply += F("?btnunit=");
reply += prev;
reply += F(">&lt;</a>");
reply += F("<a class='button link' href=");
reply += path;
reply += F("?btnunit=");
reply += next;
reply += F(">&gt;</a>");
}
// 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 [<taskname>#<taskvalue>] 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("<meta name=\"viewport\" content=\"width=width=device-width, initial-scale=1\"><STYLE>* {font-family:sans-serif; font-size:16pt;}.button {margin:4px; padding:4px 16px; background-color:#07D; color:#FFF; text-decoration:none; border-radius:4px}</STYLE>");
reply += F("<table>");
for (byte x = 0; x < TASKS_MAX; x++)
{
if (Settings.TaskDeviceNumber[x] != 0)
{
LoadTaskSettings(x);
byte DeviceIndex = getDeviceIndex(Settings.TaskDeviceNumber[x]);
reply += F("<TR><TD>");
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("<TR><TD>");
reply += F("<TD>");
reply += ExtraTaskSettings.TaskDeviceValueNames[varNr];
reply += F("<TD>");
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("<select name='");
str += id;
str += F("'");
if (reloadonchange)
str += F(" onchange=\"return dept_onchange(frmselect)\"");
str += F(">");
for (byte x = 0; x < optionCount; x++)
{
if (indices)
index = indices[x];
else
index = x;
str += F("<option value=");
str += index;
if (selectedIndex == index)
str += F(" selected");
if (attr)
{
str += F(" ");
str += attr[x];
}
str += ">";
str += options[x];
str += F("</option>");
}
str += F("</select>");
}
void addSelector_Head(String& str, const String& id, boolean reloadonchange)
{
str += F("<select name='");
str += id;
str += F("'");
if (reloadonchange)
str += F(" onchange=\"return dept_onchange(frmselect)\"");
str += F(">");
}
void addSelector_Item(String& str, const String& option, int index, boolean selected, boolean disabled, const String& attr)
{
str += F("<option value=");
str += index;
if (selected)
str += F(" selected");
if (disabled)
str += F(" disabled");
if (attr && attr.length() > 0)
{
str += F(" ");
str += attr;
}
str += ">";
str += option;
str += F("</option>");
}
void addSelector_Foot(String& str)
{
str += F("</select>");
}

View File

@@ -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&param=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)

View File

@@ -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))
{

View File

@@ -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

View File

@@ -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;
}

104
src/_P034_DHT12.ino Normal file
View File

@@ -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;
}