Add homeassisstant compatibility and choose strongest AP on wifi connection.
This commit is contained in:
parent
bfcb43d22b
commit
5b671ca0be
@ -1059,7 +1059,12 @@ uint8_t WiFiManager::connectWifi(String ssid, String pass, bool connect) {
|
|||||||
else {
|
else {
|
||||||
// connect using saved ssid if there is one
|
// connect using saved ssid if there is one
|
||||||
if (WiFi_hasAutoConnect()) {
|
if (WiFi_hasAutoConnect()) {
|
||||||
|
if (_findBestRSSI) {
|
||||||
|
wifiConnectNew(WiFi_SSID(), WiFi_psk(), connect);
|
||||||
|
} else {
|
||||||
|
// connect to saved ssid
|
||||||
wifiConnectDefault();
|
wifiConnectDefault();
|
||||||
|
}
|
||||||
connRes = waitForConnectResult();
|
connRes = waitForConnectResult();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1110,7 +1115,62 @@ bool WiFiManager::wifiConnectNew(String ssid, String pass,bool connect){
|
|||||||
#endif
|
#endif
|
||||||
WiFi_enableSTA(true,storeSTAmode); // storeSTAmode will also toggle STA on in default opmode (persistent) if true (default)
|
WiFi_enableSTA(true,storeSTAmode); // storeSTAmode will also toggle STA on in default opmode (persistent) if true (default)
|
||||||
WiFi.persistent(true);
|
WiFi.persistent(true);
|
||||||
|
|
||||||
|
|
||||||
|
if (_findBestRSSI) {
|
||||||
|
if (!_numNetworks)
|
||||||
|
WiFi_scanNetworks(); // scan in case this gets called before any scans
|
||||||
|
|
||||||
|
int n = _numNetworks;
|
||||||
|
if (n == 0) {
|
||||||
|
#ifdef WM_DEBUG_LEVEL
|
||||||
|
DEBUG_WM(F("No networks found"));
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
#ifdef WM_DEBUG_LEVEL
|
||||||
|
DEBUG_WM(n, F("networks found"));
|
||||||
|
#endif
|
||||||
|
int bestConnection = -1;
|
||||||
|
// Find best RSSI AP for given SSID
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
if (ssid == WiFi.SSID(i)) {
|
||||||
|
#ifdef WM_DEBUG_LEVEL
|
||||||
|
DEBUG_WM(String(F("SSID ")) + ssid + String(F(" found with RSSI: ")) +
|
||||||
|
String(WiFi.RSSI(i)) + String(F("(")) +
|
||||||
|
String(constrain((100.0 + WiFi.RSSI(i)) * 2, 0, 100)) +
|
||||||
|
String(F(" %) and BSSID: ")) + WiFi.BSSIDstr(i) +
|
||||||
|
String(F(" and channel: ")) + String(WiFi.channel(i)));
|
||||||
|
#endif
|
||||||
|
if (bestConnection == -1) {
|
||||||
|
bestConnection = i;
|
||||||
|
} else {
|
||||||
|
if (WiFi.RSSI(i) > WiFi.RSSI(bestConnection)) {
|
||||||
|
bestConnection = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bestConnection == -1) {
|
||||||
|
#ifdef WM_DEBUG_LEVEL
|
||||||
|
DEBUG_WM(F("No network found with SSID: "), ssid);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
#ifdef WM_DEBUG_LEVEL
|
||||||
|
DEBUG_WM(String(F("Trying to connect to SSID ")) + ssid + String(F(" found with RSSI: ")) +
|
||||||
|
String(WiFi.RSSI(bestConnection)) + String(F("(")) +
|
||||||
|
String(constrain((100.0 + WiFi.RSSI(bestConnection)) * 2, 0, 100)) +
|
||||||
|
String(F(" %) and BSSID: ")) + WiFi.BSSIDstr(bestConnection) +
|
||||||
|
String(F(" and channel: ")) + String(WiFi.channel(bestConnection)));
|
||||||
|
#endif
|
||||||
|
ret = WiFi.begin(ssid.c_str(), pass.c_str(), 0,
|
||||||
|
WiFi.BSSID(bestConnection), connect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
ret = WiFi.begin(ssid.c_str(), pass.c_str(), 0, NULL, connect);
|
ret = WiFi.begin(ssid.c_str(), pass.c_str(), 0, NULL, connect);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
WiFi.persistent(false);
|
WiFi.persistent(false);
|
||||||
#ifdef WM_DEBUG_LEVEL
|
#ifdef WM_DEBUG_LEVEL
|
||||||
if(!ret) DEBUG_WM(WM_DEBUG_ERROR,F("[ERROR] wifi begin failed"));
|
if(!ret) DEBUG_WM(WM_DEBUG_ERROR,F("[ERROR] wifi begin failed"));
|
||||||
@ -3138,6 +3198,12 @@ String WiFiManager::getWiFiHostname(){
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* toggle showing find best RSSID
|
||||||
|
* @param boolean enabled
|
||||||
|
*/
|
||||||
|
void WiFiManager::setFindBestRSSI(boolean enabled) { _findBestRSSI = enabled; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [setTitle description]
|
* [setTitle description]
|
||||||
* @param String title, set app title
|
* @param String title, set app title
|
||||||
|
|||||||
@ -431,6 +431,7 @@ class WiFiManager
|
|||||||
// clean connect, always disconnect before connecting
|
// clean connect, always disconnect before connecting
|
||||||
void setCleanConnect(bool enable); // default false
|
void setCleanConnect(bool enable); // default false
|
||||||
|
|
||||||
|
void setFindBestRSSI(boolean enabled);
|
||||||
// set custom menu items and order, vector or arr
|
// set custom menu items and order, vector or arr
|
||||||
// see _menutokens for ids
|
// see _menutokens for ids
|
||||||
void setMenu(std::vector<const char*>& menu);
|
void setMenu(std::vector<const char*>& menu);
|
||||||
@ -531,6 +532,7 @@ class WiFiManager
|
|||||||
unsigned long _lastscan = 0; // ms for timing wifi scans
|
unsigned long _lastscan = 0; // ms for timing wifi scans
|
||||||
unsigned long _startscan = 0; // ms for timing wifi scans
|
unsigned long _startscan = 0; // ms for timing wifi scans
|
||||||
unsigned long _startconn = 0; // ms for timing wifi connects
|
unsigned long _startconn = 0; // ms for timing wifi connects
|
||||||
|
boolean _findBestRSSI = true; // find best rssi ap in wifiscan
|
||||||
|
|
||||||
// defaults
|
// defaults
|
||||||
const byte DNS_PORT = 53;
|
const byte DNS_PORT = 53;
|
||||||
|
|||||||
@ -15,7 +15,7 @@ monitor_speed = 115200
|
|||||||
framework = arduino
|
framework = arduino
|
||||||
board_build.partitions = min_spiffs.csv
|
board_build.partitions = min_spiffs.csv
|
||||||
upload_protocol = espota
|
upload_protocol = espota
|
||||||
upload_port = TMP-EG-Bad.fritz.box
|
upload_port = TMP-EG-WoZi.fritz.box
|
||||||
lib_deps =
|
lib_deps =
|
||||||
moononournation/GFX Library for Arduino@^1.5.3
|
moononournation/GFX Library for Arduino@^1.5.3
|
||||||
lvgl/lvgl@^9.4.0
|
lvgl/lvgl@^9.4.0
|
||||||
|
|||||||
@ -36,7 +36,15 @@ void MQTT::begin(){
|
|||||||
wm.setConnectRetries(5);
|
wm.setConnectRetries(5);
|
||||||
wm.setWiFiAutoReconnect(true);
|
wm.setWiFiAutoReconnect(true);
|
||||||
wm.setMinimumSignalQuality(20);
|
wm.setMinimumSignalQuality(20);
|
||||||
WiFi.persistent(true);
|
WiFi.setSortMethod(WIFI_CONNECT_AP_BY_SIGNAL);
|
||||||
|
WiFi.setScanMethod(WIFI_ALL_CHANNEL_SCAN);
|
||||||
|
WiFi.persistent(false);
|
||||||
|
WiFi.mode(WIFI_OFF);
|
||||||
|
WiFi.mode(WIFI_STA);
|
||||||
|
WiFi.disconnect(true); // delete old config
|
||||||
|
WiFi.begin();
|
||||||
|
delay(500); // 500ms seems to work in most cases, may depend on AP
|
||||||
|
WiFi.disconnect(true); // delete old config
|
||||||
WiFi.setAutoConnect(true);
|
WiFi.setAutoConnect(true);
|
||||||
WiFi.setAutoReconnect(true);
|
WiFi.setAutoReconnect(true);
|
||||||
wm.addParameter(&custom_hostname);
|
wm.addParameter(&custom_hostname);
|
||||||
@ -47,6 +55,7 @@ void MQTT::begin(){
|
|||||||
wm.addParameter(&custom_enbuff);
|
wm.addParameter(&custom_enbuff);
|
||||||
wm.addParameter(&custom_ntpServer);
|
wm.addParameter(&custom_ntpServer);
|
||||||
psclient.setClient(client);
|
psclient.setClient(client);
|
||||||
|
psclient.setBufferSize(1024);
|
||||||
psclient.setServer(Settings::prefs.mqtt_server,Settings::prefs.mqtt_port);
|
psclient.setServer(Settings::prefs.mqtt_server,Settings::prefs.mqtt_port);
|
||||||
psclient.setCallback(receiveTopic);
|
psclient.setCallback(receiveTopic);
|
||||||
WiFi.setHostname(custom_hostname.getValue()); //define hostname
|
WiFi.setHostname(custom_hostname.getValue()); //define hostname
|
||||||
@ -156,6 +165,7 @@ void MQTT::receiveTopic(char* topic, byte* payload, unsigned int length) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MQTT::reconnect(void) {
|
void MQTT::reconnect(void) {
|
||||||
// Loop until we're reconnected
|
// Loop until we're reconnected
|
||||||
Serial.print("Attempting MQTT connection...");
|
Serial.print("Attempting MQTT connection...");
|
||||||
@ -170,7 +180,7 @@ void MQTT::reconnect(void) {
|
|||||||
strcat(newtopic,"/changeMode");
|
strcat(newtopic,"/changeMode");
|
||||||
psclient.subscribe(newtopic);
|
psclient.subscribe(newtopic);
|
||||||
Serial.println("connected");
|
Serial.println("connected");
|
||||||
|
sendHAautodiscovery();
|
||||||
} else {
|
} else {
|
||||||
Serial.print("failed, rc=");
|
Serial.print("failed, rc=");
|
||||||
Serial.print(psclient.state());
|
Serial.print(psclient.state());
|
||||||
@ -392,7 +402,38 @@ void MQTT::sendStatus(void){
|
|||||||
}else{
|
}else{
|
||||||
publish_sub("mode","Unknown",true);
|
publish_sub("mode","Unknown",true);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MQTT::sendHAautodiscovery(void){
|
||||||
|
char buffer[128];
|
||||||
|
char payload[1024];
|
||||||
|
String devName = Settings::prefs.mqtt_topic;
|
||||||
|
devName.replace("Raumtemp/","Thermostat ");
|
||||||
|
devName.replace("/"," ");
|
||||||
|
snprintf(buffer,sizeof(buffer),"homeassistant/climate/%s/thermostat/config",Settings::prefs.hostname);
|
||||||
|
snprintf(payload, sizeof(payload),"{\"name\":\"%s\",\"unique_id\":\"%s_climate\",\"current_temperature_topic\":\"%s/Temp[degC]\",\"temperature_state_topic\":\"%s/Set Temp[degC]\",\"temperature_command_topic\":\"%s/changeSetTemp\",\"min_temp\":5,\"max_temp\":30,\"mode_state_topic\":\"%s/mode\",\"mode_command_topic\":\"%s/changeMode\",\"modes\":[\"normal\",\"frost-prevention\",\"overheating\"],\"device\":{\"identifiers\":[\"%s\"],\"name\":\"%s\",\"model\":\"ESP32 Thermostat\",\"manufacturer\":\"DIY\"}}", devName.c_str(),Settings::prefs.hostname,Settings::prefs.mqtt_topic,Settings::prefs.mqtt_topic,Settings::prefs.mqtt_topic,Settings::prefs.mqtt_topic,Settings::prefs.mqtt_topic,Settings::prefs.hostname, devName.c_str());
|
||||||
|
psclient.publish(buffer,payload,true);
|
||||||
|
psclient.loop();
|
||||||
|
snprintf(buffer,sizeof(buffer),"homeassistant/binary_sensor/%s/heating/config",Settings::prefs.hostname);
|
||||||
|
snprintf(payload, sizeof(payload),"{\"name\":\"Heizung aktiv\",\"unique_id\":\"%s_heating\",\"state_topic\":\"%s/Heating\",\"payload_on\":\"true\",\"payload_off\":\"false\",\"device_class\":\"heat\",\"device\":{\"identifiers\":[\"%s\"],\"name\":\"%s\"}}",Settings::prefs.hostname,Settings::prefs.mqtt_topic,Settings::prefs.hostname, devName.c_str());
|
||||||
|
psclient.publish(buffer,payload,true);
|
||||||
|
psclient.loop();
|
||||||
|
snprintf(buffer,sizeof(buffer),"homeassistant/sensor/%s/temperature/config",Settings::prefs.hostname);
|
||||||
|
snprintf(payload, sizeof(payload),"{\"name\":\"Temperatur\",\"unique_id\":\"%s_temp\",\"state_topic\":\"%s/Temp[degC]\",\"unit_of_measurement\": \"°C\",\"device_class\": \"temperature\",\"state_class\": \"measurement\",\"device\":{\"identifiers\":[\"%s\"],\"name\":\"%s\"}}",Settings::prefs.hostname,Settings::prefs.mqtt_topic,Settings::prefs.hostname, devName.c_str());
|
||||||
|
psclient.publish(buffer,payload,true);
|
||||||
|
psclient.loop();
|
||||||
|
snprintf(buffer,sizeof(buffer),"homeassistant/sensor/%s/humidity/config",Settings::prefs.hostname);
|
||||||
|
snprintf(payload, sizeof(payload),"{\"name\":\"Luftfeuchte\",\"unique_id\":\"%s_hum\",\"state_topic\":\"%s/rHum[%%]\",\"unit_of_measurement\": \"%%\",\"device_class\": \"humidity\",\"state_class\": \"measurement\",\"device\":{\"identifiers\":[\"%s\"],\"name\":\"%s\"}}",Settings::prefs.hostname,Settings::prefs.mqtt_topic,Settings::prefs.hostname, devName.c_str());
|
||||||
|
psclient.publish(buffer,payload,true);
|
||||||
|
psclient.loop();
|
||||||
|
snprintf(buffer,sizeof(buffer),"homeassistant/sensor/%s/pressure/config",Settings::prefs.hostname);
|
||||||
|
snprintf(payload, sizeof(payload),"{\"name\":\"Luftdruck\",\"unique_id\":\"%s_pres\",\"state_topic\":\"%s/pressure[hPa]\",\"unit_of_measurement\": \"hPa\",\"device_class\": \"pressure\",\"state_class\": \"measurement\",\"device\":{\"identifiers\":[\"%s\"],\"name\":\"%s\"}}",Settings::prefs.hostname,Settings::prefs.mqtt_topic,Settings::prefs.hostname, devName.c_str());
|
||||||
|
psclient.publish(buffer,payload,true);
|
||||||
|
psclient.loop();
|
||||||
|
snprintf(buffer,sizeof(buffer),"homeassistant/sensor/%s/hostname/config",Settings::prefs.hostname);
|
||||||
|
snprintf(payload, sizeof(payload),"{\"name\":\"Luftdruck\",\"unique_id\":\"%s_host\",\"state_topic\":\"%s/hostname\",\"entity_category\": \"diagnostic\",\"device\":{\"identifiers\":[\"%s\"],\"name\":\"%s\"}}",Settings::prefs.hostname,Settings::prefs.mqtt_topic,Settings::prefs.hostname, devName.c_str());
|
||||||
|
psclient.publish(buffer,payload,true);
|
||||||
|
psclient.loop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MQTT::remoteLog(const char* str, int32_t num){
|
void MQTT::remoteLog(const char* str, int32_t num){
|
||||||
|
|||||||
@ -36,6 +36,7 @@ public:
|
|||||||
WiFiManager wm;
|
WiFiManager wm;
|
||||||
static WiFiUDP udp;
|
static WiFiUDP udp;
|
||||||
void sendStatus(void);
|
void sendStatus(void);
|
||||||
|
void sendHAautodiscovery(void);
|
||||||
char* getMqttServer(void);
|
char* getMqttServer(void);
|
||||||
uint16_t getMqttPort(void);
|
uint16_t getMqttPort(void);
|
||||||
char* getHostname(void);
|
char* getHostname(void);
|
||||||
@ -45,10 +46,8 @@ public:
|
|||||||
void begin();
|
void begin();
|
||||||
void loop(void);
|
void loop(void);
|
||||||
void publish(const char* msg);
|
void publish(const char* msg);
|
||||||
void publish(String msg);
|
|
||||||
void publish(const char* msg, unsigned int len);
|
void publish(const char* msg, unsigned int len);
|
||||||
void publish(const char* msg, bool retained);
|
void publish(const char* msg, bool retained);
|
||||||
void publish(const char* msg, unsigned int len, bool retained);
|
|
||||||
void publish_sub(const char* subtopic, const char* msg, bool retained = false);
|
void publish_sub(const char* subtopic, const char* msg, bool retained = false);
|
||||||
static void remoteLog(const char* str,const char* str2);
|
static void remoteLog(const char* str,const char* str2);
|
||||||
static void remoteLog(const char* str);
|
static void remoteLog(const char* str);
|
||||||
@ -66,10 +65,6 @@ private:
|
|||||||
//static void serveSetValve(AsyncWebServerRequest *request);
|
//static void serveSetValve(AsyncWebServerRequest *request);
|
||||||
// static void handleWebSocket(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len);
|
// static void handleWebSocket(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len);
|
||||||
// static void handleWebSocketMessage(void *arg, uint8_t *data, size_t len);
|
// static void handleWebSocketMessage(void *arg, uint8_t *data, size_t len);
|
||||||
static String processor(const String& var);
|
|
||||||
static String makeStatusJSON(void);
|
|
||||||
static String makeTimerJSON(void);
|
|
||||||
void sendMQTTstatus(void);
|
|
||||||
void saveConfigToFlash(void);
|
void saveConfigToFlash(void);
|
||||||
static void saveConfigCallback(void);
|
static void saveConfigCallback(void);
|
||||||
unsigned long lastReconnectTry{0};
|
unsigned long lastReconnectTry{0};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user