mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 08:19:52 +03:00
added MQTT QOS and Keep Alive configurable
This commit is contained in:
@@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Retrieve/display mode for Junkers FW100/120 thermostats (thanks @Neonox31)
|
||||
- Added sending of Mixer Module data via MQTT (thanks @peclik)
|
||||
- Reporting of MQTT publish and subscribe errors
|
||||
- Added MQTT QOS (default 1) and Keep Alive (default 60 seconds) as parameters to both telnet and WebUI
|
||||
|
||||
### Fixed
|
||||
|
||||
|
||||
@@ -677,8 +677,10 @@ void MyESP::_printSetCommands() {
|
||||
myDebug_P(PSTR(" set mqtt_enabled <on | off>"));
|
||||
myDebug_P(PSTR(" set <mqtt_ip | mqtt_username | mqtt_password> [value]"));
|
||||
myDebug_P(PSTR(" set mqtt_heartbeat <on | off>"));
|
||||
myDebug_P(PSTR(" set mqtt_base [value]"));
|
||||
myDebug_P(PSTR(" set mqtt_port [value]"));
|
||||
myDebug_P(PSTR(" set mqtt_base [string]"));
|
||||
myDebug_P(PSTR(" set mqtt_port [number]"));
|
||||
myDebug_P(PSTR(" set mqtt_qos [0,1,2,3]"));
|
||||
myDebug_P(PSTR(" set mqtt_keepalive [seconds]"));
|
||||
myDebug_P(PSTR(" set ntp_enabled <on | off>"));
|
||||
myDebug_P(PSTR(" set serial <on | off>"));
|
||||
myDebug_P(PSTR(" set log_events <on | off>"));
|
||||
@@ -732,6 +734,8 @@ void MyESP::_printSetCommands() {
|
||||
myDebug_P(PSTR(" mqtt_base="));
|
||||
}
|
||||
myDebug_P(PSTR(" mqtt_port=%d"), _mqtt_port);
|
||||
myDebug_P(PSTR(" mqtt_keepalive=%d"), _mqtt_keepalive);
|
||||
myDebug_P(PSTR(" mqtt_qos=%d"), _mqtt_qos);
|
||||
myDebug_P(PSTR(" mqtt_heartbeat=%s"), (_mqtt_heartbeat) ? "on" : "off");
|
||||
|
||||
#ifdef FORCE_SERIAL
|
||||
@@ -815,6 +819,10 @@ bool MyESP::_changeSetting(uint8_t wc, const char * setting, const char * value)
|
||||
save_config = fs_setSettingValue(&_mqtt_base, value, MQTT_BASE_DEFAULT);
|
||||
} else if (strcmp(setting, "mqtt_port") == 0) {
|
||||
save_config = fs_setSettingValue(&_mqtt_port, value, MQTT_PORT);
|
||||
} else if (strcmp(setting, "mqtt_keepalive") == 0) {
|
||||
save_config = fs_setSettingValue(&_mqtt_keepalive, value, MQTT_KEEPALIVE);
|
||||
} else if (strcmp(setting, "mqtt_qos") == 0) {
|
||||
save_config = fs_setSettingValue(&_mqtt_qos, value, MQTT_QOS);
|
||||
} else if (strcmp(setting, "mqtt_enabled") == 0) {
|
||||
save_config = fs_setSettingValue(&_mqtt_enabled, value, false);
|
||||
} else if (strcmp(setting, "serial") == 0) {
|
||||
@@ -1690,6 +1698,8 @@ bool MyESP::_fs_loadConfig() {
|
||||
_mqtt_ip = strdup(mqtt["ip"] | "");
|
||||
_mqtt_user = strdup(mqtt["user"] | "");
|
||||
_mqtt_port = mqtt["port"] | MQTT_PORT;
|
||||
_mqtt_keepalive = mqtt["keepalive"] | MQTT_KEEPALIVE;
|
||||
_mqtt_qos = mqtt["qos"] | MQTT_QOS;
|
||||
_mqtt_password = strdup(mqtt["password"] | "");
|
||||
_mqtt_base = strdup(mqtt["base"] | MQTT_BASE_DEFAULT);
|
||||
|
||||
@@ -1721,7 +1731,7 @@ bool MyESP::fs_setSettingValue(char ** setting, const char * value, const char *
|
||||
return true;
|
||||
}
|
||||
|
||||
// saves a integer into a config setting, using default value if non set
|
||||
// saves a 2-byte short integer into a config setting, using default value if non set
|
||||
// returns true if successful
|
||||
bool MyESP::fs_setSettingValue(uint16_t * setting, const char * value, uint16_t value_default) {
|
||||
if (_hasValue(value)) {
|
||||
@@ -1733,6 +1743,18 @@ bool MyESP::fs_setSettingValue(uint16_t * setting, const char * value, uint16_t
|
||||
return true;
|
||||
}
|
||||
|
||||
// saves an 8-bit integer into a config setting, using default value if non set
|
||||
// returns true if successful
|
||||
bool MyESP::fs_setSettingValue(uint8_t * setting, const char * value, uint8_t value_default) {
|
||||
if (_hasValue(value)) {
|
||||
*setting = (uint8_t)atoi(value);
|
||||
} else {
|
||||
*setting = value_default; // use the default value
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// saves a bool into a config setting, using default value if non set
|
||||
// returns true if successful
|
||||
bool MyESP::fs_setSettingValue(bool * setting, const char * value, bool value_default) {
|
||||
@@ -1879,8 +1901,11 @@ bool MyESP::_fs_writeConfig() {
|
||||
mqtt["ip"] = _mqtt_ip;
|
||||
mqtt["user"] = _mqtt_user;
|
||||
mqtt["port"] = _mqtt_port;
|
||||
mqtt["password"] = _mqtt_password;
|
||||
mqtt["base"] = _mqtt_base;
|
||||
mqtt["qos"] = _mqtt_qos;
|
||||
mqtt["keepalive"] = _mqtt_keepalive;
|
||||
|
||||
mqtt["password"] = _mqtt_password;
|
||||
mqtt["base"] = _mqtt_base;
|
||||
|
||||
JsonObject ntp = doc.createNestedObject("ntp");
|
||||
ntp["server"] = _ntp_server;
|
||||
|
||||
@@ -80,8 +80,8 @@ extern struct rst_info resetInfo;
|
||||
#define MQTT_WILL_OFFLINE_PAYLOAD "offline" // for last will & testament payload
|
||||
#define MQTT_BASE_DEFAULT "home" // default MQTT prefix to topics
|
||||
#define MQTT_RETAIN false
|
||||
#define MQTT_KEEPALIVE 60 // 1 minute
|
||||
#define MQTT_QOS 1
|
||||
#define MQTT_KEEPALIVE 60 // default keepalive 1 minute
|
||||
#define MQTT_QOS 1 // default qos
|
||||
#define MQTT_WILL_TOPIC "status" // for last will & testament topic name
|
||||
#define MQTT_MAX_TOPIC_SIZE 50 // max length of MQTT topic
|
||||
#define MQTT_MAX_PAYLOAD_SIZE 700 // max size of a JSON object. See https://arduinojson.org/v6/assistant/
|
||||
@@ -293,6 +293,7 @@ class MyESP {
|
||||
bool fs_saveCustomConfig(JsonObject root);
|
||||
bool fs_setSettingValue(char ** setting, const char * value, const char * value_default);
|
||||
bool fs_setSettingValue(uint16_t * setting, const char * value, uint16_t value_default);
|
||||
bool fs_setSettingValue(uint8_t * setting, const char * value, uint8_t value_default);
|
||||
bool fs_setSettingValue(bool * setting, const char * value, bool value_default);
|
||||
|
||||
// Web
|
||||
@@ -340,7 +341,7 @@ class MyESP {
|
||||
uint16_t _mqtt_port;
|
||||
char * _mqtt_base;
|
||||
bool _mqtt_enabled;
|
||||
uint32_t _mqtt_keepalive;
|
||||
uint16_t _mqtt_keepalive;
|
||||
uint8_t _mqtt_qos;
|
||||
bool _mqtt_retain;
|
||||
char * _mqtt_will_topic;
|
||||
|
||||
@@ -873,39 +873,6 @@ void publishValues(bool force) {
|
||||
}
|
||||
}
|
||||
|
||||
// used to read the next string from an input buffer and convert to an 8 bit int
|
||||
uint8_t _readIntNumber() {
|
||||
char * numTextPtr = strtok(nullptr, ", \n");
|
||||
if (numTextPtr == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
return atoi(numTextPtr);
|
||||
}
|
||||
|
||||
// used to read the next string from an input buffer and convert to a double
|
||||
float _readFloatNumber() {
|
||||
char * numTextPtr = strtok(nullptr, ", \n");
|
||||
if (numTextPtr == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
return atof(numTextPtr);
|
||||
}
|
||||
|
||||
// used to read the next string from an input buffer as a hex value and convert to a 16 bit int
|
||||
uint16_t _readHexNumber() {
|
||||
char * numTextPtr = strtok(nullptr, ", \n");
|
||||
if (numTextPtr == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
return (uint16_t)strtol(numTextPtr, 0, 16);
|
||||
}
|
||||
|
||||
// used to read the next string from an input buffer
|
||||
char * _readWord() {
|
||||
char * word = strtok(nullptr, ", \n");
|
||||
return word;
|
||||
}
|
||||
|
||||
// publish external dallas sensor temperature values to MQTT
|
||||
void do_publishSensorValues() {
|
||||
if ((EMSESP_Settings.dallas_sensors) && (EMSESP_Settings.publish_time)) {
|
||||
|
||||
@@ -260,3 +260,36 @@ char * _smallitoa3(uint16_t value, char * buffer) {
|
||||
buffer[3] = '\0';
|
||||
return buffer;
|
||||
}
|
||||
|
||||
// used to read the next string from an input buffer and convert to an 8 bit int
|
||||
uint8_t _readIntNumber() {
|
||||
char * numTextPtr = strtok(nullptr, ", \n");
|
||||
if (numTextPtr == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
return atoi(numTextPtr);
|
||||
}
|
||||
|
||||
// used to read the next string from an input buffer and convert to a double
|
||||
float _readFloatNumber() {
|
||||
char * numTextPtr = strtok(nullptr, ", \n");
|
||||
if (numTextPtr == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
return atof(numTextPtr);
|
||||
}
|
||||
|
||||
// used to read the next string from an input buffer as a hex value and convert to a 16 bit int
|
||||
uint16_t _readHexNumber() {
|
||||
char * numTextPtr = strtok(nullptr, ", \n");
|
||||
if (numTextPtr == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
return (uint16_t)strtol(numTextPtr, 0, 16);
|
||||
}
|
||||
|
||||
// used to read the next string from an input buffer
|
||||
char * _readWord() {
|
||||
char * word = strtok(nullptr, ", \n");
|
||||
return word;
|
||||
}
|
||||
|
||||
@@ -14,16 +14,20 @@
|
||||
#define myDebug(...) myESP.myDebug(__VA_ARGS__)
|
||||
#define myDebug_P(...) myESP.myDebug_P(__VA_ARGS__)
|
||||
|
||||
char * _float_to_char(char * a, float f, uint8_t precision = 2);
|
||||
char * _bool_to_char(char * s, uint8_t value);
|
||||
char * _short_to_char(char * s, int16_t value, uint8_t decimals = 1);
|
||||
char * _ushort_to_char(char * s, uint16_t value, uint8_t decimals = 1);
|
||||
void _renderShortValue(const char * prefix, const char * postfix, int16_t value, uint8_t decimals = 1);
|
||||
void _renderUShortValue(const char * prefix, const char * postfix, uint16_t value, uint8_t decimals = 1);
|
||||
char * _int_to_char(char * s, uint8_t value, uint8_t div = 1);
|
||||
void _renderIntValue(const char * prefix, const char * postfix, uint8_t value, uint8_t div = 1);
|
||||
void _renderLongValue(const char * prefix, const char * postfix, uint32_t value);
|
||||
void _renderBoolValue(const char * prefix, uint8_t value);
|
||||
char * _hextoa(uint8_t value, char * buffer);
|
||||
char * _smallitoa(uint8_t value, char * buffer);
|
||||
char * _smallitoa3(uint16_t value, char * buffer);
|
||||
char * _float_to_char(char * a, float f, uint8_t precision = 2);
|
||||
char * _bool_to_char(char * s, uint8_t value);
|
||||
char * _short_to_char(char * s, int16_t value, uint8_t decimals = 1);
|
||||
char * _ushort_to_char(char * s, uint16_t value, uint8_t decimals = 1);
|
||||
void _renderShortValue(const char * prefix, const char * postfix, int16_t value, uint8_t decimals = 1);
|
||||
void _renderUShortValue(const char * prefix, const char * postfix, uint16_t value, uint8_t decimals = 1);
|
||||
char * _int_to_char(char * s, uint8_t value, uint8_t div = 1);
|
||||
void _renderIntValue(const char * prefix, const char * postfix, uint8_t value, uint8_t div = 1);
|
||||
void _renderLongValue(const char * prefix, const char * postfix, uint32_t value);
|
||||
void _renderBoolValue(const char * prefix, uint8_t value);
|
||||
char * _hextoa(uint8_t value, char * buffer);
|
||||
char * _smallitoa(uint8_t value, char * buffer);
|
||||
char * _smallitoa3(uint16_t value, char * buffer);
|
||||
uint8_t _readIntNumber();
|
||||
float _readFloatNumber();
|
||||
uint16_t _readHexNumber();
|
||||
char * _readWord();
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define APP_VERSION "1.9.2b7"
|
||||
#define APP_VERSION "1.9.2b8"
|
||||
|
||||
@@ -191,7 +191,7 @@
|
||||
data-toggle="popover" data-trigger="hover" data-placement="right"
|
||||
data-content="MQTT Server IP Address"></i></label>
|
||||
<span class="col-xs-9">
|
||||
<input class="form-control input-sm" placeholder="MQTT IP" style="display:inline;max-width:185px"
|
||||
<input class="form-control input-sm" placeholder="IP address" style="display:inline;max-width:185px"
|
||||
id="mqttip" type="text">
|
||||
</span>
|
||||
<br>
|
||||
@@ -201,11 +201,31 @@
|
||||
aria-hidden="true" data-toggle="popover" data-trigger="hover" data-placement="right"
|
||||
data-content="MQTT Server port number"></i></label>
|
||||
<span class="col-xs-9">
|
||||
<input class="form-control input-sm" placeholder="MQTT Port" value="" style="display:inline;max-width:185px"
|
||||
<input class="form-control input-sm" placeholder="1883" value="" style="display:inline;max-width:185px"
|
||||
id="mqttport" type="text">
|
||||
</span>
|
||||
<br>
|
||||
</div>
|
||||
<div class="row form-group">
|
||||
<label class="col-xs-3">QOS<i style="margin-left: 10px;" class="glyphicon glyphicon-info-sign"
|
||||
aria-hidden="true" data-toggle="popover" data-trigger="hover" data-placement="right"
|
||||
data-content="MQTT QOS"></i></label>
|
||||
<span class="col-xs-9">
|
||||
<input class="form-control input-sm" placeholder="1" value="" style="display:inline;max-width:185px"
|
||||
id="mqttqos" type="text">
|
||||
</span>
|
||||
<br>
|
||||
</div>
|
||||
<div class="row form-group">
|
||||
<label class="col-xs-3">Keep Alive<i style="margin-left: 10px;" class="glyphicon glyphicon-info-sign"
|
||||
aria-hidden="true" data-toggle="popover" data-trigger="hover" data-placement="right"
|
||||
data-content="MQTT Keep Alive time in seconds"></i></label>
|
||||
<span class="col-xs-9">
|
||||
<input class="form-control input-sm" placeholder="60" value="" style="display:inline;max-width:185px"
|
||||
id="mqttkeepalive" type="text">
|
||||
</span>
|
||||
<br>
|
||||
</div>
|
||||
<div class="row form-group">
|
||||
<label class="col-xs-3">Username<i style="margin-left: 10px;" class="glyphicon glyphicon-info-sign"
|
||||
aria-hidden="true" data-toggle="popover" data-trigger="hover" data-placement="right"
|
||||
@@ -231,7 +251,7 @@
|
||||
aria-hidden="true" data-toggle="popover" data-trigger="hover" data-placement="right"
|
||||
data-content="MQTT topic prefix (<mqtt base>/<host name>/)"></i></label>
|
||||
<span class="col-xs-9">
|
||||
<input class="form-control input-sm" placeholder="MQTT base" value="" style="display:inline;max-width:185px"
|
||||
<input class="form-control input-sm" placeholder="home" value="" style="display:inline;max-width:185px"
|
||||
id="mqttbase" type="text">
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -25,6 +25,8 @@ var config = {
|
||||
"enabled": false,
|
||||
"ip": "",
|
||||
"port": 1883,
|
||||
"qos": 1,
|
||||
"keepalive": 60,
|
||||
"base": "",
|
||||
"user": "",
|
||||
"password": "",
|
||||
@@ -173,6 +175,8 @@ function savemqtt() {
|
||||
|
||||
config.mqtt.ip = document.getElementById("mqttip").value;
|
||||
config.mqtt.port = parseInt(document.getElementById("mqttport").value);
|
||||
config.mqtt.qos = parseInt(document.getElementById("mqttqos").value);
|
||||
config.mqtt.keepalive = parseInt(document.getElementById("mqttkeepalive").value);
|
||||
config.mqtt.base = document.getElementById("mqttbase").value;
|
||||
config.mqtt.user = document.getElementById("mqttuser").value;
|
||||
config.mqtt.password = document.getElementById("mqttpwd").value;
|
||||
@@ -323,6 +327,8 @@ function listmqtt() {
|
||||
|
||||
document.getElementById("mqttip").value = config.mqtt.ip;
|
||||
document.getElementById("mqttport").value = config.mqtt.port;
|
||||
document.getElementById("mqttqos").value = config.mqtt.qos;
|
||||
document.getElementById("mqttkeepalive").value = config.mqtt.keepalive;
|
||||
document.getElementById("mqttbase").value = config.mqtt.base;
|
||||
document.getElementById("mqttuser").value = config.mqtt.user;
|
||||
document.getElementById("mqttpwd").value = config.mqtt.password;
|
||||
|
||||
@@ -76,6 +76,8 @@ var configfile = {
|
||||
"enabled": false,
|
||||
"ip": "ip",
|
||||
"port": "port",
|
||||
"qos": "qos",
|
||||
"keepalive": "keepalive",
|
||||
"base": "base",
|
||||
"user": "user",
|
||||
"password": "password",
|
||||
|
||||
Reference in New Issue
Block a user