287 lines
9.4 KiB
C++
287 lines
9.4 KiB
C++
#include "MQTT.h"
|
|
|
|
|
|
|
|
WebServer MQTT::server = WebServer(80);
|
|
|
|
bool MQTT::saveConfigFlag=false;
|
|
WiFiManagerParameter custom_hostname("hostname", "Hostname", "", 40);
|
|
WiFiManagerParameter custom_mqtt_server("server", "mqtt server", "", 40);
|
|
WiFiManagerParameter custom_mqtt_port("port", "mqtt port", "",6);
|
|
WiFiManagerParameter custom_mqtt_topic("topic", "topic", "", 40);
|
|
WiFiManagerParameter custom_deftemp("deftemp", "Default Temperature", "", 6);
|
|
WiFiManagerParameter custom_enbuff("enBuff", "Enable heatBuffer", "", 6);
|
|
|
|
MQTT::MQTT(){
|
|
|
|
}
|
|
|
|
void MQTT::serveOverride(void){
|
|
String sending;
|
|
sending = "{";
|
|
if(server.args() == 1 && glblData.enBuff){
|
|
if(server.argName(0)=="SW" || server.argName(0)=="sw"){
|
|
if(server.arg(0) == "ON"){
|
|
glblData.override = OVR_ALWAYSON;
|
|
sending = "{\"Status\": \"Success\", ";
|
|
}else if(server.arg(0) == "OFF"){
|
|
glblData.override = OVR_ALWAYSOFF;
|
|
sending = "{\"Status\": \"Success\", ";
|
|
}else{
|
|
glblData.override = OVR_NONE;
|
|
sending = "{\"Status\": \"Success\", ";
|
|
}
|
|
}
|
|
}else if(!glblData.enBuff){
|
|
sending = "{\"Status\": \"Not Enabled\", ";
|
|
glblData.override = OVR_NONE;
|
|
}
|
|
switch(glblData.override){
|
|
case OVR_ALWAYSOFF:
|
|
sending += "\"Override\": \"Always OFF\"}";
|
|
break;
|
|
case OVR_ALWAYSON:
|
|
sending += "\"Override\": \"Always ON\"}";
|
|
break;
|
|
case OVR_NONE:
|
|
sending += "\"Override\": \"NONE\"}";
|
|
break;
|
|
}
|
|
server.send(404, "text/plain", sending);
|
|
}
|
|
|
|
void MQTT::serveData(void){
|
|
String sending;
|
|
sending = "{\"Temp[degC]\": ";
|
|
sending += glblData.temp;
|
|
sending += ", \"pressure[hPa]\": ";
|
|
sending += glblData.seaLevelPress;
|
|
sending += ", \"rHum[%]\": ";
|
|
sending += glblData.hum;
|
|
sending += ", \"Heating\": ";
|
|
sending += glblData.heating;
|
|
sending += ", \"Set Temp[degC]\": ";
|
|
sending += glblData.settemp;
|
|
sending += " }";
|
|
Serial.println("Sending website...");
|
|
server.send(200, FPSTR(HTTP_HEAD_JSON), sending);
|
|
Serial.println("Sent website...");
|
|
/*
|
|
request->send(404, "text/plain", sending);*/
|
|
}
|
|
|
|
|
|
|
|
void MQTT::sendStatus(void){
|
|
char buffer[10];
|
|
snprintf(buffer, sizeof buffer, "%0.1f", glblData.temp);
|
|
publish_sub("Temp[degC]",buffer);
|
|
snprintf(buffer, sizeof buffer, "%0.0f", glblData.seaLevelPress);
|
|
publish_sub("pressure[hPa]",buffer);
|
|
snprintf(buffer, sizeof buffer, "%0.0f", glblData.hum);
|
|
publish_sub("rHum[%]",buffer);
|
|
snprintf(buffer, sizeof buffer, "%s", digitalRead(PIN_REL)?"true":"false");
|
|
publish_sub("Heating",buffer);
|
|
snprintf(buffer, sizeof buffer, "%0.1f", glblData.settemp);
|
|
publish_sub("Set Temp[degC]",buffer);
|
|
}
|
|
|
|
|
|
void MQTT::begin(){
|
|
saveConfigFlag = false;
|
|
prefs.begin("settings");
|
|
prefs.getString("HOST",hostname,40);
|
|
prefs.getString("MQTT_SERVER",mqtt_server,40);
|
|
mqtt_port = prefs.getInt("MQTT_PORT",mqtt_port);
|
|
prefs.getString("MQTT_TOPIC",mqtt_topic,40);
|
|
defTemp = prefs.getFloat("DEF_TMP",defTemp);
|
|
enBuff = prefs.getBool("EN_OVR",enBuff);
|
|
glblData.enBuff = enBuff;
|
|
ui_settemp(defTemp);
|
|
prefs.end();
|
|
wm.setSaveConfigCallback(MQTT::saveConfigCallback);
|
|
custom_hostname.setValue(hostname,40);
|
|
custom_mqtt_server.setValue(mqtt_server,40);
|
|
custom_mqtt_port.setValue(String(mqtt_port).c_str(),6);
|
|
custom_mqtt_topic.setValue(mqtt_topic,40);
|
|
custom_deftemp.setValue(String(defTemp).c_str(),6);
|
|
custom_enbuff.setValue(String(enBuff).c_str(),6);
|
|
wm.addParameter(&custom_hostname);
|
|
wm.addParameter(&custom_mqtt_server);
|
|
wm.addParameter(&custom_mqtt_port);
|
|
wm.addParameter(&custom_mqtt_topic);
|
|
wm.addParameter(&custom_deftemp);
|
|
wm.addParameter(&custom_enbuff);
|
|
psclient.setClient(client);
|
|
psclient.setServer(mqtt_server,mqtt_port);
|
|
WiFi.setHostname(custom_hostname.getValue()); //define hostname
|
|
wm.setConfigPortalBlocking(false);
|
|
|
|
|
|
if(wm.autoConnect("AutoConnectAP")){
|
|
//if you get here you have connected to the WiFi
|
|
Serial.println("connected...yeey :)");
|
|
strcpy(myIP,WiFi.localIP().toString().c_str());
|
|
wm.setHttpPort(8080);
|
|
wm.startWebPortal();
|
|
wifiConnected = true;
|
|
}
|
|
else
|
|
{
|
|
wm.startWebPortal();
|
|
Serial.println("non blocking config portal running on Port 80");
|
|
}
|
|
if(wifiConnected){
|
|
ArduinoOTA.setHostname(hostname);
|
|
ArduinoOTA
|
|
.onStart([]() {
|
|
String type;
|
|
if (ArduinoOTA.getCommand() == U_FLASH)
|
|
type = "sketch";
|
|
else // U_SPIFFS
|
|
type = "filesystem";
|
|
|
|
// NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
|
|
Serial.println("Start updating " + type);
|
|
})
|
|
.onEnd([]() {
|
|
Serial.println("\nEnd");
|
|
})
|
|
.onProgress([](unsigned int progress, unsigned int total) {
|
|
Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
|
|
})
|
|
.onError([](ota_error_t error) {
|
|
Serial.printf("Error[%u]: ", error);
|
|
if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
|
|
else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
|
|
else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
|
|
else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
|
|
else if (error == OTA_END_ERROR) Serial.println("End Failed");
|
|
});
|
|
ArduinoOTA.begin();
|
|
|
|
// This is not the safest way to reset the webserver, it can cause crashes on callbacks initilized before this and since its a shared pointer...
|
|
// @todo add a new callback maybe, after webserver started, callback cannot override handlers, but can grab them first
|
|
|
|
/* Setup httpd callbacks, web pages: root, wifi config pages, SO captive portal detectors and not found. */
|
|
|
|
// G macro workaround for Uri() bug https://github.com/esp8266/Arduino/issues/7102
|
|
server.on("/", MQTT::serveData);
|
|
server.on("/override", MQTT::serveOverride);
|
|
server.on("/data", MQTT::serveData);
|
|
server.begin();
|
|
reconnect();
|
|
}
|
|
}
|
|
void MQTT::saveConfigCallback(void){
|
|
Serial.println("SAVE");
|
|
saveConfigFlag = true;
|
|
}
|
|
|
|
void MQTT::saveConfigToFlash(void){
|
|
strcpy(mqtt_server,custom_mqtt_server.getValue());
|
|
mqtt_port = atoi(custom_mqtt_port.getValue());
|
|
strcpy(hostname,custom_hostname.getValue());
|
|
strcpy(mqtt_topic,custom_mqtt_topic.getValue());
|
|
defTemp = atof(custom_deftemp.getValue());
|
|
if(custom_enbuff.getValue() != "0"){
|
|
enBuff = true;
|
|
}
|
|
glblData.enBuff = enBuff;
|
|
prefs.begin("settings");
|
|
prefs.putString("HOST",hostname);
|
|
prefs.putString("MQTT_SERVER",mqtt_server);
|
|
prefs.putInt("MQTT_PORT",mqtt_port);
|
|
prefs.putString("MQTT_TOPIC",mqtt_topic);
|
|
prefs.putFloat("DEF_TMP",defTemp);
|
|
prefs.putBool("EN_OVR",enBuff);
|
|
prefs.end();
|
|
|
|
}
|
|
|
|
void MQTT::reconnect(void) {
|
|
// Loop until we're reconnected
|
|
Serial.print("Attempting MQTT connection...");
|
|
// Attempt to connect
|
|
if (psclient.connect(hostname)) {
|
|
Serial.println("connected");
|
|
// Subscribe
|
|
if(strlen(mqtt_topic)>1)
|
|
psclient.subscribe(mqtt_topic);
|
|
} else {
|
|
Serial.print("failed, rc=");
|
|
Serial.print(psclient.state());
|
|
}
|
|
}
|
|
|
|
void MQTT::loop(void){
|
|
unsigned long now = millis();
|
|
if(now-lastStatusUpdate > 15000){ //update wifi status every 15secs.
|
|
lastStatusUpdate = now;
|
|
if(WiFi.isConnected()){
|
|
int32_t rssi = WiFi.RSSI();
|
|
if(rssi > -55){
|
|
update_wifi_strength(WIFI_STRENGTH_HIGH);
|
|
}else if(rssi > -75){
|
|
update_wifi_strength(WIFI_STRENGTH_MED);
|
|
}else if(rssi > -90){
|
|
update_wifi_strength(WIFI_STRENGTH_LOW);
|
|
}else{
|
|
update_wifi_strength(WIFI_STRENGTH_OFF);
|
|
}
|
|
if(!psclient.connected()){
|
|
update_wifi_strength(WIFI_STRENGTH_ERROR);
|
|
if(now-lastReconnectTry > 60000){
|
|
lastReconnectTry = now;
|
|
reconnect();
|
|
}
|
|
}
|
|
}else{
|
|
update_wifi_strength(WIFI_STRENGTH_OFF);
|
|
}
|
|
}
|
|
server.handleClient();
|
|
psclient.loop();
|
|
ArduinoOTA.handle();
|
|
wm.process();
|
|
if(saveConfigFlag){
|
|
Serial.println("Save Settings");
|
|
saveConfigFlag = false;
|
|
saveConfigToFlash();
|
|
Serial.println("disconnect mqtt to activate new settings");
|
|
psclient.disconnect();
|
|
}
|
|
}
|
|
|
|
char* MQTT::getMqttServer(void){
|
|
return mqtt_server;
|
|
}
|
|
uint16_t MQTT::getMqttPort(void){
|
|
return mqtt_port;
|
|
}
|
|
char* MQTT::getHostname(void){
|
|
return hostname;
|
|
}
|
|
char* MQTT::getMqttTopic(void){
|
|
return mqtt_topic;
|
|
}
|
|
char* MQTT::getMyIP(void){
|
|
return myIP;
|
|
}
|
|
|
|
void MQTT::publish(const char* msg){
|
|
psclient.publish(mqtt_topic,msg);
|
|
}
|
|
void MQTT::publish(const char* msg, unsigned int len){
|
|
psclient.publish(mqtt_topic,msg,len);
|
|
}
|
|
void MQTT::publish(const char* msg, bool retained){
|
|
psclient.publish(mqtt_topic,msg,retained);
|
|
}
|
|
void MQTT::publish_sub(const char* subtopic, const char* msg){
|
|
char newtopic[60];
|
|
strcpy(newtopic,mqtt_topic);
|
|
strcat(newtopic,"/");
|
|
strcat(newtopic,subtopic);
|
|
psclient.publish(newtopic,msg);
|
|
} |