Skip to content

Commit

Permalink
Feature: Allow custom MQTT Client ID
Browse files Browse the repository at this point in the history
  • Loading branch information
tbnobody committed Jun 28, 2024
1 parent e4bbf55 commit ba95f99
Show file tree
Hide file tree
Showing 12 changed files with 39 additions and 3 deletions.
2 changes: 2 additions & 0 deletions include/Configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#define NTP_MAX_TIMEZONEDESCR_STRLEN 50

#define MQTT_MAX_HOSTNAME_STRLEN 128
#define MQTT_MAX_CLIENTID_STRLEN 64
#define MQTT_MAX_USERNAME_STRLEN 64
#define MQTT_MAX_PASSWORD_STRLEN 64
#define MQTT_MAX_TOPIC_STRLEN 32
Expand Down Expand Up @@ -88,6 +89,7 @@ struct CONFIG_T {
bool Enabled;
char Hostname[MQTT_MAX_HOSTNAME_STRLEN + 1];
uint32_t Port;
char ClientId[MQTT_MAX_CLIENTID_STRLEN + 1];
char Username[MQTT_MAX_USERNAME_STRLEN + 1];
char Password[MQTT_MAX_PASSWORD_STRLEN + 1];
char Topic[MQTT_MAX_TOPIC_STRLEN + 1];
Expand Down
1 change: 1 addition & 0 deletions include/WebApi_errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ enum WebApiError {
MqttHassTopicLength,
MqttHassTopicCharacter,
MqttLwtQos,
MqttClientIdLength,

NetworkBase = 8000,
NetworkIpInvalid,
Expand Down
3 changes: 3 additions & 0 deletions src/Configuration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/
#include "Configuration.h"
#include "MessageOutput.h"
#include "NetworkSettings.h"
#include "Utils.h"
#include "defaults.h"
#include <ArduinoJson.h>
Expand Down Expand Up @@ -58,6 +59,7 @@ bool ConfigurationClass::write()
mqtt["enabled"] = config.Mqtt.Enabled;
mqtt["hostname"] = config.Mqtt.Hostname;
mqtt["port"] = config.Mqtt.Port;
mqtt["clientid"] = config.Mqtt.ClientId;
mqtt["username"] = config.Mqtt.Username;
mqtt["password"] = config.Mqtt.Password;
mqtt["topic"] = config.Mqtt.Topic;
Expand Down Expand Up @@ -232,6 +234,7 @@ bool ConfigurationClass::read()
config.Mqtt.Enabled = mqtt["enabled"] | MQTT_ENABLED;
strlcpy(config.Mqtt.Hostname, mqtt["hostname"] | MQTT_HOST, sizeof(config.Mqtt.Hostname));
config.Mqtt.Port = mqtt["port"] | MQTT_PORT;
strlcpy(config.Mqtt.ClientId, mqtt["clientid"] | NetworkSettings.getApName().c_str(), sizeof(config.Mqtt.ClientId));
strlcpy(config.Mqtt.Username, mqtt["username"] | MQTT_USER, sizeof(config.Mqtt.Username));
strlcpy(config.Mqtt.Password, mqtt["password"] | MQTT_PASSWORD, sizeof(config.Mqtt.Password));
strlcpy(config.Mqtt.Topic, mqtt["topic"] | MQTT_TOPIC, sizeof(config.Mqtt.Topic));
Expand Down
2 changes: 1 addition & 1 deletion src/MqttSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ void MqttSettingsClass::performConnect()
MessageOutput.println("Connecting to MQTT...");
const CONFIG_T& config = Configuration.get();
const String willTopic = getPrefix() + config.Mqtt.Lwt.Topic;
const String clientId = NetworkSettings.getApName();
const String clientId = config.Mqtt.ClientId;
if (config.Mqtt.Tls.Enabled) {
static_cast<espMqttClientSecure*>(_mqttClient)->setCACert(config.Mqtt.Tls.RootCaCert);
static_cast<espMqttClientSecure*>(_mqttClient)->setServer(config.Mqtt.Hostname, config.Mqtt.Port);
Expand Down
11 changes: 11 additions & 0 deletions src/WebApi_mqtt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ void WebApiMqttClass::onMqttStatus(AsyncWebServerRequest* request)
root["mqtt_enabled"] = config.Mqtt.Enabled;
root["mqtt_hostname"] = config.Mqtt.Hostname;
root["mqtt_port"] = config.Mqtt.Port;
root["mqtt_clientid"] = config.Mqtt.ClientId;
root["mqtt_username"] = config.Mqtt.Username;
root["mqtt_topic"] = config.Mqtt.Topic;
root["mqtt_connected"] = MqttSettings.getConnected();
Expand Down Expand Up @@ -67,6 +68,7 @@ void WebApiMqttClass::onMqttAdminGet(AsyncWebServerRequest* request)
root["mqtt_enabled"] = config.Mqtt.Enabled;
root["mqtt_hostname"] = config.Mqtt.Hostname;
root["mqtt_port"] = config.Mqtt.Port;
root["mqtt_clientid"] = config.Mqtt.ClientId;
root["mqtt_username"] = config.Mqtt.Username;
root["mqtt_password"] = config.Mqtt.Password;
root["mqtt_topic"] = config.Mqtt.Topic;
Expand Down Expand Up @@ -108,6 +110,7 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request)
if (!(root.containsKey("mqtt_enabled")
&& root.containsKey("mqtt_hostname")
&& root.containsKey("mqtt_port")
&& root.containsKey("mqtt_clientid")
&& root.containsKey("mqtt_username")
&& root.containsKey("mqtt_password")
&& root.containsKey("mqtt_topic")
Expand Down Expand Up @@ -142,6 +145,13 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request)
return;
}

if (root["mqtt_clientid"].as<String>().length() > MQTT_MAX_CLIENTID_STRLEN) {
retMsg["message"] = "Client ID must not be longer than " STR(MQTT_MAX_CLIENTID_STRLEN) " characters!";
retMsg["code"] = WebApiError::MqttClientIdLength;
retMsg["param"]["max"] = MQTT_MAX_CLIENTID_STRLEN;
WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__);
return;
}
if (root["mqtt_username"].as<String>().length() > MQTT_MAX_USERNAME_STRLEN) {
retMsg["message"] = "Username must not be longer than " STR(MQTT_MAX_USERNAME_STRLEN) " characters!";
retMsg["code"] = WebApiError::MqttUsernameLength;
Expand Down Expand Up @@ -271,6 +281,7 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request)
strlcpy(config.Mqtt.Tls.ClientKey, root["mqtt_client_key"].as<String>().c_str(), sizeof(config.Mqtt.Tls.ClientKey));
config.Mqtt.Port = root["mqtt_port"].as<uint>();
strlcpy(config.Mqtt.Hostname, root["mqtt_hostname"].as<String>().c_str(), sizeof(config.Mqtt.Hostname));
strlcpy(config.Mqtt.ClientId, root["mqtt_clientid"].as<String>().c_str(), sizeof(config.Mqtt.ClientId));
strlcpy(config.Mqtt.Username, root["mqtt_username"].as<String>().c_str(), sizeof(config.Mqtt.Username));
strlcpy(config.Mqtt.Password, root["mqtt_password"].as<String>().c_str(), sizeof(config.Mqtt.Password));
strlcpy(config.Mqtt.Lwt.Topic, root["mqtt_lwt_topic"].as<String>().c_str(), sizeof(config.Mqtt.Lwt.Topic));
Expand Down
3 changes: 3 additions & 0 deletions webapp/src/locales/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
"7014": "Hass-Topic darf nicht länger als {max} Zeichen sein!",
"7015": "Hass-Topic darf keine Leerzeichen enthalten!",
"7016": "LWT QOS darf icht größer als {max} sein!",
"7017": "Client ID darf nicht länger als {max} Zeichen sein!",
"8001": "IP-Adresse ist ungültig!",
"8002": "Netzmaske ist ungültig!",
"8003": "Standardgateway ist ungültig!",
Expand Down Expand Up @@ -297,6 +298,7 @@
"Disabled": "nicht aktiv",
"Server": "@:ntpinfo.Server",
"Port": "Port",
"ClientId": "Client ID",
"Username": "Benutzername",
"BaseTopic": "Basis-Topic",
"PublishInterval": "Veröffentlichungsintervall",
Expand Down Expand Up @@ -441,6 +443,7 @@
"Hostname": "Hostname:",
"HostnameHint": "Hostname oder IP-Adresse",
"Port": "Port:",
"ClientId": "Client ID:",
"Username": "Benutzername:",
"UsernameHint": "Benutzername, leer lassen für anonyme Verbindung",
"Password": "Passwort:",
Expand Down
3 changes: 3 additions & 0 deletions webapp/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
"7014": "Hass topic must not longer then {max} characters!",
"7015": "Hass topic must not contain space characters!",
"7016": "LWT QOS must not greater then {max}!",
"7017": "Client ID must not longer then {max} characters!",
"8001": "IP address is invalid!",
"8002": "Netmask is invalid!",
"8003": "Gateway is invalid!",
Expand Down Expand Up @@ -297,6 +298,7 @@
"Disabled": "Disabled",
"Server": "@:ntpinfo.Server",
"Port": "Port",
"ClientId": "Client ID",
"Username": "Username",
"BaseTopic": "Base Topic",
"PublishInterval": "Publish Interval",
Expand Down Expand Up @@ -441,6 +443,7 @@
"Hostname": "Hostname:",
"HostnameHint": "Hostname or IP address",
"Port": "Port:",
"ClientId": "Client ID:",
"Username": "Username:",
"UsernameHint": "Username, leave empty for anonymous connection",
"Password": "Password:",
Expand Down
3 changes: 3 additions & 0 deletions webapp/src/locales/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
"7014": "Le sujet Hass ne doit pas dépasser {max} caractères !",
"7015": "Le sujet Hass ne doit pas contenir d'espace !",
"7016": "LWT QOS ne doit pas être supérieur à {max}!",
"7017": "Client ID must not longer then {max} characters!",
"8001": "L'adresse IP n'est pas valide !",
"8002": "Le masque de réseau n'est pas valide !",
"8003": "La passerelle n'est pas valide !",
Expand Down Expand Up @@ -297,6 +298,7 @@
"Disabled": "Désactivé",
"Server": "@:ntpinfo.Server",
"Port": "Port",
"ClientId": "Client ID",
"Username": "Nom d'utilisateur",
"BaseTopic": "Sujet de base",
"PublishInterval": "Intervalle de publication",
Expand Down Expand Up @@ -441,6 +443,7 @@
"Hostname": "Nom d'hôte",
"HostnameHint": "Nom d'hôte ou adresse IP",
"Port": "Port",
"ClientId": "Client ID:",
"Username": "Nom d'utilisateur",
"UsernameHint": "Nom d'utilisateur, laisser vide pour une connexion anonyme",
"Password": "Mot de passe:",
Expand Down
3 changes: 2 additions & 1 deletion webapp/src/types/MqttConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export interface MqttConfig {
mqtt_enabled: boolean;
mqtt_hostname: string;
mqtt_port: number;
mqtt_clientid: string;
mqtt_username: string;
mqtt_password: string;
mqtt_topic: string;
Expand All @@ -22,4 +23,4 @@ export interface MqttConfig {
mqtt_hass_retain: boolean;
mqtt_hass_topic: string;
mqtt_hass_individualpanels: boolean;
}
}
3 changes: 2 additions & 1 deletion webapp/src/types/MqttStatus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export interface MqttStatus {
mqtt_enabled: boolean;
mqtt_hostname: string;
mqtt_port: number;
mqtt_clientid: string;
mqtt_username: string;
mqtt_topic: string;
mqtt_publish_interval: number;
Expand All @@ -17,4 +18,4 @@ export interface MqttStatus {
mqtt_hass_retain: boolean;
mqtt_hass_topic: string;
mqtt_hass_individualpanels: boolean;
}
}
4 changes: 4 additions & 0 deletions webapp/src/views/MqttAdminView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@
v-model="mqttConfigList.mqtt_port"
type="number" min="1" max="65535"/>

<InputElement :label="$t('mqttadmin.ClientId')"
v-model="mqttConfigList.mqtt_clientid"
type="text" maxlength="64"/>

<InputElement :label="$t('mqttadmin.Username')"
v-model="mqttConfigList.mqtt_username"
type="text" maxlength="64"
Expand Down
4 changes: 4 additions & 0 deletions webapp/src/views/MqttInfoView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
<th>{{ $t('mqttinfo.Port') }}</th>
<td>{{ mqttDataList.mqtt_port }}</td>
</tr>
<tr>
<th>{{ $t('mqttinfo.ClientId') }}</th>
<td>{{ mqttDataList.mqtt_clientid }}</td>
</tr>
<tr>
<th>{{ $t('mqttinfo.Username') }}</th>
<td>{{ mqttDataList.mqtt_username }}</td>
Expand Down

0 comments on commit ba95f99

Please sign in to comment.