Merge pull request #4531 from emontnemery/hass_announce_switch

MQTT Discovery - Announce switches
This commit is contained in:
Theo Arends 2018-12-06 11:02:40 +01:00 committed by GitHub
commit 9471163d86
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 109 additions and 48 deletions

View File

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

View File

@ -33,16 +33,21 @@ const char HASS_DISCOVER_RELAY[] PROGMEM =
"\"payload_available\":\"" D_ONLINE "\"," // Online "\"payload_available\":\"" D_ONLINE "\"," // Online
"\"payload_not_available\":\"" D_OFFLINE "\""; // Offline "\"payload_not_available\":\"" D_OFFLINE "\""; // Offline
const char HASS_DISCOVER_BUTTON[] PROGMEM = const char HASS_DISCOVER_BUTTON_SWITCH[] PROGMEM =
"{\"name\":\"%s\"," // dualr2 1 BTN "{\"name\":\"%s\"," // dualr2 1 BTN
"\"state_topic\":\"%s\"," // cmnd/dualr2/POWER (implies "\"optimistic\":\"false\",") "\"state_topic\":\"%s\"," // cmnd/dualr2/POWER (implies "\"optimistic\":\"false\",")
// "\"value_template\":\"{{value_json.%s}}\"," // POWER2 // "\"value_template\":\"{{value_json.%s}}\"," // POWER2
"\"payload_on\":\"%s\"," // TOGGLE "\"payload_on\":\"%s\"," // TOGGLE / ON
// "\"optimistic\":\"false\"," // false is Hass default when state_topic is set // "\"optimistic\":\"false\"," // false is Hass default when state_topic is set
"\"availability_topic\":\"%s\"," // tele/dualr2/LWT "\"availability_topic\":\"%s\"," // tele/dualr2/LWT
"\"payload_available\":\"" D_ONLINE "\"," // Online "\"payload_available\":\"" D_ONLINE "\"," // Online
"\"payload_not_available\":\"" D_OFFLINE "\"," // Offline "\"payload_not_available\":\"" D_OFFLINE "\""; // Offline
"\"force_update\":true";
const char HASS_DISCOVER_BUTTON_SWITCH_TOGGLE[] PROGMEM =
"%s,\"force_update\":true";
const char HASS_DISCOVER_BUTTON_SWITCH_ONOFF[] PROGMEM =
"%s,\"payload_off\":\"%s\""; // OFF
const char HASS_DISCOVER_LIGHT_DIMMER[] PROGMEM = const char HASS_DISCOVER_LIGHT_DIMMER[] PROGMEM =
"%s,\"brightness_command_topic\":\"%s\"," // cmnd/led2/Dimmer "%s,\"brightness_command_topic\":\"%s\"," // cmnd/led2/Dimmer
@ -92,7 +97,7 @@ const char HASS_DISCOVER_RELAY_SHORT[] PROGMEM =
"\"pl_avail\":\"" D_ONLINE "\"," // Online "\"pl_avail\":\"" D_ONLINE "\"," // Online
"\"pl_not_avail\":\"" D_OFFLINE "\""; // Offline "\"pl_not_avail\":\"" D_OFFLINE "\""; // Offline
const char HASS_DISCOVER_BUTTON_SHORT[] PROGMEM = const char HASS_DISCOVER_BUTTON_SWITCH_SHORT[] PROGMEM =
"{\"name\":\"%s\"," // dualr2 1 BTN "{\"name\":\"%s\"," // dualr2 1 BTN
"\"stat_t\":\"%s\"," // cmnd/dualr2/POWER (implies "\"optimistic\":\"false\",") "\"stat_t\":\"%s\"," // cmnd/dualr2/POWER (implies "\"optimistic\":\"false\",")
// "\"value_template\":\"{{value_json.%s}}\"," // POWER2 // "\"value_template\":\"{{value_json.%s}}\"," // POWER2
@ -100,8 +105,14 @@ const char HASS_DISCOVER_BUTTON_SHORT[] PROGMEM =
// "\"optimistic\":\"false\"," // false is Hass default when state_topic is set // "\"optimistic\":\"false\"," // false is Hass default when state_topic is set
"\"avty_t\":\"%s\"," // tele/dualr2/LWT "\"avty_t\":\"%s\"," // tele/dualr2/LWT
"\"pl_avail\":\"" D_ONLINE "\"," // Online "\"pl_avail\":\"" D_ONLINE "\"," // Online
"\"pl_not_avail\":\"" D_OFFLINE "\"," // Offline "\"pl_not_avail\":\"" D_OFFLINE "\""; // Offline
"\"frc_upd\":true";
const char HASS_DISCOVER_BUTTON_SWITCH_TOGGLE_SHORT[] PROGMEM =
"%s,\"frc_upd\":true";
const char HASS_DISCOVER_BUTTON_SWITCH_ONOFF_SHORT[] PROGMEM =
"%s,\"pl_off\":\"%s\""; // OFF
const char HASS_DISCOVER_LIGHT_DIMMER_SHORT[] PROGMEM = const char HASS_DISCOVER_LIGHT_DIMMER_SHORT[] PROGMEM =
"%s,\"bri_cmd_t\":\"%s\"," // cmnd/led2/Dimmer "%s,\"bri_cmd_t\":\"%s\"," // cmnd/led2/Dimmer
@ -266,9 +277,85 @@ void HAssAnnounceRelayLight(void)
} }
} }
void HAssAnnounceButton(void) void HAssAnnounceButtonSwitch(byte device, char* topic, byte present, byte key, byte toggle)
{ {
char stopic[TOPSZ];
char sidx[8]; char sidx[8];
mqtt_data[0] = '\0'; // Clear retained message
// Clear or Set topic
snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/binary_sensor/%s_%s_%d/config"),
topic, key?"BTN":"SW",device+1);
if (Settings.flag.hass_discovery && present) {
char name[33];
char value_template[33];
char _state_topic[TOPSZ];
char _availability_topic[TOPSZ];
char prefix[TOPSZ];
char *state_topic = _state_topic;
char *availability_topic = _availability_topic;
if (device+1 > MAX_FRIENDLYNAMES) {
snprintf_P(name, sizeof(name), PSTR("%s %s %d"), Settings.friendlyname[0], key?"BTN":"SW", device+1);
} else {
snprintf_P(name, sizeof(name), PSTR("%s %s"), Settings.friendlyname[device], key?"BTN":"SW");
}
GetPowerDevice(value_template, device+1, sizeof(value_template), Settings.flag.device_index_enable);
GetTopic_P(state_topic, CMND, topic, value_template); // State of button is sent as CMND TOGGLE, state of switch is sent as ON/OFF
GetTopic_P(availability_topic, TELE, mqtt_topic, S_LWT);
FindPrefix(state_topic, availability_topic, prefix);
if (Settings.flag3.hass_short_discovery_msg) {
Shorten(&state_topic, prefix);
Shorten(&availability_topic, prefix);
}
snprintf_P(mqtt_data, sizeof(mqtt_data), Settings.flag3.hass_short_discovery_msg?HASS_DISCOVER_BUTTON_SWITCH_SHORT:HASS_DISCOVER_BUTTON_SWITCH,
name, state_topic, Settings.state_text[toggle?2:1], availability_topic);
if (toggle) snprintf_P(mqtt_data, sizeof(mqtt_data),
Settings.flag3.hass_short_discovery_msg?HASS_DISCOVER_BUTTON_SWITCH_TOGGLE_SHORT:HASS_DISCOVER_BUTTON_SWITCH_TOGGLE,
mqtt_data);
else snprintf_P(mqtt_data, sizeof(mqtt_data),
Settings.flag3.hass_short_discovery_msg?HASS_DISCOVER_BUTTON_SWITCH_ONOFF_SHORT:HASS_DISCOVER_BUTTON_SWITCH_ONOFF,
mqtt_data, Settings.state_text[0]);
if (Settings.flag3.hass_short_discovery_msg)
snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_TOPIC_PREFIX, mqtt_data, prefix);
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
}
MqttPublish(stopic, true);
}
void HAssAnnounceSwitches(void)
{
char sw_topic[sizeof(Settings.switch_topic)];
// Send info about buttons
char *tmp = Settings.switch_topic;
Format(sw_topic, tmp, sizeof(sw_topic));
if ((strlen(sw_topic) != 0) && strcmp(sw_topic, "0")) {
for (byte switch_index = 0; switch_index < MAX_SWITCHES; switch_index++) {
byte switch_present = 0;
byte toggle = 1;
if ((pin[GPIO_SWT1 + switch_index] < 99) || (pin[GPIO_SWT1_NP + switch_index] < 99)) {
switch_present = 1;
}
// Check if MQTT message will be ON/OFF or TOGGLE
if (Settings.switchmode[switch_index] == FOLLOW || Settings.switchmode[switch_index] == FOLLOW_INV ||
!strcmp(mqtt_topic, sw_topic) || !strcmp(Settings.mqtt_grptopic, sw_topic))
{
toggle = 0;
}
HAssAnnounceButtonSwitch(switch_index, sw_topic, switch_present, 0, toggle);
}
}
}
void HAssAnnounceButtons(void)
{
char stopic[TOPSZ]; char stopic[TOPSZ];
char key_topic[sizeof(Settings.button_topic)]; char key_topic[sizeof(Settings.button_topic)];
@ -277,52 +364,24 @@ void HAssAnnounceButton(void)
Format(key_topic, tmp, sizeof(key_topic)); Format(key_topic, tmp, sizeof(key_topic));
if ((strlen(key_topic) != 0) && strcmp(key_topic, "0")) { if ((strlen(key_topic) != 0) && strcmp(key_topic, "0")) {
for (byte button_index = 0; button_index < MAX_KEYS; button_index++) { for (byte button_index = 0; button_index < MAX_KEYS; button_index++) {
uint8_t button_present = 0; byte button_present = 0;
byte toggle = 1;
if (!button_index && ((SONOFF_DUAL == Settings.module) || (CH4 == Settings.module))) { if (!button_index && ((SONOFF_DUAL == Settings.module) || (CH4 == Settings.module))) {
button_present = 1; button_present = 1;
} else { } else {
if (pin[GPIO_KEY1 + button_index] < 99) { if ((pin[GPIO_KEY1 + button_index] < 99) || (pin[GPIO_KEY1_NP + button_index] < 99)) {
button_present = 1; button_present = 1;
} }
} }
mqtt_data[0] = '\0'; // Clear retained message // Check if MQTT message will be ON/OFF or TOGGLE
if (!strcmp(mqtt_topic, key_topic) || !strcmp(Settings.mqtt_grptopic, key_topic))
// Clear or Set topic {
snprintf_P(sidx, sizeof(sidx), PSTR("_%d"), button_index+1); toggle = 0;
snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/%s/%s%s/config"), "binary_sensor", key_topic, sidx);
if (Settings.flag.hass_discovery && button_present) {
char name[33];
char value_template[33];
char _state_topic[TOPSZ];
char _availability_topic[TOPSZ];
char prefix[TOPSZ];
char *state_topic = _state_topic;
char *availability_topic = _availability_topic;
if (button_index+1 > MAX_FRIENDLYNAMES) {
snprintf_P(name, sizeof(name), PSTR("%s %d BTN"), Settings.friendlyname[0], button_index+1);
} else {
snprintf_P(name, sizeof(name), PSTR("%s BTN"), Settings.friendlyname[button_index]);
}
GetPowerDevice(value_template, button_index+1, sizeof(value_template), Settings.flag.device_index_enable);
GetTopic_P(state_topic, CMND, key_topic, value_template); // State of button is sent as CMND TOGGLE
GetTopic_P(availability_topic, TELE, mqtt_topic, S_LWT);
FindPrefix(state_topic, availability_topic, prefix);
if (Settings.flag3.hass_short_discovery_msg) {
Shorten(&state_topic, prefix);
Shorten(&availability_topic, prefix);
}
snprintf_P(mqtt_data, sizeof(mqtt_data), Settings.flag3.hass_short_discovery_msg?HASS_DISCOVER_BUTTON_SHORT:HASS_DISCOVER_BUTTON,
name, state_topic, Settings.state_text[2], availability_topic);
if (Settings.flag3.hass_short_discovery_msg)
snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_TOPIC_PREFIX, mqtt_data, prefix);
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
} }
MqttPublish(stopic, true);
HAssAnnounceButtonSwitch(button_index, key_topic, button_present, 1, toggle);
} }
} }
} }
@ -440,9 +499,10 @@ void HAssDiscovery(uint8_t mode)
HAssAnnounceRelayLight(); HAssAnnounceRelayLight();
// Send info about buttons // Send info about buttons
HAssAnnounceButton(); HAssAnnounceButtons();
// TODO: Send info about switches // Send info about switches
HAssAnnounceSwitches();
// Send info about sensors // Send info about sensors
HAssAnnounceSensors(); HAssAnnounceSensors();