mirror of
https://github.com/letscontrolit/ArduinoEasy.git
synced 2026-03-11 04:16:51 +01:00
Fixed syslog and some memory reductions
This commit is contained in:
@@ -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
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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("><</a>");
|
||||
reply += F("<a class='button link' href=");
|
||||
reply += path;
|
||||
reply += F("?btnunit=");
|
||||
reply += next;
|
||||
reply += F(">></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>");
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
104
src/_P034_DHT12.ino
Normal 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;
|
||||
}
|
||||
Reference in New Issue
Block a user