Feature: Allow custom MQTT Client ID
This commit is contained in:
parent
e4bbf55ea5
commit
ba95f99e03
@ -16,6 +16,7 @@
|
|||||||
#define NTP_MAX_TIMEZONEDESCR_STRLEN 50
|
#define NTP_MAX_TIMEZONEDESCR_STRLEN 50
|
||||||
|
|
||||||
#define MQTT_MAX_HOSTNAME_STRLEN 128
|
#define MQTT_MAX_HOSTNAME_STRLEN 128
|
||||||
|
#define MQTT_MAX_CLIENTID_STRLEN 64
|
||||||
#define MQTT_MAX_USERNAME_STRLEN 64
|
#define MQTT_MAX_USERNAME_STRLEN 64
|
||||||
#define MQTT_MAX_PASSWORD_STRLEN 64
|
#define MQTT_MAX_PASSWORD_STRLEN 64
|
||||||
#define MQTT_MAX_TOPIC_STRLEN 32
|
#define MQTT_MAX_TOPIC_STRLEN 32
|
||||||
@ -88,6 +89,7 @@ struct CONFIG_T {
|
|||||||
bool Enabled;
|
bool Enabled;
|
||||||
char Hostname[MQTT_MAX_HOSTNAME_STRLEN + 1];
|
char Hostname[MQTT_MAX_HOSTNAME_STRLEN + 1];
|
||||||
uint32_t Port;
|
uint32_t Port;
|
||||||
|
char ClientId[MQTT_MAX_CLIENTID_STRLEN + 1];
|
||||||
char Username[MQTT_MAX_USERNAME_STRLEN + 1];
|
char Username[MQTT_MAX_USERNAME_STRLEN + 1];
|
||||||
char Password[MQTT_MAX_PASSWORD_STRLEN + 1];
|
char Password[MQTT_MAX_PASSWORD_STRLEN + 1];
|
||||||
char Topic[MQTT_MAX_TOPIC_STRLEN + 1];
|
char Topic[MQTT_MAX_TOPIC_STRLEN + 1];
|
||||||
|
|||||||
@ -60,6 +60,7 @@ enum WebApiError {
|
|||||||
MqttHassTopicLength,
|
MqttHassTopicLength,
|
||||||
MqttHassTopicCharacter,
|
MqttHassTopicCharacter,
|
||||||
MqttLwtQos,
|
MqttLwtQos,
|
||||||
|
MqttClientIdLength,
|
||||||
|
|
||||||
NetworkBase = 8000,
|
NetworkBase = 8000,
|
||||||
NetworkIpInvalid,
|
NetworkIpInvalid,
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
#include "MessageOutput.h"
|
#include "MessageOutput.h"
|
||||||
|
#include "NetworkSettings.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
#include "defaults.h"
|
#include "defaults.h"
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
@ -58,6 +59,7 @@ bool ConfigurationClass::write()
|
|||||||
mqtt["enabled"] = config.Mqtt.Enabled;
|
mqtt["enabled"] = config.Mqtt.Enabled;
|
||||||
mqtt["hostname"] = config.Mqtt.Hostname;
|
mqtt["hostname"] = config.Mqtt.Hostname;
|
||||||
mqtt["port"] = config.Mqtt.Port;
|
mqtt["port"] = config.Mqtt.Port;
|
||||||
|
mqtt["clientid"] = config.Mqtt.ClientId;
|
||||||
mqtt["username"] = config.Mqtt.Username;
|
mqtt["username"] = config.Mqtt.Username;
|
||||||
mqtt["password"] = config.Mqtt.Password;
|
mqtt["password"] = config.Mqtt.Password;
|
||||||
mqtt["topic"] = config.Mqtt.Topic;
|
mqtt["topic"] = config.Mqtt.Topic;
|
||||||
@ -232,6 +234,7 @@ bool ConfigurationClass::read()
|
|||||||
config.Mqtt.Enabled = mqtt["enabled"] | MQTT_ENABLED;
|
config.Mqtt.Enabled = mqtt["enabled"] | MQTT_ENABLED;
|
||||||
strlcpy(config.Mqtt.Hostname, mqtt["hostname"] | MQTT_HOST, sizeof(config.Mqtt.Hostname));
|
strlcpy(config.Mqtt.Hostname, mqtt["hostname"] | MQTT_HOST, sizeof(config.Mqtt.Hostname));
|
||||||
config.Mqtt.Port = mqtt["port"] | MQTT_PORT;
|
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.Username, mqtt["username"] | MQTT_USER, sizeof(config.Mqtt.Username));
|
||||||
strlcpy(config.Mqtt.Password, mqtt["password"] | MQTT_PASSWORD, sizeof(config.Mqtt.Password));
|
strlcpy(config.Mqtt.Password, mqtt["password"] | MQTT_PASSWORD, sizeof(config.Mqtt.Password));
|
||||||
strlcpy(config.Mqtt.Topic, mqtt["topic"] | MQTT_TOPIC, sizeof(config.Mqtt.Topic));
|
strlcpy(config.Mqtt.Topic, mqtt["topic"] | MQTT_TOPIC, sizeof(config.Mqtt.Topic));
|
||||||
|
|||||||
@ -115,7 +115,7 @@ void MqttSettingsClass::performConnect()
|
|||||||
MessageOutput.println("Connecting to MQTT...");
|
MessageOutput.println("Connecting to MQTT...");
|
||||||
const CONFIG_T& config = Configuration.get();
|
const CONFIG_T& config = Configuration.get();
|
||||||
const String willTopic = getPrefix() + config.Mqtt.Lwt.Topic;
|
const String willTopic = getPrefix() + config.Mqtt.Lwt.Topic;
|
||||||
const String clientId = NetworkSettings.getApName();
|
const String clientId = config.Mqtt.ClientId;
|
||||||
if (config.Mqtt.Tls.Enabled) {
|
if (config.Mqtt.Tls.Enabled) {
|
||||||
static_cast<espMqttClientSecure*>(_mqttClient)->setCACert(config.Mqtt.Tls.RootCaCert);
|
static_cast<espMqttClientSecure*>(_mqttClient)->setCACert(config.Mqtt.Tls.RootCaCert);
|
||||||
static_cast<espMqttClientSecure*>(_mqttClient)->setServer(config.Mqtt.Hostname, config.Mqtt.Port);
|
static_cast<espMqttClientSecure*>(_mqttClient)->setServer(config.Mqtt.Hostname, config.Mqtt.Port);
|
||||||
|
|||||||
@ -34,6 +34,7 @@ void WebApiMqttClass::onMqttStatus(AsyncWebServerRequest* request)
|
|||||||
root["mqtt_enabled"] = config.Mqtt.Enabled;
|
root["mqtt_enabled"] = config.Mqtt.Enabled;
|
||||||
root["mqtt_hostname"] = config.Mqtt.Hostname;
|
root["mqtt_hostname"] = config.Mqtt.Hostname;
|
||||||
root["mqtt_port"] = config.Mqtt.Port;
|
root["mqtt_port"] = config.Mqtt.Port;
|
||||||
|
root["mqtt_clientid"] = config.Mqtt.ClientId;
|
||||||
root["mqtt_username"] = config.Mqtt.Username;
|
root["mqtt_username"] = config.Mqtt.Username;
|
||||||
root["mqtt_topic"] = config.Mqtt.Topic;
|
root["mqtt_topic"] = config.Mqtt.Topic;
|
||||||
root["mqtt_connected"] = MqttSettings.getConnected();
|
root["mqtt_connected"] = MqttSettings.getConnected();
|
||||||
@ -67,6 +68,7 @@ void WebApiMqttClass::onMqttAdminGet(AsyncWebServerRequest* request)
|
|||||||
root["mqtt_enabled"] = config.Mqtt.Enabled;
|
root["mqtt_enabled"] = config.Mqtt.Enabled;
|
||||||
root["mqtt_hostname"] = config.Mqtt.Hostname;
|
root["mqtt_hostname"] = config.Mqtt.Hostname;
|
||||||
root["mqtt_port"] = config.Mqtt.Port;
|
root["mqtt_port"] = config.Mqtt.Port;
|
||||||
|
root["mqtt_clientid"] = config.Mqtt.ClientId;
|
||||||
root["mqtt_username"] = config.Mqtt.Username;
|
root["mqtt_username"] = config.Mqtt.Username;
|
||||||
root["mqtt_password"] = config.Mqtt.Password;
|
root["mqtt_password"] = config.Mqtt.Password;
|
||||||
root["mqtt_topic"] = config.Mqtt.Topic;
|
root["mqtt_topic"] = config.Mqtt.Topic;
|
||||||
@ -108,6 +110,7 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request)
|
|||||||
if (!(root.containsKey("mqtt_enabled")
|
if (!(root.containsKey("mqtt_enabled")
|
||||||
&& root.containsKey("mqtt_hostname")
|
&& root.containsKey("mqtt_hostname")
|
||||||
&& root.containsKey("mqtt_port")
|
&& root.containsKey("mqtt_port")
|
||||||
|
&& root.containsKey("mqtt_clientid")
|
||||||
&& root.containsKey("mqtt_username")
|
&& root.containsKey("mqtt_username")
|
||||||
&& root.containsKey("mqtt_password")
|
&& root.containsKey("mqtt_password")
|
||||||
&& root.containsKey("mqtt_topic")
|
&& root.containsKey("mqtt_topic")
|
||||||
@ -142,6 +145,13 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request)
|
|||||||
return;
|
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) {
|
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["message"] = "Username must not be longer than " STR(MQTT_MAX_USERNAME_STRLEN) " characters!";
|
||||||
retMsg["code"] = WebApiError::MqttUsernameLength;
|
retMsg["code"] = WebApiError::MqttUsernameLength;
|
||||||
@ -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));
|
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>();
|
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.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.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.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));
|
strlcpy(config.Mqtt.Lwt.Topic, root["mqtt_lwt_topic"].as<String>().c_str(), sizeof(config.Mqtt.Lwt.Topic));
|
||||||
|
|||||||
@ -85,6 +85,7 @@
|
|||||||
"7014": "Hass-Topic darf nicht länger als {max} Zeichen sein!",
|
"7014": "Hass-Topic darf nicht länger als {max} Zeichen sein!",
|
||||||
"7015": "Hass-Topic darf keine Leerzeichen enthalten!",
|
"7015": "Hass-Topic darf keine Leerzeichen enthalten!",
|
||||||
"7016": "LWT QOS darf icht größer als {max} sein!",
|
"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!",
|
"8001": "IP-Adresse ist ungültig!",
|
||||||
"8002": "Netzmaske ist ungültig!",
|
"8002": "Netzmaske ist ungültig!",
|
||||||
"8003": "Standardgateway ist ungültig!",
|
"8003": "Standardgateway ist ungültig!",
|
||||||
@ -297,6 +298,7 @@
|
|||||||
"Disabled": "nicht aktiv",
|
"Disabled": "nicht aktiv",
|
||||||
"Server": "@:ntpinfo.Server",
|
"Server": "@:ntpinfo.Server",
|
||||||
"Port": "Port",
|
"Port": "Port",
|
||||||
|
"ClientId": "Client ID",
|
||||||
"Username": "Benutzername",
|
"Username": "Benutzername",
|
||||||
"BaseTopic": "Basis-Topic",
|
"BaseTopic": "Basis-Topic",
|
||||||
"PublishInterval": "Veröffentlichungsintervall",
|
"PublishInterval": "Veröffentlichungsintervall",
|
||||||
@ -441,6 +443,7 @@
|
|||||||
"Hostname": "Hostname:",
|
"Hostname": "Hostname:",
|
||||||
"HostnameHint": "Hostname oder IP-Adresse",
|
"HostnameHint": "Hostname oder IP-Adresse",
|
||||||
"Port": "Port:",
|
"Port": "Port:",
|
||||||
|
"ClientId": "Client ID:",
|
||||||
"Username": "Benutzername:",
|
"Username": "Benutzername:",
|
||||||
"UsernameHint": "Benutzername, leer lassen für anonyme Verbindung",
|
"UsernameHint": "Benutzername, leer lassen für anonyme Verbindung",
|
||||||
"Password": "Passwort:",
|
"Password": "Passwort:",
|
||||||
|
|||||||
@ -85,6 +85,7 @@
|
|||||||
"7014": "Hass topic must not longer then {max} characters!",
|
"7014": "Hass topic must not longer then {max} characters!",
|
||||||
"7015": "Hass topic must not contain space characters!",
|
"7015": "Hass topic must not contain space characters!",
|
||||||
"7016": "LWT QOS must not greater then {max}!",
|
"7016": "LWT QOS must not greater then {max}!",
|
||||||
|
"7017": "Client ID must not longer then {max} characters!",
|
||||||
"8001": "IP address is invalid!",
|
"8001": "IP address is invalid!",
|
||||||
"8002": "Netmask is invalid!",
|
"8002": "Netmask is invalid!",
|
||||||
"8003": "Gateway is invalid!",
|
"8003": "Gateway is invalid!",
|
||||||
@ -297,6 +298,7 @@
|
|||||||
"Disabled": "Disabled",
|
"Disabled": "Disabled",
|
||||||
"Server": "@:ntpinfo.Server",
|
"Server": "@:ntpinfo.Server",
|
||||||
"Port": "Port",
|
"Port": "Port",
|
||||||
|
"ClientId": "Client ID",
|
||||||
"Username": "Username",
|
"Username": "Username",
|
||||||
"BaseTopic": "Base Topic",
|
"BaseTopic": "Base Topic",
|
||||||
"PublishInterval": "Publish Interval",
|
"PublishInterval": "Publish Interval",
|
||||||
@ -441,6 +443,7 @@
|
|||||||
"Hostname": "Hostname:",
|
"Hostname": "Hostname:",
|
||||||
"HostnameHint": "Hostname or IP address",
|
"HostnameHint": "Hostname or IP address",
|
||||||
"Port": "Port:",
|
"Port": "Port:",
|
||||||
|
"ClientId": "Client ID:",
|
||||||
"Username": "Username:",
|
"Username": "Username:",
|
||||||
"UsernameHint": "Username, leave empty for anonymous connection",
|
"UsernameHint": "Username, leave empty for anonymous connection",
|
||||||
"Password": "Password:",
|
"Password": "Password:",
|
||||||
|
|||||||
@ -85,6 +85,7 @@
|
|||||||
"7014": "Le sujet Hass ne doit pas dépasser {max} caractères !",
|
"7014": "Le sujet Hass ne doit pas dépasser {max} caractères !",
|
||||||
"7015": "Le sujet Hass ne doit pas contenir d'espace !",
|
"7015": "Le sujet Hass ne doit pas contenir d'espace !",
|
||||||
"7016": "LWT QOS ne doit pas être supérieur à {max}!",
|
"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 !",
|
"8001": "L'adresse IP n'est pas valide !",
|
||||||
"8002": "Le masque de réseau n'est pas valide !",
|
"8002": "Le masque de réseau n'est pas valide !",
|
||||||
"8003": "La passerelle n'est pas valide !",
|
"8003": "La passerelle n'est pas valide !",
|
||||||
@ -297,6 +298,7 @@
|
|||||||
"Disabled": "Désactivé",
|
"Disabled": "Désactivé",
|
||||||
"Server": "@:ntpinfo.Server",
|
"Server": "@:ntpinfo.Server",
|
||||||
"Port": "Port",
|
"Port": "Port",
|
||||||
|
"ClientId": "Client ID",
|
||||||
"Username": "Nom d'utilisateur",
|
"Username": "Nom d'utilisateur",
|
||||||
"BaseTopic": "Sujet de base",
|
"BaseTopic": "Sujet de base",
|
||||||
"PublishInterval": "Intervalle de publication",
|
"PublishInterval": "Intervalle de publication",
|
||||||
@ -441,6 +443,7 @@
|
|||||||
"Hostname": "Nom d'hôte",
|
"Hostname": "Nom d'hôte",
|
||||||
"HostnameHint": "Nom d'hôte ou adresse IP",
|
"HostnameHint": "Nom d'hôte ou adresse IP",
|
||||||
"Port": "Port",
|
"Port": "Port",
|
||||||
|
"ClientId": "Client ID:",
|
||||||
"Username": "Nom d'utilisateur",
|
"Username": "Nom d'utilisateur",
|
||||||
"UsernameHint": "Nom d'utilisateur, laisser vide pour une connexion anonyme",
|
"UsernameHint": "Nom d'utilisateur, laisser vide pour une connexion anonyme",
|
||||||
"Password": "Mot de passe:",
|
"Password": "Mot de passe:",
|
||||||
|
|||||||
@ -2,6 +2,7 @@ export interface MqttConfig {
|
|||||||
mqtt_enabled: boolean;
|
mqtt_enabled: boolean;
|
||||||
mqtt_hostname: string;
|
mqtt_hostname: string;
|
||||||
mqtt_port: number;
|
mqtt_port: number;
|
||||||
|
mqtt_clientid: string;
|
||||||
mqtt_username: string;
|
mqtt_username: string;
|
||||||
mqtt_password: string;
|
mqtt_password: string;
|
||||||
mqtt_topic: string;
|
mqtt_topic: string;
|
||||||
@ -22,4 +23,4 @@ export interface MqttConfig {
|
|||||||
mqtt_hass_retain: boolean;
|
mqtt_hass_retain: boolean;
|
||||||
mqtt_hass_topic: string;
|
mqtt_hass_topic: string;
|
||||||
mqtt_hass_individualpanels: boolean;
|
mqtt_hass_individualpanels: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@ export interface MqttStatus {
|
|||||||
mqtt_enabled: boolean;
|
mqtt_enabled: boolean;
|
||||||
mqtt_hostname: string;
|
mqtt_hostname: string;
|
||||||
mqtt_port: number;
|
mqtt_port: number;
|
||||||
|
mqtt_clientid: string;
|
||||||
mqtt_username: string;
|
mqtt_username: string;
|
||||||
mqtt_topic: string;
|
mqtt_topic: string;
|
||||||
mqtt_publish_interval: number;
|
mqtt_publish_interval: number;
|
||||||
@ -17,4 +18,4 @@ export interface MqttStatus {
|
|||||||
mqtt_hass_retain: boolean;
|
mqtt_hass_retain: boolean;
|
||||||
mqtt_hass_topic: string;
|
mqtt_hass_topic: string;
|
||||||
mqtt_hass_individualpanels: boolean;
|
mqtt_hass_individualpanels: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,6 +28,10 @@
|
|||||||
v-model="mqttConfigList.mqtt_port"
|
v-model="mqttConfigList.mqtt_port"
|
||||||
type="number" min="1" max="65535"/>
|
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')"
|
<InputElement :label="$t('mqttadmin.Username')"
|
||||||
v-model="mqttConfigList.mqtt_username"
|
v-model="mqttConfigList.mqtt_username"
|
||||||
type="text" maxlength="64"
|
type="text" maxlength="64"
|
||||||
|
|||||||
@ -18,6 +18,10 @@
|
|||||||
<th>{{ $t('mqttinfo.Port') }}</th>
|
<th>{{ $t('mqttinfo.Port') }}</th>
|
||||||
<td>{{ mqttDataList.mqtt_port }}</td>
|
<td>{{ mqttDataList.mqtt_port }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>{{ $t('mqttinfo.ClientId') }}</th>
|
||||||
|
<td>{{ mqttDataList.mqtt_clientid }}</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{ $t('mqttinfo.Username') }}</th>
|
<th>{{ $t('mqttinfo.Username') }}</th>
|
||||||
<td>{{ mqttDataList.mqtt_username }}</td>
|
<td>{{ mqttDataList.mqtt_username }}</td>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user