Add Wifi and mqtt broker configuration over MQTT commands (#971)

- Adds MQTT command to change the WiFi access point.
- Adds MQTT command to change the MQTT broker and update username and password.

This will test the connection changes first and, if unsuccessful, fallback to the current connection.
If successful the new configuration will be saved in non-volatile memory.
This commit is contained in:
h2zero authored and GitHub committed 2021-06-05 16:52:30 -05:00
1 parent 31efcb32ee
commit b8b99c6d5d
2 files changed
+156 -31

No files matched your search

+25
View File
@@ -33,6 +33,31 @@ If you want the settings to be kept upon gateway restart, you can publish the co
Auto discovery is enable by default on release binaries, on platformio (except for UNO). With Arduino IDE please read the [advanced configuration section](../upload/advanced-configuration#auto-discovery) of the documentation.
:::
## Change the WiFi credentials
`mosquitto_pub -t "home/OpenMQTTGateway/commands/MQTTtoSYS/config" -m '{"wifi_ssid":"ssid", "wifi_pass":"password"}'`
::: tip
If the new connection fails the gateway will fallback to the previous connection.
:::
## Change the MQTT broker credentials
```
mosquitto_pub -t "home/OpenMQTTGateway/commands/MQTTtoSYS/config" -m
'{
"mqtt_user": "user_name",
"mqtt_pass": "password",
"mqtt_server": "host",
"mqtt_port": "port",
"mqtt_secure": "false"
}'
```
::: tip
Server, port, and secure_flag are only required if changing connection to another broker.
If the new connection fails the gateway will fallback to the previous connection.
:::
# Firmware update from MQTT (ESP only)
The gateway can be updated through an MQTT message by providing a JSON formatted message with a version number, OTA password (optional, see below), and URL to fetch the update from.
+131 -31
View File
@@ -272,7 +272,7 @@ bool to_bool(String const& s) { // thanks Chris Jester-Young from stackoverflow
}
void pub(const char* topicori, const char* payload, bool retainFlag) {
String topic = String(mqtt_topic) + String(topicori);
String topic = String(mqtt_topic) + String(gateway_name) + String(topicori);
pubMQTT(topic.c_str(), payload, retainFlag);
}
@@ -281,7 +281,7 @@ void pub(const char* topicori, JsonObject& data) {
digitalWrite(LED_RECEIVE, LED_RECEIVE_ON);
logJson(data);
if (client.connected()) {
String topic = String(mqtt_topic) + String(topicori);
String topic = String(mqtt_topic) + String(gateway_name) + String(topicori);
#ifdef valueAsASubject
# ifdef ZgatewayPilight
String value = data["value"];
@@ -337,7 +337,7 @@ void pub(const char* topicori, JsonObject& data) {
void pub(const char* topicori, const char* payload) {
if (client.connected()) {
String topic = String(mqtt_topic) + String(topicori);
String topic = String(mqtt_topic) + String(gateway_name) + String(topicori);
Log.trace(F("Pub ack %s into: %s" CR), payload, topic.c_str());
pubMQTT(topic, payload);
} else {
@@ -460,6 +460,7 @@ void logJson(JsonObject& jsondata) {
bool cmpToMainTopic(const char* topicOri, const char* toAdd) {
char topic[mqtt_topic_max_size];
strcpy(topic, mqtt_topic);
strcat(topic, gateway_name);
strcat(topic, toAdd);
if (strstr(topicOri, topic) != NULL) {
return true;
@@ -478,6 +479,7 @@ void connectMQTT() {
Log.warning(F("MQTT connection..." CR));
char topic[mqtt_topic_max_size];
strcpy(topic, mqtt_topic);
strcat(topic, gateway_name);
strcat(topic, will_Topic);
client.setBufferSize(mqtt_max_packet_size);
if (client.connect(gateway_name, mqtt_user, mqtt_pass, topic, will_QoS, will_Retain, will_Message)) {
@@ -494,6 +496,7 @@ void connectMQTT() {
//Subscribing to topic
char topic2[mqtt_topic_max_size];
strcpy(topic2, mqtt_topic);
strcat(topic2, gateway_name);
strcat(topic2, subjectMQTTtoX);
if (client.subscribe(topic2)) {
#ifdef ZgatewayRF
@@ -545,10 +548,6 @@ void callback(char* topic, byte* payload, unsigned int length) {
free(p);
}
void setup_parameters() {
strcat(mqtt_topic, gateway_name);
}
void setup() {
//Launch serial for debugging purposes
Serial.begin(SERIAL_BAUD);
@@ -623,8 +622,6 @@ void setup() {
client.setServer(mqtt_server, port);
#endif
setup_parameters();
client.setCallback(callback);
delay(1500);
@@ -961,6 +958,29 @@ void eraseAndRestart() {
# endif
}
void saveMqttConfig() {
Log.trace(F("saving config" CR));
DynamicJsonBuffer jsonBuffer;
JsonObject& json = jsonBuffer.createObject();
json["mqtt_server"] = mqtt_server;
json["mqtt_port"] = mqtt_port;
json["mqtt_user"] = mqtt_user;
json["mqtt_pass"] = mqtt_pass;
json["mqtt_topic"] = mqtt_topic;
json["gateway_name"] = gateway_name;
json["mqtt_broker_secure"] = mqtt_secure;
json["mqtt_broker_cert"] = mqtt_cert;
File configFile = SPIFFS.open("/config.json", "w");
if (!configFile) {
Log.error(F("failed to open config file for writing" CR));
}
json.printTo(Serial);
json.printTo(configFile);
configFile.close();
}
void setup_wifimanager(bool reset_settings) {
# ifdef TRIGGER_GPIO
pinMode(TRIGGER_GPIO, INPUT_PULLUP);
@@ -1128,27 +1148,7 @@ void setup_wifimanager(bool reset_settings) {
}
//save the custom parameters to FS
Log.trace(F("saving config" CR));
DynamicJsonBuffer jsonBuffer;
JsonObject& json = jsonBuffer.createObject();
json["mqtt_server"] = mqtt_server;
json["mqtt_port"] = mqtt_port;
json["mqtt_user"] = mqtt_user;
json["mqtt_pass"] = mqtt_pass;
json["mqtt_topic"] = mqtt_topic;
json["gateway_name"] = gateway_name;
json["mqtt_secure"] = mqtt_secure;
json["mqtt_cert"] = mqtt_cert;
File configFile = SPIFFS.open("/config.json", "w");
if (!configFile) {
Log.error(F("failed to open config file for writing" CR));
}
json.printTo(Serial);
json.printTo(configFile);
configFile.close();
//end save
saveMqttConfig();
}
}
# ifdef ESP32_ETHERNET
@@ -1809,7 +1809,107 @@ void MQTTtoSYS(char* topicOri, JsonObject& SYSdata) { // json object decoding
stateMeasures();
}
}
if (SYSdata.containsKey("wifi_ssid") && SYSdata.containsKey("wifi_pass")) {
# if defined(ZgatewayBT) && defined(ESP32)
stopProcessing();
# endif
String prev_ssid = WiFi.SSID();
String prev_pass = WiFi.psk();
client.disconnect();
WiFi.disconnect(true);
Log.warning(F("Attempting connection to new AP" CR));
WiFi.begin((const char*)SYSdata["wifi_ssid"], (const char*)SYSdata["wifi_pass"]);
WiFi.waitForConnectResult();
if (WiFi.status() != WL_CONNECTED) {
Log.error(F("Failed to connect to new AP; falling back" CR));
WiFi.disconnect(true);
WiFi.begin(prev_ssid.c_str(), prev_pass.c_str());
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
# if defined(ESP8266)
ESP.reset();
# else
ESP.restart();
# endif
}
}
# if defined(ZgatewayBT) && defined(ESP32)
startProcessing();
# endif
}
if (SYSdata.containsKey("mqtt_user") && SYSdata.containsKey("mqtt_pass")) {
# if defined(ZgatewayBT) && defined(ESP32)
stopProcessing();
# endif
client.disconnect();
bool update_server = false;
void* prev_client = nullptr;
if (SYSdata.containsKey("mqtt_server") && SYSdata.containsKey("mqtt_port")) {
if (!SYSdata.containsKey("mqtt_secure")) {
Log.warning(F("mqtt_server provided without mqtt_secure defined - ignoring command" CR));
return;
}
update_server = true;
if (SYSdata.get<bool>("mqtt_secure") != mqtt_secure) {
prev_client = eClient;
if (!mqtt_secure) {
eClient = new WiFiClientSecure;
setupTLS();
} else {
Log.warning(F("Switching to unsecure MQTT broker" CR));
eClient = new WiFiClient;
}
client.setClient(*(Client*)eClient);
}
client.setServer(SYSdata.get<const char*>("mqtt_server"), SYSdata.get<unsigned int>("mqtt_port"));
}
String prev_user = mqtt_user;
String prev_pass = mqtt_pass;
strcpy(mqtt_user, SYSdata["mqtt_user"]);
strcpy(mqtt_pass, SYSdata["mqtt_pass"]);
connectMQTT();
if (client.connected()) {
if (update_server) {
strcpy(mqtt_server, SYSdata["mqtt_server"]);
strcpy(mqtt_port, SYSdata["mqtt_port"]);
if (prev_client != nullptr) {
mqtt_secure = !mqtt_secure;
delete prev_client;
}
}
# ifndef ESPWifiManualSetup
saveMqttConfig();
# endif
} else {
if (update_server) {
if (prev_client != nullptr) {
delete eClient;
eClient = prev_client;
client.setClient(*(Client*)eClient);
}
uint16_t port = strtol(mqtt_port, NULL, 10);
client.setServer(mqtt_server, port);
}
strcpy(mqtt_user, prev_user.c_str());
strcpy(mqtt_pass, prev_pass.c_str());
connectMQTT();
}
# if defined(ZgatewayBT) && defined(ESP32)
startProcessing();
# endif
}
#endif
#ifdef ZmqttDiscovery
if (SYSdata.containsKey("discovery")) {
if (SYSdata.is<bool>("discovery")) {
@@ -1852,4 +1952,4 @@ String toString(uint32_t input) {
return result;
}
# endif
#endif
#endif