espurna icon indicating copy to clipboard operation
espurna copied to clipboard

MQTT report setting for buttons: send action events, all events or state

Open mcspr opened this issue 5 years ago • 7 comments

ref #1747

@skyynet I though a bit about eventsensor for this, but it might be a bad match due to hardware limitations and noise (i think you pretty much required to have hardware filtering for the digital pin signal)

Instead, what about an option to send button pressed state instead of event, bypassing event mapping and directly giving user the button state?

edit: ...but I think this needs to be per-button instead of a global to be more flexible done! current gcc version supports binary literals, so it is pretty easy to specify bitmask directly as int

Deprecate BUTTON_MQTT_SEND_ALL_EVENTS New defines are BUTTON_MQTT_MASK_EVENTS and BUTTON_MQTT_MASK_PRESSED (with runtime btnMaskEvents and btnMaskPressed)

  • BUTTON_MQTT_MASK_PRESSED bitset to specify which buttons should send pressed() status to mqtt instead of events. For example with 3 buttons, it should be 0b11000000 to make BUTTON1 and BUTTON2 report to MQTT. BUTTON3 will still handle events
  • BUTTON_MQTT_MASK_EVENTS bitset to specify which buttons should ignore NONE action and still send event to mqtt. BUTTON_MQTT_MASK_PRESSED overrides it.

mcspr avatar Jun 11 '19 17:06 mcspr

Per definitions configuration, button limit is 8 (=> uint8_t as mask makes sense) And some useful things for container values:

  • uint8_t value{DEFINITION}; instead of uint8_t value = DEFINITION; will trigger compilation error instead of just a mere warning.
  • Based on v2 limits definition, BUTTONS_MAX is added. One wordy solution to this is to use container type as reference: std::numeric_limits<decltype(_button_mqtt_mask_events)>::digits would result in 8 for uint8_t

mcspr avatar Jun 13 '19 10:06 mcspr

Is there currently any way I can use the mqtt reporting of a button state whose BUTTON_ACTION is set to NONE? I have a relay bound to switch#0 and use PRESSED as TOGGLE and also LONG CLICK for OFF. All others are set to NONE I use the LONG CLICK mqtt state 4 with openHAB to put the light into a different state using rules within openHAB.

I'd like to be able to use the DOUBLE CLICK state 3 or other states to carry out other functions in openHAB depending on the mqtt state of that same button, without operating the bound relay.

davebuk avatar Apr 05 '20 18:04 davebuk

Is there currently any way I can use the mqtt reporting of a button state whose BUTTON_ACTION is set to NONE?

See BUTTON_MQTT_SEND_ALL_EVENTS flag (default off)? I have changed it a bit in the #2162 so it also checks btnMqttSendAll<button#> key (as boolean 1 or 0) to modify behaviour for a single button. After setting to 1 it should always send button event, even without any action attached.

mcspr avatar Apr 05 '20 23:04 mcspr

Thanks. I thought BUTTON_MQTT_SEND_ALL_EVENTS was already default to ON. I'll test.

davebuk avatar Apr 06 '20 07:04 davebuk

That all works. I did have one issue as I had set Click repeat delay in the webUI general section to 0 so accidental presses stop resets or AP mode. I've had to set it to 500ms to get the double/triple clicks to work.

Can Click repeat delay be defined per button at build to override the webUI setting?

davebuk avatar Apr 06 '20 10:04 davebuk

I've yet to add this to config list in the Wiki: https://github.com/xoseperez/espurna/blob/e2e0409c5962e4a90ec6632f8636ad88d7841db3/code/espurna/button.ino#L581-L596 btnRepDel<#index> key can be used for specific button. It will cancel out what WebUI sets, which is global default value.

mcspr avatar Apr 06 '20 12:04 mcspr

I was mistaken about the order above. To actually do that:

diff --git a/code/espurna/button.ino b/code/espurna/button.ino
index ff311352..7f5b7796 100644
--- a/code/espurna/button.ino
+++ b/code/espurna/button.ino
@@ -490,7 +490,7 @@ void _buttonConfigure() {
 // TODO: compatibility proxy, fetch global key before indexed
 template<typename T>
 unsigned long _buttonGetSetting(const char* key, unsigned char index, T default_value) {
-    return getSetting(key, getSetting({key, index}, default_value));
+    return getSetting({key, index}, getSetting(key, default_value));
 }

Without the patch btnRepDel overrides every btnRepDel0, btnRepDel1 etc., btnRepDel0 read second, then hard-coded value. With the patch btnRepDel0 is read first, then btnRepDel, then hard-coded value.

mcspr avatar Apr 06 '20 14:04 mcspr