mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-08 00:39:50 +03:00
Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev
This commit is contained in:
@@ -5,7 +5,6 @@
|
|||||||
## **IMPORTANT! BREAKING CHANGES**
|
## **IMPORTANT! BREAKING CHANGES**
|
||||||
|
|
||||||
- When upgrading to v3.5 for the first time from v3.4 on a BBQKees Gateway board you will need to use the [EMS-EPS Flasher](https://github.com/emsesp/EMS-ESP-Flasher/releases) to correctly re-partition the flash. Make sure you backup the settings and customizations from the WebUI (System->Upload/Download) and restore after the upgrade.
|
- When upgrading to v3.5 for the first time from v3.4 on a BBQKees Gateway board you will need to use the [EMS-EPS Flasher](https://github.com/emsesp/EMS-ESP-Flasher/releases) to correctly re-partition the flash. Make sure you backup the settings and customizations from the WebUI (System->Upload/Download) and restore after the upgrade.
|
||||||
- Since 3.5.0b11 we added support for multiple EMS-ESPs [#759] so they can co-exist with MQTT Discovery. The mqtt base is now included in each of the entity names to make them unique. Unfortunately this means in Home Assistant the entity IDs have also been renamed (for example from `number.boiler_burnminperiod` to `number.ems_esp_boiler_burnminperiod`) and any dashboards and automation scripts need to be adjusted accordingly.
|
|
||||||
|
|
||||||
## Added
|
## Added
|
||||||
|
|
||||||
|
|||||||
28
interface/package-lock.json
generated
28
interface/package-lock.json
generated
@@ -15,12 +15,12 @@
|
|||||||
"@mui/material": "^5.10.16",
|
"@mui/material": "^5.10.16",
|
||||||
"@table-library/react-table-library": "4.0.23",
|
"@table-library/react-table-library": "4.0.23",
|
||||||
"@types/lodash": "^4.14.191",
|
"@types/lodash": "^4.14.191",
|
||||||
"@types/node": "^18.11.10",
|
"@types/node": "^18.11.11",
|
||||||
"@types/react": "^18.0.26",
|
"@types/react": "^18.0.26",
|
||||||
"@types/react-dom": "^18.0.9",
|
"@types/react-dom": "^18.0.9",
|
||||||
"@types/react-router-dom": "^5.3.3",
|
"@types/react-router-dom": "^5.3.3",
|
||||||
"async-validator": "^4.2.5",
|
"async-validator": "^4.2.5",
|
||||||
"axios": "^1.2.0",
|
"axios": "^1.2.1",
|
||||||
"http-proxy-middleware": "^2.0.6",
|
"http-proxy-middleware": "^2.0.6",
|
||||||
"jwt-decode": "^3.1.2",
|
"jwt-decode": "^3.1.2",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
@@ -4017,9 +4017,9 @@
|
|||||||
"integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA=="
|
"integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA=="
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "18.11.10",
|
"version": "18.11.11",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.10.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.11.tgz",
|
||||||
"integrity": "sha512-juG3RWMBOqcOuXC643OAdSA525V44cVgGV6dUDuiFtss+8Fk5x1hI93Rsld43VeJVIeqlP9I7Fn9/qaVqoEAuQ=="
|
"integrity": "sha512-KJ021B1nlQUBLopzZmPBVuGU9un7WJd/W4ya7Ih02B4Uwky5Nja0yGYav2EfYIk0RR2Q9oVhf60S2XR1BCWJ2g=="
|
||||||
},
|
},
|
||||||
"node_modules/@types/parse-json": {
|
"node_modules/@types/parse-json": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
@@ -5030,9 +5030,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/axios": {
|
"node_modules/axios": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/axios/-/axios-1.2.1.tgz",
|
||||||
"integrity": "sha512-zT7wZyNYu3N5Bu0wuZ6QccIf93Qk1eV8LOewxgjOZFd2DenOs98cJ7+Y6703d0wkaXGY6/nZd4EweJaHz9uzQw==",
|
"integrity": "sha512-I88cFiGu9ryt/tfVEi4kX2SITsvDddTajXTOFmt2uK1ZVA8LytjtdeyefdQWEf5PU8w+4SSJDoYnggflB5tW4A==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"follow-redirects": "^1.15.0",
|
"follow-redirects": "^1.15.0",
|
||||||
"form-data": "^4.0.0",
|
"form-data": "^4.0.0",
|
||||||
@@ -20230,9 +20230,9 @@
|
|||||||
"integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA=="
|
"integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA=="
|
||||||
},
|
},
|
||||||
"@types/node": {
|
"@types/node": {
|
||||||
"version": "18.11.10",
|
"version": "18.11.11",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.10.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.11.tgz",
|
||||||
"integrity": "sha512-juG3RWMBOqcOuXC643OAdSA525V44cVgGV6dUDuiFtss+8Fk5x1hI93Rsld43VeJVIeqlP9I7Fn9/qaVqoEAuQ=="
|
"integrity": "sha512-KJ021B1nlQUBLopzZmPBVuGU9un7WJd/W4ya7Ih02B4Uwky5Nja0yGYav2EfYIk0RR2Q9oVhf60S2XR1BCWJ2g=="
|
||||||
},
|
},
|
||||||
"@types/parse-json": {
|
"@types/parse-json": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
@@ -20998,9 +20998,9 @@
|
|||||||
"integrity": "sha512-u2MVsXfew5HBvjsczCv+xlwdNnB1oQR9HlAcsejZttNjKKSkeDNVwB1vMThIUIFI9GoT57Vtk8iQLwqOfAkboA=="
|
"integrity": "sha512-u2MVsXfew5HBvjsczCv+xlwdNnB1oQR9HlAcsejZttNjKKSkeDNVwB1vMThIUIFI9GoT57Vtk8iQLwqOfAkboA=="
|
||||||
},
|
},
|
||||||
"axios": {
|
"axios": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/axios/-/axios-1.2.1.tgz",
|
||||||
"integrity": "sha512-zT7wZyNYu3N5Bu0wuZ6QccIf93Qk1eV8LOewxgjOZFd2DenOs98cJ7+Y6703d0wkaXGY6/nZd4EweJaHz9uzQw==",
|
"integrity": "sha512-I88cFiGu9ryt/tfVEi4kX2SITsvDddTajXTOFmt2uK1ZVA8LytjtdeyefdQWEf5PU8w+4SSJDoYnggflB5tW4A==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"follow-redirects": "^1.15.0",
|
"follow-redirects": "^1.15.0",
|
||||||
"form-data": "^4.0.0",
|
"form-data": "^4.0.0",
|
||||||
|
|||||||
@@ -11,12 +11,12 @@
|
|||||||
"@mui/material": "^5.10.16",
|
"@mui/material": "^5.10.16",
|
||||||
"@table-library/react-table-library": "4.0.23",
|
"@table-library/react-table-library": "4.0.23",
|
||||||
"@types/lodash": "^4.14.191",
|
"@types/lodash": "^4.14.191",
|
||||||
"@types/node": "^18.11.10",
|
"@types/node": "^18.11.11",
|
||||||
"@types/react": "^18.0.26",
|
"@types/react": "^18.0.26",
|
||||||
"@types/react-dom": "^18.0.9",
|
"@types/react-dom": "^18.0.9",
|
||||||
"@types/react-router-dom": "^5.3.3",
|
"@types/react-router-dom": "^5.3.3",
|
||||||
"async-validator": "^4.2.5",
|
"async-validator": "^4.2.5",
|
||||||
"axios": "^1.2.0",
|
"axios": "^1.2.1",
|
||||||
"http-proxy-middleware": "^2.0.6",
|
"http-proxy-middleware": "^2.0.6",
|
||||||
"jwt-decode": "^3.1.2",
|
"jwt-decode": "^3.1.2",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
|
|||||||
@@ -162,6 +162,10 @@ const MqttSettingsForm: FC = () => {
|
|||||||
</ValidatedTextField>
|
</ValidatedTextField>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
<BlockFormControlLabel
|
||||||
|
control={<Checkbox name="multiple_instances" checked={data.multiple_instances} onChange={updateFormValue} />}
|
||||||
|
label={LL.MQTT_MULTIPLE_INSTANCES()}
|
||||||
|
/>
|
||||||
<BlockFormControlLabel
|
<BlockFormControlLabel
|
||||||
control={<Checkbox name="clean_session" checked={data.clean_session} onChange={updateFormValue} />}
|
control={<Checkbox name="clean_session" checked={data.clean_session} onChange={updateFormValue} />}
|
||||||
label={LL.MQTT_CLEAN_SESSION()}
|
label={LL.MQTT_CLEAN_SESSION()}
|
||||||
|
|||||||
@@ -248,6 +248,7 @@ const de: Translation = {
|
|||||||
MQTT_INT_HEARTBEAT: 'Heartbeat',
|
MQTT_INT_HEARTBEAT: 'Heartbeat',
|
||||||
MQTT_QUEUE: 'MQTT Queue',
|
MQTT_QUEUE: 'MQTT Queue',
|
||||||
DEFAULT: 'Standard',
|
DEFAULT: 'Standard',
|
||||||
|
MQTT_MULTIPLE_INSTANCES: 'Enable Multiple Instances of EMS-ESP',
|
||||||
MQTT_CLEAN_SESSION: 'Setze `Clean Session`',
|
MQTT_CLEAN_SESSION: 'Setze `Clean Session`',
|
||||||
MQTT_RETAIN_FLAG: 'Setze `Retain flag` immer',
|
MQTT_RETAIN_FLAG: 'Setze `Retain flag` immer',
|
||||||
INACTIVE: 'Inaktiv',
|
INACTIVE: 'Inaktiv',
|
||||||
|
|||||||
@@ -248,6 +248,7 @@ const en: Translation = {
|
|||||||
MQTT_INT_HEARTBEAT: 'Heartbeat',
|
MQTT_INT_HEARTBEAT: 'Heartbeat',
|
||||||
MQTT_QUEUE: 'MQTT Queue',
|
MQTT_QUEUE: 'MQTT Queue',
|
||||||
DEFAULT: 'Default',
|
DEFAULT: 'Default',
|
||||||
|
MQTT_MULTIPLE_INSTANCES: 'Enable Multiple Instances of EMS-ESP',
|
||||||
MQTT_CLEAN_SESSION: 'Set Clean Session',
|
MQTT_CLEAN_SESSION: 'Set Clean Session',
|
||||||
MQTT_RETAIN_FLAG: 'Always set Retain flag',
|
MQTT_RETAIN_FLAG: 'Always set Retain flag',
|
||||||
INACTIVE: 'Inactive',
|
INACTIVE: 'Inactive',
|
||||||
|
|||||||
@@ -248,6 +248,7 @@ const nl: Translation = {
|
|||||||
MQTT_INT_HEARTBEAT: 'Heartbeat',
|
MQTT_INT_HEARTBEAT: 'Heartbeat',
|
||||||
MQTT_QUEUE: 'MQTT Queue',
|
MQTT_QUEUE: 'MQTT Queue',
|
||||||
DEFAULT: 'Default',
|
DEFAULT: 'Default',
|
||||||
|
MQTT_MULTIPLE_INSTANCES: 'Enable Multiple Instances of EMS-ESP',
|
||||||
MQTT_CLEAN_SESSION: 'Clean Session aan',
|
MQTT_CLEAN_SESSION: 'Clean Session aan',
|
||||||
MQTT_RETAIN_FLAG: 'Retain flag aan',
|
MQTT_RETAIN_FLAG: 'Retain flag aan',
|
||||||
INACTIVE: 'Inactief',
|
INACTIVE: 'Inactief',
|
||||||
|
|||||||
@@ -248,6 +248,7 @@ const no: Translation = {
|
|||||||
MQTT_INT_HEARTBEAT: 'Heartbeat',
|
MQTT_INT_HEARTBEAT: 'Heartbeat',
|
||||||
MQTT_QUEUE: 'MQTT Queue',
|
MQTT_QUEUE: 'MQTT Queue',
|
||||||
DEFAULT: 'Standard',
|
DEFAULT: 'Standard',
|
||||||
|
MQTT_MULTIPLE_INSTANCES: 'Enable Multiple Instances of EMS-ESP',
|
||||||
MQTT_CLEAN_SESSION: 'Benytt Clean Session',
|
MQTT_CLEAN_SESSION: 'Benytt Clean Session',
|
||||||
MQTT_RETAIN_FLAG: 'Alltid sett Retain flag',
|
MQTT_RETAIN_FLAG: 'Alltid sett Retain flag',
|
||||||
INACTIVE: 'Innaktiv',
|
INACTIVE: 'Innaktiv',
|
||||||
|
|||||||
@@ -248,6 +248,7 @@ const pl: BaseTranslation = {
|
|||||||
MQTT_INT_HEARTBEAT: 'Heartbeat',
|
MQTT_INT_HEARTBEAT: 'Heartbeat',
|
||||||
MQTT_QUEUE: 'Kolejka MQTT',
|
MQTT_QUEUE: 'Kolejka MQTT',
|
||||||
DEFAULT: '{{Pozostałe|Domyślna|}}',
|
DEFAULT: '{{Pozostałe|Domyślna|}}',
|
||||||
|
MQTT_MULTIPLE_INSTANCES: 'Enable Multiple Instances of EMS-ESP',
|
||||||
MQTT_CLEAN_SESSION: 'Ustawiaj flagę "Clean session"',
|
MQTT_CLEAN_SESSION: 'Ustawiaj flagę "Clean session"',
|
||||||
MQTT_RETAIN_FLAG: 'Ustawiaj flagę "Retain"',
|
MQTT_RETAIN_FLAG: 'Ustawiaj flagę "Retain"',
|
||||||
INACTIVE: 'nieaktywny',
|
INACTIVE: 'nieaktywny',
|
||||||
|
|||||||
@@ -248,6 +248,7 @@ const se: Translation = {
|
|||||||
MQTT_INT_HEARTBEAT: 'Heartbeat',
|
MQTT_INT_HEARTBEAT: 'Heartbeat',
|
||||||
MQTT_QUEUE: 'MQTT Queue',
|
MQTT_QUEUE: 'MQTT Queue',
|
||||||
DEFAULT: 'Standard',
|
DEFAULT: 'Standard',
|
||||||
|
MQTT_MULTIPLE_INSTANCES: 'Enable Multiple Instances of EMS-ESP',
|
||||||
MQTT_CLEAN_SESSION: 'Använd "Clean Session"-flaggan',
|
MQTT_CLEAN_SESSION: 'Använd "Clean Session"-flaggan',
|
||||||
MQTT_RETAIN_FLAG: 'Använd "Always Retain"-flaggan',
|
MQTT_RETAIN_FLAG: 'Använd "Always Retain"-flaggan',
|
||||||
INACTIVE: 'Inaktiv',
|
INACTIVE: 'Inaktiv',
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ export interface MqttSettings {
|
|||||||
client_id: string;
|
client_id: string;
|
||||||
keep_alive: number;
|
keep_alive: number;
|
||||||
clean_session: boolean;
|
clean_session: boolean;
|
||||||
|
multiple_instances: boolean;
|
||||||
publish_time_boiler: number;
|
publish_time_boiler: number;
|
||||||
publish_time_thermostat: number;
|
publish_time_thermostat: number;
|
||||||
publish_time_solar: number;
|
publish_time_solar: number;
|
||||||
|
|||||||
@@ -154,6 +154,7 @@ void MqttSettings::read(MqttSettings & settings, JsonObject & root) {
|
|||||||
root["client_id"] = settings.clientId;
|
root["client_id"] = settings.clientId;
|
||||||
root["keep_alive"] = settings.keepAlive;
|
root["keep_alive"] = settings.keepAlive;
|
||||||
root["clean_session"] = settings.cleanSession;
|
root["clean_session"] = settings.cleanSession;
|
||||||
|
root["multiple_instances"] = settings.multiple_instances;
|
||||||
|
|
||||||
// added by proddy for EMS-ESP
|
// added by proddy for EMS-ESP
|
||||||
root["publish_time_boiler"] = settings.publish_time_boiler;
|
root["publish_time_boiler"] = settings.publish_time_boiler;
|
||||||
@@ -186,6 +187,8 @@ StateUpdateResult MqttSettings::update(JsonObject & root, MqttSettings & setting
|
|||||||
newSettings.clientId = root["client_id"] | FACTORY_MQTT_CLIENT_ID;
|
newSettings.clientId = root["client_id"] | FACTORY_MQTT_CLIENT_ID;
|
||||||
newSettings.keepAlive = root["keep_alive"] | FACTORY_MQTT_KEEP_ALIVE;
|
newSettings.keepAlive = root["keep_alive"] | FACTORY_MQTT_KEEP_ALIVE;
|
||||||
newSettings.cleanSession = root["clean_session"] | FACTORY_MQTT_CLEAN_SESSION;
|
newSettings.cleanSession = root["clean_session"] | FACTORY_MQTT_CLEAN_SESSION;
|
||||||
|
newSettings.multiple_instances = root["multiple_instances"] | FACTORY_MQTT_MULTIPLE_INSTANCES;
|
||||||
|
|
||||||
newSettings.mqtt_qos = root["mqtt_qos"] | EMSESP_DEFAULT_MQTT_QOS;
|
newSettings.mqtt_qos = root["mqtt_qos"] | EMSESP_DEFAULT_MQTT_QOS;
|
||||||
newSettings.mqtt_retain = root["mqtt_retain"] | EMSESP_DEFAULT_MQTT_RETAIN;
|
newSettings.mqtt_retain = root["mqtt_retain"] | EMSESP_DEFAULT_MQTT_RETAIN;
|
||||||
|
|
||||||
|
|||||||
@@ -57,6 +57,10 @@ static String generateClientId() {
|
|||||||
#define FACTORY_MQTT_MAX_TOPIC_LENGTH 128
|
#define FACTORY_MQTT_MAX_TOPIC_LENGTH 128
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef FACTORY_MQTT_MULTIPLE_INSTANCES
|
||||||
|
#define FACTORY_MQTT_MULTIPLE_INSTANCES false
|
||||||
|
#endif
|
||||||
|
|
||||||
class MqttSettings {
|
class MqttSettings {
|
||||||
public:
|
public:
|
||||||
// host and port - if enabled
|
// host and port - if enabled
|
||||||
@@ -75,6 +79,9 @@ class MqttSettings {
|
|||||||
uint16_t keepAlive;
|
uint16_t keepAlive;
|
||||||
bool cleanSession;
|
bool cleanSession;
|
||||||
|
|
||||||
|
// multiple instances
|
||||||
|
bool multiple_instances;
|
||||||
|
|
||||||
// proddy EMS-ESP specific
|
// proddy EMS-ESP specific
|
||||||
String base;
|
String base;
|
||||||
uint16_t publish_time_boiler;
|
uint16_t publish_time_boiler;
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ class DummySettings {
|
|||||||
String username = "";
|
String username = "";
|
||||||
uint16_t keepAlive = 60;
|
uint16_t keepAlive = 60;
|
||||||
bool cleanSession = false;
|
bool cleanSession = false;
|
||||||
|
bool multiple_instances = false;
|
||||||
|
|
||||||
uint16_t publish_time_boiler = 10;
|
uint16_t publish_time_boiler = 10;
|
||||||
uint16_t publish_time_thermostat = 10;
|
uint16_t publish_time_thermostat = 10;
|
||||||
|
|||||||
@@ -219,6 +219,7 @@ mqtt_settings = {
|
|||||||
client_id: 'ems-esp',
|
client_id: 'ems-esp',
|
||||||
keep_alive: 60,
|
keep_alive: 60,
|
||||||
clean_session: true,
|
clean_session: true,
|
||||||
|
multiple_instances: false,
|
||||||
publish_time_boiler: 10,
|
publish_time_boiler: 10,
|
||||||
publish_time_thermostat: 10,
|
publish_time_thermostat: 10,
|
||||||
publish_time_solar: 10,
|
publish_time_solar: 10,
|
||||||
|
|||||||
@@ -451,7 +451,12 @@ void AnalogSensor::publish_values(const bool force) {
|
|||||||
}
|
}
|
||||||
config["val_tpl"] = str;
|
config["val_tpl"] = str;
|
||||||
|
|
||||||
|
if (Mqtt::multiple_instances()) {
|
||||||
snprintf(str, sizeof(str), "%s_analogsensor_%d", Mqtt::basename().c_str(), sensor.gpio());
|
snprintf(str, sizeof(str), "%s_analogsensor_%d", Mqtt::basename().c_str(), sensor.gpio());
|
||||||
|
} else {
|
||||||
|
snprintf(str, sizeof(str), "analogsensor_%d", sensor.gpio());
|
||||||
|
}
|
||||||
|
|
||||||
config["object_id"] = str;
|
config["object_id"] = str;
|
||||||
config["uniq_id"] = str; // same as object_id
|
config["uniq_id"] = str; // same as object_id
|
||||||
|
|
||||||
|
|||||||
@@ -518,7 +518,12 @@ void DallasSensor::publish_values(const bool force) {
|
|||||||
}
|
}
|
||||||
config["val_tpl"] = str;
|
config["val_tpl"] = str;
|
||||||
|
|
||||||
|
if (Mqtt::multiple_instances()) {
|
||||||
snprintf(str, sizeof(str), "%s_dallassensor_%s", Mqtt::basename().c_str(), sensor.id().c_str());
|
snprintf(str, sizeof(str), "%s_dallassensor_%s", Mqtt::basename().c_str(), sensor.id().c_str());
|
||||||
|
} else {
|
||||||
|
snprintf(str, sizeof(str), "dallassensor_%s", sensor.id().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
config["object_id"] = str;
|
config["object_id"] = str;
|
||||||
config["uniq_id"] = str; // same as object_id
|
config["uniq_id"] = str; // same as object_id
|
||||||
|
|
||||||
|
|||||||
18
src/mqtt.cpp
18
src/mqtt.cpp
@@ -38,6 +38,7 @@ uint32_t Mqtt::publish_time_sensor_;
|
|||||||
uint32_t Mqtt::publish_time_other_;
|
uint32_t Mqtt::publish_time_other_;
|
||||||
uint32_t Mqtt::publish_time_heartbeat_;
|
uint32_t Mqtt::publish_time_heartbeat_;
|
||||||
bool Mqtt::mqtt_enabled_;
|
bool Mqtt::mqtt_enabled_;
|
||||||
|
bool Mqtt::multiple_instances_;
|
||||||
bool Mqtt::ha_enabled_;
|
bool Mqtt::ha_enabled_;
|
||||||
uint8_t Mqtt::nested_format_;
|
uint8_t Mqtt::nested_format_;
|
||||||
std::string Mqtt::discovery_prefix_;
|
std::string Mqtt::discovery_prefix_;
|
||||||
@@ -429,6 +430,7 @@ void Mqtt::load_settings() {
|
|||||||
publish_single2cmd_ = mqttSettings.publish_single2cmd;
|
publish_single2cmd_ = mqttSettings.publish_single2cmd;
|
||||||
send_response_ = mqttSettings.send_response;
|
send_response_ = mqttSettings.send_response;
|
||||||
discovery_prefix_ = mqttSettings.discovery_prefix.c_str();
|
discovery_prefix_ = mqttSettings.discovery_prefix.c_str();
|
||||||
|
multiple_instances_ = mqttSettings.multiple_instances;
|
||||||
|
|
||||||
// convert to milliseconds
|
// convert to milliseconds
|
||||||
publish_time_boiler_ = mqttSettings.publish_time_boiler * 1000;
|
publish_time_boiler_ = mqttSettings.publish_time_boiler * 1000;
|
||||||
@@ -606,10 +608,10 @@ void Mqtt::ha_status() {
|
|||||||
StaticJsonDocument<EMSESP_JSON_SIZE_HA_CONFIG> doc;
|
StaticJsonDocument<EMSESP_JSON_SIZE_HA_CONFIG> doc;
|
||||||
|
|
||||||
char uniq[70];
|
char uniq[70];
|
||||||
snprintf(uniq, sizeof(uniq), "%s_status", mqtt_basename_.c_str());
|
snprintf(uniq, sizeof(uniq), "%s_status", mqtt_basename_.c_str()); // always use basename
|
||||||
doc["uniq_id"] = uniq;
|
doc["uniq_id"] = uniq;
|
||||||
doc["object_id"] = uniq;
|
doc["object_id"] = uniq;
|
||||||
doc["~"] = mqtt_base_; // default ems-esp
|
doc["~"] = mqtt_base_;
|
||||||
// doc["avty_t"] = "~/status"; // commented out, as it causes errors in HA sometimes
|
// doc["avty_t"] = "~/status"; // commented out, as it causes errors in HA sometimes
|
||||||
// doc["json_attr_t"] = "~/heartbeat"; // store also as HA attributes
|
// doc["json_attr_t"] = "~/heartbeat"; // store also as HA attributes
|
||||||
doc["stat_t"] = "~/status";
|
doc["stat_t"] = "~/status";
|
||||||
@@ -796,6 +798,7 @@ void Mqtt::process_queue() {
|
|||||||
if (message->topic.find(discovery_prefix_) == 0) {
|
if (message->topic.find(discovery_prefix_) == 0) {
|
||||||
strlcpy(topic, message->topic.c_str(), sizeof(topic)); // leave topic as it is
|
strlcpy(topic, message->topic.c_str(), sizeof(topic)); // leave topic as it is
|
||||||
} else {
|
} else {
|
||||||
|
// it's a discovery topic, added the mqtt base to the topic path
|
||||||
snprintf(topic, MQTT_TOPIC_MAX_SIZE, "%s/%s", mqtt_base_.c_str(), message->topic.c_str()); // uses base
|
snprintf(topic, MQTT_TOPIC_MAX_SIZE, "%s/%s", mqtt_base_.c_str(), message->topic.c_str()); // uses base
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -978,7 +981,12 @@ void Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
|
|||||||
|
|
||||||
// build unique identifier which will be used in the topic, also used as object_id
|
// build unique identifier which will be used in the topic, also used as object_id
|
||||||
char uniq_id[70];
|
char uniq_id[70];
|
||||||
|
if (multiple_instances_) {
|
||||||
|
// prefix base name to each uniq_id
|
||||||
snprintf(uniq_id, sizeof(uniq_id), "%s_%s_%s", mqtt_basename_.c_str(), device_name, entity_with_tag);
|
snprintf(uniq_id, sizeof(uniq_id), "%s_%s_%s", mqtt_basename_.c_str(), device_name, entity_with_tag);
|
||||||
|
} else {
|
||||||
|
snprintf(uniq_id, sizeof(uniq_id), "%s_%s", device_name, entity_with_tag);
|
||||||
|
}
|
||||||
|
|
||||||
// build a config topic that will be prefix onto a HA type (e.g. number, switch)
|
// build a config topic that will be prefix onto a HA type (e.g. number, switch)
|
||||||
// e.g. homeassistant/number/ems-esp/thermostat_hc1_manualtemp
|
// e.g. homeassistant/number/ems-esp/thermostat_hc1_manualtemp
|
||||||
@@ -1280,7 +1288,13 @@ void Mqtt::publish_ha_climate_config(const uint8_t tag, const bool has_roomtemp,
|
|||||||
hc_mode_s);
|
hc_mode_s);
|
||||||
|
|
||||||
snprintf(name_s, sizeof(name_s), "Hc%d", hc_num);
|
snprintf(name_s, sizeof(name_s), "Hc%d", hc_num);
|
||||||
|
|
||||||
|
if (Mqtt::multiple_instances()) {
|
||||||
snprintf(uniq_id_s, sizeof(uniq_id_s), "%s_thermostat_hc%d", mqtt_basename_.c_str(), hc_num); // add basename
|
snprintf(uniq_id_s, sizeof(uniq_id_s), "%s_thermostat_hc%d", mqtt_basename_.c_str(), hc_num); // add basename
|
||||||
|
} else {
|
||||||
|
snprintf(uniq_id_s, sizeof(uniq_id_s), "thermostat_hc%d", hc_num); // backward compatible with v3.4
|
||||||
|
}
|
||||||
|
|
||||||
snprintf(temp_cmd_s, sizeof(temp_cmd_s), "~/thermostat/hc%d/seltemp", hc_num);
|
snprintf(temp_cmd_s, sizeof(temp_cmd_s), "~/thermostat/hc%d/seltemp", hc_num);
|
||||||
snprintf(mode_cmd_s, sizeof(temp_cmd_s), "~/thermostat/hc%d/mode", hc_num);
|
snprintf(mode_cmd_s, sizeof(temp_cmd_s), "~/thermostat/hc%d/mode", hc_num);
|
||||||
|
|
||||||
|
|||||||
@@ -180,6 +180,10 @@ class Mqtt {
|
|||||||
return nested_format_ == NestedFormat::NESTED;
|
return nested_format_ == NestedFormat::NESTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool multiple_instances() {
|
||||||
|
return multiple_instances_;
|
||||||
|
}
|
||||||
|
|
||||||
static void nested_format(uint8_t nested_format) {
|
static void nested_format(uint8_t nested_format) {
|
||||||
nested_format_ = nested_format;
|
nested_format_ = nested_format;
|
||||||
}
|
}
|
||||||
@@ -317,6 +321,7 @@ class Mqtt {
|
|||||||
static bool mqtt_enabled_;
|
static bool mqtt_enabled_;
|
||||||
static bool ha_enabled_;
|
static bool ha_enabled_;
|
||||||
static uint8_t nested_format_;
|
static uint8_t nested_format_;
|
||||||
|
static bool multiple_instances_;
|
||||||
static std::string discovery_prefix_;
|
static std::string discovery_prefix_;
|
||||||
static bool publish_single_;
|
static bool publish_single_;
|
||||||
static bool publish_single2cmd_;
|
static bool publish_single2cmd_;
|
||||||
|
|||||||
@@ -1147,6 +1147,7 @@ bool System::command_info(const char * value, const int8_t id, JsonObject & outp
|
|||||||
node["client id"] = settings.clientId;
|
node["client id"] = settings.clientId;
|
||||||
node["keep alive"] = settings.keepAlive;
|
node["keep alive"] = settings.keepAlive;
|
||||||
node["clean session"] = settings.cleanSession;
|
node["clean session"] = settings.cleanSession;
|
||||||
|
node["multiple instances"] = settings.multiple_instances;
|
||||||
node["base"] = settings.base;
|
node["base"] = settings.base;
|
||||||
node["discovery prefix"] = settings.discovery_prefix;
|
node["discovery prefix"] = settings.discovery_prefix;
|
||||||
node["nested format"] = settings.nested_format;
|
node["nested format"] = settings.nested_format;
|
||||||
|
|||||||
Reference in New Issue
Block a user