Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Wifi and mqtt broker configuration over MQTT commands. #971

Merged
merged 1 commit into from
Jun 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions docs/use/gateway.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
162 changes: 131 additions & 31 deletions main/main.ino
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand All @@ -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"];
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
Expand All @@ -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)) {
Expand All @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -623,8 +622,6 @@ void setup() {
client.setServer(mqtt_server, port);
#endif

setup_parameters();

client.setCallback(callback);

delay(1500);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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")) {
Expand Down Expand Up @@ -1852,4 +1952,4 @@ String toString(uint32_t input) {
return result;
}
# endif
#endif
#endif