Skip to content

Commit ad1dab2

Browse files
authored
Merge pull request arendst#4531 from emontnemery/hass_announce_switch
MQTT Discovery - Announce switches
2 parents 1f65621 + df3e47e commit ad1dab2

File tree

2 files changed

+109
-48
lines changed

2 files changed

+109
-48
lines changed

sonoff/sonoff.ino

+2-1
Original file line numberDiff line numberDiff line change
@@ -1308,7 +1308,8 @@ boolean SendKey(byte key, byte device, byte state)
13081308
Format(key_topic, tmp, sizeof(key_topic));
13091309
if (Settings.flag.mqtt_enabled && MqttIsConnected() && (strlen(key_topic) != 0) && strcmp(key_topic, "0")) {
13101310
if (!key && (device > devices_present)) device = 1; // Only allow number of buttons up to number of devices
1311-
GetTopic_P(stopic, CMND, key_topic, GetPowerDevice(scommand, device, sizeof(scommand), key)); // cmnd/switchtopic/POWERx
1311+
GetTopic_P(stopic, CMND, key_topic, GetPowerDevice(scommand, device, sizeof(scommand),
1312+
(key + Settings.flag.device_index_enable))); // cmnd/switchtopic/POWERx
13121313
if (9 == state) {
13131314
mqtt_data[0] = '\0';
13141315
} else {

sonoff/xdrv_12_home_assistant.ino

+107-47
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,21 @@ const char HASS_DISCOVER_RELAY[] PROGMEM =
3333
"\"payload_available\":\"" D_ONLINE "\"," // Online
3434
"\"payload_not_available\":\"" D_OFFLINE "\""; // Offline
3535

36-
const char HASS_DISCOVER_BUTTON[] PROGMEM =
36+
const char HASS_DISCOVER_BUTTON_SWITCH[] PROGMEM =
3737
"{\"name\":\"%s\"," // dualr2 1 BTN
3838
"\"state_topic\":\"%s\"," // cmnd/dualr2/POWER (implies "\"optimistic\":\"false\",")
3939
// "\"value_template\":\"{{value_json.%s}}\"," // POWER2
40-
"\"payload_on\":\"%s\"," // TOGGLE
40+
"\"payload_on\":\"%s\"," // TOGGLE / ON
4141
// "\"optimistic\":\"false\"," // false is Hass default when state_topic is set
4242
"\"availability_topic\":\"%s\"," // tele/dualr2/LWT
4343
"\"payload_available\":\"" D_ONLINE "\"," // Online
44-
"\"payload_not_available\":\"" D_OFFLINE "\"," // Offline
45-
"\"force_update\":true";
44+
"\"payload_not_available\":\"" D_OFFLINE "\""; // Offline
45+
46+
const char HASS_DISCOVER_BUTTON_SWITCH_TOGGLE[] PROGMEM =
47+
"%s,\"force_update\":true";
48+
49+
const char HASS_DISCOVER_BUTTON_SWITCH_ONOFF[] PROGMEM =
50+
"%s,\"payload_off\":\"%s\""; // OFF
4651

4752
const char HASS_DISCOVER_LIGHT_DIMMER[] PROGMEM =
4853
"%s,\"brightness_command_topic\":\"%s\"," // cmnd/led2/Dimmer
@@ -92,16 +97,22 @@ const char HASS_DISCOVER_RELAY_SHORT[] PROGMEM =
9297
"\"pl_avail\":\"" D_ONLINE "\"," // Online
9398
"\"pl_not_avail\":\"" D_OFFLINE "\""; // Offline
9499

95-
const char HASS_DISCOVER_BUTTON_SHORT[] PROGMEM =
100+
const char HASS_DISCOVER_BUTTON_SWITCH_SHORT[] PROGMEM =
96101
"{\"name\":\"%s\"," // dualr2 1 BTN
97102
"\"stat_t\":\"%s\"," // cmnd/dualr2/POWER (implies "\"optimistic\":\"false\",")
98103
// "\"value_template\":\"{{value_json.%s}}\"," // POWER2
99104
"\"pl_on\":\"%s\"," // TOGGLE
100105
// "\"optimistic\":\"false\"," // false is Hass default when state_topic is set
101106
"\"avty_t\":\"%s\"," // tele/dualr2/LWT
102107
"\"pl_avail\":\"" D_ONLINE "\"," // Online
103-
"\"pl_not_avail\":\"" D_OFFLINE "\"," // Offline
104-
"\"frc_upd\":true";
108+
"\"pl_not_avail\":\"" D_OFFLINE "\""; // Offline
109+
110+
const char HASS_DISCOVER_BUTTON_SWITCH_TOGGLE_SHORT[] PROGMEM =
111+
"%s,\"frc_upd\":true";
112+
113+
const char HASS_DISCOVER_BUTTON_SWITCH_ONOFF_SHORT[] PROGMEM =
114+
"%s,\"pl_off\":\"%s\""; // OFF
115+
105116

106117
const char HASS_DISCOVER_LIGHT_DIMMER_SHORT[] PROGMEM =
107118
"%s,\"bri_cmd_t\":\"%s\"," // cmnd/led2/Dimmer
@@ -266,9 +277,85 @@ void HAssAnnounceRelayLight(void)
266277
}
267278
}
268279

269-
void HAssAnnounceButton(void)
280+
void HAssAnnounceButtonSwitch(byte device, char* topic, byte present, byte key, byte toggle)
270281
{
282+
char stopic[TOPSZ];
271283
char sidx[8];
284+
285+
mqtt_data[0] = '\0'; // Clear retained message
286+
287+
// Clear or Set topic
288+
snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/binary_sensor/%s_%s_%d/config"),
289+
topic, key?"BTN":"SW",device+1);
290+
291+
if (Settings.flag.hass_discovery && present) {
292+
char name[33];
293+
char value_template[33];
294+
char _state_topic[TOPSZ];
295+
char _availability_topic[TOPSZ];
296+
char prefix[TOPSZ];
297+
char *state_topic = _state_topic;
298+
char *availability_topic = _availability_topic;
299+
300+
if (device+1 > MAX_FRIENDLYNAMES) {
301+
snprintf_P(name, sizeof(name), PSTR("%s %s %d"), Settings.friendlyname[0], key?"BTN":"SW", device+1);
302+
} else {
303+
snprintf_P(name, sizeof(name), PSTR("%s %s"), Settings.friendlyname[device], key?"BTN":"SW");
304+
}
305+
GetPowerDevice(value_template, device+1, sizeof(value_template), Settings.flag.device_index_enable);
306+
GetTopic_P(state_topic, CMND, topic, value_template); // State of button is sent as CMND TOGGLE, state of switch is sent as ON/OFF
307+
GetTopic_P(availability_topic, TELE, mqtt_topic, S_LWT);
308+
FindPrefix(state_topic, availability_topic, prefix);
309+
if (Settings.flag3.hass_short_discovery_msg) {
310+
Shorten(&state_topic, prefix);
311+
Shorten(&availability_topic, prefix);
312+
}
313+
snprintf_P(mqtt_data, sizeof(mqtt_data), Settings.flag3.hass_short_discovery_msg?HASS_DISCOVER_BUTTON_SWITCH_SHORT:HASS_DISCOVER_BUTTON_SWITCH,
314+
name, state_topic, Settings.state_text[toggle?2:1], availability_topic);
315+
if (toggle) snprintf_P(mqtt_data, sizeof(mqtt_data),
316+
Settings.flag3.hass_short_discovery_msg?HASS_DISCOVER_BUTTON_SWITCH_TOGGLE_SHORT:HASS_DISCOVER_BUTTON_SWITCH_TOGGLE,
317+
mqtt_data);
318+
else snprintf_P(mqtt_data, sizeof(mqtt_data),
319+
Settings.flag3.hass_short_discovery_msg?HASS_DISCOVER_BUTTON_SWITCH_ONOFF_SHORT:HASS_DISCOVER_BUTTON_SWITCH_ONOFF,
320+
mqtt_data, Settings.state_text[0]);
321+
322+
if (Settings.flag3.hass_short_discovery_msg)
323+
snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_TOPIC_PREFIX, mqtt_data, prefix);
324+
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
325+
}
326+
MqttPublish(stopic, true);
327+
}
328+
329+
void HAssAnnounceSwitches(void)
330+
{
331+
char sw_topic[sizeof(Settings.switch_topic)];
332+
333+
// Send info about buttons
334+
char *tmp = Settings.switch_topic;
335+
Format(sw_topic, tmp, sizeof(sw_topic));
336+
if ((strlen(sw_topic) != 0) && strcmp(sw_topic, "0")) {
337+
for (byte switch_index = 0; switch_index < MAX_SWITCHES; switch_index++) {
338+
byte switch_present = 0;
339+
byte toggle = 1;
340+
341+
if ((pin[GPIO_SWT1 + switch_index] < 99) || (pin[GPIO_SWT1_NP + switch_index] < 99)) {
342+
switch_present = 1;
343+
}
344+
345+
// Check if MQTT message will be ON/OFF or TOGGLE
346+
if (Settings.switchmode[switch_index] == FOLLOW || Settings.switchmode[switch_index] == FOLLOW_INV ||
347+
!strcmp(mqtt_topic, sw_topic) || !strcmp(Settings.mqtt_grptopic, sw_topic))
348+
{
349+
toggle = 0;
350+
}
351+
352+
HAssAnnounceButtonSwitch(switch_index, sw_topic, switch_present, 0, toggle);
353+
}
354+
}
355+
}
356+
357+
void HAssAnnounceButtons(void)
358+
{
272359
char stopic[TOPSZ];
273360
char key_topic[sizeof(Settings.button_topic)];
274361

@@ -277,52 +364,24 @@ void HAssAnnounceButton(void)
277364
Format(key_topic, tmp, sizeof(key_topic));
278365
if ((strlen(key_topic) != 0) && strcmp(key_topic, "0")) {
279366
for (byte button_index = 0; button_index < MAX_KEYS; button_index++) {
280-
uint8_t button_present = 0;
367+
byte button_present = 0;
368+
byte toggle = 1;
281369

282370
if (!button_index && ((SONOFF_DUAL == Settings.module) || (CH4 == Settings.module))) {
283371
button_present = 1;
284372
} else {
285-
if (pin[GPIO_KEY1 + button_index] < 99) {
373+
if ((pin[GPIO_KEY1 + button_index] < 99) || (pin[GPIO_KEY1_NP + button_index] < 99)) {
286374
button_present = 1;
287375
}
288376
}
289377

290-
mqtt_data[0] = '\0'; // Clear retained message
291-
292-
// Clear or Set topic
293-
snprintf_P(sidx, sizeof(sidx), PSTR("_%d"), button_index+1);
294-
snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/%s/%s%s/config"), "binary_sensor", key_topic, sidx);
295-
296-
if (Settings.flag.hass_discovery && button_present) {
297-
char name[33];
298-
char value_template[33];
299-
char _state_topic[TOPSZ];
300-
char _availability_topic[TOPSZ];
301-
char prefix[TOPSZ];
302-
char *state_topic = _state_topic;
303-
char *availability_topic = _availability_topic;
304-
305-
if (button_index+1 > MAX_FRIENDLYNAMES) {
306-
snprintf_P(name, sizeof(name), PSTR("%s %d BTN"), Settings.friendlyname[0], button_index+1);
307-
} else {
308-
snprintf_P(name, sizeof(name), PSTR("%s BTN"), Settings.friendlyname[button_index]);
309-
}
310-
GetPowerDevice(value_template, button_index+1, sizeof(value_template), Settings.flag.device_index_enable);
311-
GetTopic_P(state_topic, CMND, key_topic, value_template); // State of button is sent as CMND TOGGLE
312-
GetTopic_P(availability_topic, TELE, mqtt_topic, S_LWT);
313-
FindPrefix(state_topic, availability_topic, prefix);
314-
if (Settings.flag3.hass_short_discovery_msg) {
315-
Shorten(&state_topic, prefix);
316-
Shorten(&availability_topic, prefix);
317-
}
318-
snprintf_P(mqtt_data, sizeof(mqtt_data), Settings.flag3.hass_short_discovery_msg?HASS_DISCOVER_BUTTON_SHORT:HASS_DISCOVER_BUTTON,
319-
name, state_topic, Settings.state_text[2], availability_topic);
320-
321-
if (Settings.flag3.hass_short_discovery_msg)
322-
snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_TOPIC_PREFIX, mqtt_data, prefix);
323-
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
378+
// Check if MQTT message will be ON/OFF or TOGGLE
379+
if (!strcmp(mqtt_topic, key_topic) || !strcmp(Settings.mqtt_grptopic, key_topic))
380+
{
381+
toggle = 0;
324382
}
325-
MqttPublish(stopic, true);
383+
384+
HAssAnnounceButtonSwitch(button_index, key_topic, button_present, 1, toggle);
326385
}
327386
}
328387
}
@@ -440,9 +499,10 @@ void HAssDiscovery(uint8_t mode)
440499
HAssAnnounceRelayLight();
441500

442501
// Send info about buttons
443-
HAssAnnounceButton();
502+
HAssAnnounceButtons();
444503

445-
// TODO: Send info about switches
504+
// Send info about switches
505+
HAssAnnounceSwitches();
446506

447507
// Send info about sensors
448508
HAssAnnounceSensors();

0 commit comments

Comments
 (0)