@@ -64,11 +64,11 @@ void Mqtt::subscribe(const uint8_t device_type, const std::string & topic, mqtt_
64
64
if (!mqtt_subfunctions_.empty ()) {
65
65
for (auto & mqtt_subfunction : mqtt_subfunctions_) {
66
66
if ((mqtt_subfunction.device_type_ == device_type) && (strcmp (mqtt_subfunction.topic_ .c_str (), topic.c_str ()) == 0 )) {
67
- // add the function, in case its not there
67
+ // add the function ( in case its not there) and quit because it already exists
68
68
if (cb) {
69
69
mqtt_subfunction.mqtt_subfunction_ = cb;
70
70
}
71
- return ; // it exists, exit
71
+ return ;
72
72
}
73
73
}
74
74
}
@@ -89,8 +89,9 @@ void Mqtt::subscribe(const uint8_t device_type, const std::string & topic, mqtt_
89
89
90
90
// subscribe to the command topic if it doesn't exist yet
91
91
void Mqtt::register_command (const uint8_t device_type, const __FlashStringHelper * cmd, cmdfunction_p cb) {
92
- std::string cmd_topic = EMSdevice::device_type_2_device_name (device_type);
92
+ std::string cmd_topic = EMSdevice::device_type_2_device_name (device_type); // thermostat, boiler, etc...
93
93
94
+ // see if we have already a handler for the device type (boiler, thermostat). If not add it
94
95
bool exists = false ;
95
96
if (!mqtt_subfunctions_.empty ()) {
96
97
for (const auto & mqtt_subfunction : mqtt_subfunctions_) {
@@ -101,15 +102,21 @@ void Mqtt::register_command(const uint8_t device_type, const __FlashStringHelper
101
102
}
102
103
103
104
if (!exists) {
104
- Mqtt::subscribe (device_type, cmd_topic, nullptr ); // use an empty function handler to signal this is a command function
105
+ Mqtt::subscribe (device_type, cmd_topic, nullptr ); // use an empty function handler to signal this is a command function only (e.g. ems-esp/boiler)
106
+ LOG_DEBUG (F (" Registering MQTT cmd %s with topic %s" ), uuid::read_flash_string (cmd).c_str (), EMSdevice::device_type_2_device_name (device_type).c_str ());
105
107
}
106
108
107
- LOG_DEBUG (F (" Registering MQTT cmd %s with topic %s" ), uuid::read_flash_string (cmd).c_str (), EMSdevice::device_type_2_device_name (device_type).c_str ());
109
+ // register the individual commands too (e.g. ems-esp/boiler/wwonetime)
110
+ // https://github.com/emsesp/EMS-ESP32/issues/31
111
+ std::string topic (100 , ' \0 ' );
112
+ topic = cmd_topic + " /" + uuid::read_flash_string (cmd);
113
+ Mqtt::subscribe (device_type, topic, nullptr );
108
114
}
109
115
110
- // subscribe to an MQTT topic, and store the associated callback function. For generic functions not tied to a specific device
116
+ // subscribe to an MQTT topic, and store the associated callback function
117
+ // For generic functions not tied to a specific device
111
118
void Mqtt::subscribe (const std::string & topic, mqtt_subfunction_p cb) {
112
- subscribe (0 , topic, cb); // no device_id needed, if generic to EMS-ESP
119
+ subscribe (0 , topic, cb); // no device_id needed if generic to EMS-ESP
113
120
}
114
121
115
122
// resubscribe to all MQTT topics
@@ -189,7 +196,7 @@ void Mqtt::show_mqtt(uuid::console::Shell & shell) {
189
196
// show subscriptions
190
197
shell.printfln (F (" MQTT topic subscriptions:" ));
191
198
for (const auto & mqtt_subfunction : mqtt_subfunctions_) {
192
- shell.printfln (F (" %s/%s" ), mqtt_base_.c_str (), mqtt_subfunction.topic_ .c_str ());
199
+ shell.printfln (F (" %s/%s (%s) " ), mqtt_base_.c_str (), mqtt_subfunction.topic_ . c_str (), EMSdevice::device_type_2_device_name (mqtt_subfunction. device_type_ ) .c_str ());
193
200
}
194
201
shell.println ();
195
202
@@ -266,6 +273,20 @@ void Mqtt::on_message(const char * fulltopic, const char * payload, size_t len)
266
273
return ;
267
274
}
268
275
276
+ // check if it's not json, then try and extract the command from the topic name
277
+ if (message[0 ] != ' {' ) {
278
+ char * cmd_only = strrchr (topic, ' /' );
279
+ if (cmd_only == NULL ) {
280
+ return ; // invalid topic name
281
+ }
282
+ cmd_only++; // skip the /
283
+ // LOG_INFO(F("devicetype= %d, topic = %s, cmd = %s, message = %s"), mf.device_type_, topic, cmd_only, message);
284
+ if (!Command::call (mf.device_type_ , cmd_only, message)) {
285
+ LOG_ERROR (F (" No matching cmd (%s) in topic %s, or invalid data" ), cmd_only, topic);
286
+ }
287
+ return ;
288
+ }
289
+
269
290
// It's a command then with the payload being JSON like {"cmd":"<cmd>", "data":<data>, "id":<n>}
270
291
// Find the command from the json and call it directly
271
292
StaticJsonDocument<EMSESP_JSON_SIZE_SMALL> doc;
@@ -305,7 +326,7 @@ void Mqtt::on_message(const char * fulltopic, const char * payload, size_t len)
305
326
}
306
327
307
328
if (!cmd_known) {
308
- LOG_ERROR (F (" No matching cmd (%s), invalid data or command failed " ), command);
329
+ LOG_ERROR (F (" No matching cmd (%s) or invalid data " ), command);
309
330
}
310
331
311
332
return ;
0 commit comments