Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MQTT -> Publish button status #1747

Closed
skyynet opened this issue May 31, 2019 · 15 comments
Closed

MQTT -> Publish button status #1747

skyynet opened this issue May 31, 2019 · 15 comments

Comments

@skyynet
Copy link

skyynet commented May 31, 2019

I publish from my Sonoff Dual R2 to my Mosquitto Broker on my Synology.

When I read /home/relay/0 any time I get the current state (0 or 1). This also applies to relay/1.

When I read /home/button/0 I get no result. I see its status is published but would like to read it any time using phpMQTT.

So generally I'd like to see button/0 and button/1 behave like relay/0 and relay/1.

Is this something I can configure somewhere, a bug or a feature request?

In hardware.h I defined:

#elif defined(ITEAD_SONOFF_DUAL_R2)

    #define MANUFACTURER        "ITEAD"
    #define DEVICE              "SONOFF_DUAL_R2"

    // Buttons
    #define BUTTON1_PIN         0       // Button 0 on header
    #define BUTTON2_PIN         9       // Button 1 on header
    #define BUTTON3_PIN         10      // Physical button
    #define BUTTON1_RELAY       0
    #define BUTTON2_RELAY       0
    #define BUTTON3_RELAY       1
    #define BUTTON1_MODE        BUTTON_SWITCH | BUTTON_SET_PULLUP | BUTTON_DEFAULT_HIGH
    #define BUTTON2_MODE        BUTTON_SWITCH | BUTTON_SET_PULLUP | BUTTON_DEFAULT_HIGH
    #define BUTTON3_MODE        BUTTON_PUSHBUTTON | BUTTON_DEFAULT_HIGH

    // Relays
    #define RELAY1_PIN          12
    #define RELAY2_PIN          5
    #define RELAY1_TYPE         RELAY_TYPE_NORMAL
    #define RELAY2_TYPE         RELAY_TYPE_NORMAL

    // LEDs
    #define LED1_PIN            13
    #define LED1_PIN_INVERSE    1
@mcspr
Copy link
Collaborator

mcspr commented May 31, 2019

per #608 i think buttons need to be PUSHBUTTON (edit, sorry!). only then we can reliably say about the current state and enable retained flag for mqtt messages

also a reminder about #619 ?
*aaalso, see #844 regarding button states, maybe double pin events sensor is a better match

@skyynet
Copy link
Author

skyynet commented Jun 1, 2019

Thanks for the hint. Unfortunately this doesn't help. Subscribing to relay/0 or 1 gives me immediately status "0" indicating the relay is off. Subscribing to button/0 or 1 gives me nothing. When connecting the according pin with gnd it gives me 2,3 or 4.

I would really like to get state "0" for open buttons and something else for closed ones.

@mcspr
Copy link
Collaborator

mcspr commented Jun 2, 2019

Right, but that can only happen when espurna sends out mqtt with retain flag. That way, mqtt broker saves the last published message and will send it out to every subscriber on initial connection, until the device (or something else) sends something different or deletes it.

Note that 3c2b201 did explicitly remove this behaviour:

mqttSend(MQTT_TOPIC_BUTTON, id, payload, false, false); // 1st bool = force, 2nd = retain

We can add a setting, maybe? btnRetain, BUTTON_MQTT_RETAIN define, 0 or 1, to control this

And idk if you'd want that, but based on config above buttons will still change relay state. When button action is set to NONE, to still receive button events BUTTON_MQTT_SEND_ALL_EVENTS needs to be 1 / true

if (action != BUTTON_MODE_NONE || BUTTON_MQTT_SEND_ALL_EVENTS) {
buttonMQTT(id, event);
}

@skyynet
Copy link
Author

skyynet commented Jun 2, 2019

Thanks for the info. Now I know that it's nothing i oversaw but "works as designed".
IMHO it's not intuitive to have the relays send as "retain" and the buttons not.
This might be a pro or con depending on ones projects.

I use a Sonoff Dual R2 to open and close slides on my grass mower's garage. I intend to use the two additional buttons to sense the mower in the garage and the slides being opened or closed.

Thus, inventing a configurable retain feature for the buttons (and relays) would be great.

I followed your hint regarding button.ino and changed
mqttSend(MQTT_TOPIC_BUTTON, id, payload, false, true); // 1st bool = force, 2nd = retain
Unfortunately this didn't help. I suppose mqttSend somewhere is called with the 2nd parameter set to false overwriting the default behaviour set in buttons.ino. Any additional hint?

Thanks for your big help and maybe a configurable "retain" might make it into one of the next versions.

Oh, and I think I configured the buttons not to switch the relays in defaults.h. At least they don't currently switch but only report state.

@mcspr
Copy link
Collaborator

mcspr commented Jun 8, 2019

mini reminder: github will not send notifications for edits! i just accidentally noticed this in gitter window

That should've worked.

With small code snippet in terminal setup():

terminalRegisterCommand(F("TEST"), [](Embedis* e) {
    mqttSend(MQTT_TOPIC_BUTTON, 0, "1", false, true); // send 1 with retain flag
    delay(100);
    mqttSend(MQTT_TOPIC_BUTTON, 0, "2", false, false); // send 2 without retain
});

Running test command on the device while subscribed to the button topic:

$ mosquitto_sub -v -t '+/+/button/0'
ESPURNA-35A259/button/0 1
ESPURNA-35A259/button/0 2
^C
$ mosquitto_sub -v -t '+/+/button/0'
ESPURNA-35A259/button/0 1

@skyynet
Copy link
Author

skyynet commented Jun 9, 2019

Thanks. While I'm not that good in Terminal I checked with MQTT Box on MacOS which supports subscribe & publish to topics.

The code modification has worked so far that when I subscribe to the buttons, I receive an initial
2 (qos : 1, retain : true, cmd : publish, dup : false, topic : /home/garden/mowgli/button/0, messageId : 14, length : 33, Raw payload : 50)

When I connect button with gnd I always receive a 2 with retain:false which is ok.

Unfortunately there is no 0 sent when I disconnect the bridge. I assumed, with BUTTON_MQTT_SEND_ALL_EVENTS this would also be sent.

This is the only thing which prevents me from using MQTT to check the state of the button.
I don't think my usage so uncommon as a lot of people would like to control something and check its state before and afterwards. So implementing it easy configurable into ESPurna would be great.

@mcspr
Copy link
Collaborator

mcspr commented Jun 11, 2019

#define BUTTON_EVENT_NONE 0
#define BUTTON_EVENT_PRESSED 1
#define BUTTON_EVENT_RELEASED 2
#define BUTTON_EVENT_CLICK 2
#define BUTTON_EVENT_DBLCLICK 3
#define BUTTON_EVENT_LNGCLICK 4
#define BUTTON_EVENT_LNGLNGCLICK 5
#define BUTTON_EVENT_TRIPLECLICK 6

If button is configured as PUSHBUTTON, we receive a bunch of events that depend on connection/disconnection count and their longevity, ref the header values above.
I think there is a slight misunderstanding of what 0 actually is. It only happens in this mode and when we do something event mapper does not understand as any other event type
for example: if event 1 received 4 times in a row, we can't map it to anything and send 0 (NONE)

[077427] [BUTTON] Button #0 event 1
[077933] [BUTTON] Button #0 event 2
[079911] [BUTTON] Button #0 event 1
[080143] [BUTTON] Button #0 event 1
[080650] [BUTTON] Button #0 event 3
[081978] [BUTTON] Button #0 event 1
[082262] [BUTTON] Button #0 event 1
[082537] [BUTTON] Button #0 event 1
[082860] [BUTTON] Button #0 event 1
[083368] [BUTTON] Button #0 event 0

And if it is SWITCH, we receive event 2 (BUTTON_EVENT_RELEASED / BUTTON_EVENT_CLICK) when contact is connected or disconnected. So retaining this is of no use.

I do hope I properly understood that the issue here is that we only receive event, not the actual status. We can't exactly avoid event mapper right now (but it is something to maybe change ever slightly), but we can use EventSensor instead of button. See #1771 and code/espurna/config/sensors.h for info about it's configuration. I added specific option when trigger mode is enabled to retain last read pin value.

@skyynet
Copy link
Author

skyynet commented Jun 16, 2019

Thanks for your help. BUTTONS really don't work like I expected them to.
My aim is to have Buttons send their state like 0 for open and 1 for closed and the MQTT Broker retain the last sent status.

I read #1771 and sensors.h but couldn't figure out how to configure this for my purpose.

@mcspr
Copy link
Collaborator

mcspr commented Jun 16, 2019

EventSensor minimal config would be

#define EVENTS_SUPPORT 1
#define EVENTS_PIN <button GPIO>
#define EVENTS_PIN_MODE CHANGE
#define EVENTS_TRIGGER 1

But, as noted in the PR, it can be imprecise for this purpose (within interrupt, digitalRead can sometimes return surprising results. and due to Core limitations and compatibility with Arduino API we are kind of stuck with it)
Which is why I made the #1772, where already existing button handler now can ignore events and just report raw status. Naming might need to change though, to avoid mqtt-only meaning.

@skyynet
Copy link
Author

skyynet commented Jun 22, 2019

I compiled with the above mentioned EventSensor values with EVENTS_PIN set to 9 which should be BUTTON1 on the Sonoff Dual R2. When I subscribe to MQTT I see event being 0. When I connect BUTTON1 with GND nothing happens. Compiling with EVENTS_PIN set to 0 also nothing happens when connecting BUTTON0 with GND.

And idea? Also how do I configure to check for BUTTON1 and BUTTON0?

Thanks.

@mcspr
Copy link
Collaborator

mcspr commented Jun 22, 2019

EVENTS_PIN_MODE needs to be INPUT_PULLUP with some pins (ref button modes that sets it as such)
Have you tried #1772?

@skyynet
Copy link
Author

skyynet commented Jun 22, 2019

That's my not working config:

#define EVENTS_SUPPORT                  1       // Do not build with counter support by default
#define EVENTS_TRIGGER                  1       // 1 to trigger callback on events,
#define EVENTS_PIN                      9       // GPIO to monitor
#define EVENTS_PIN_MODE                 INPUT_PULLUP   // INPUT, INPUT_PULLUP, CHANGE
#define EVENTS_INTERRUPT_MODE           CHANGE  // RISING, FALLING, CHANGE
#define EVENTS_DEBOUNCE                 50      // Do not register events within less than 50 millis

As I'm not good at all in patching source code from github I'll wait for #1772 to be merged into the code. So I haven't tried, yet.

@mcspr
Copy link
Collaborator

mcspr commented Jun 27, 2019

The events sensor "event" is a logical read. So connecting GND would give 0 and 3v3 - 1.

#1772 configuration proposes additional "reporting mode", so that each button can be either sending events or pressed status. I do wonder it bitmasks are needed though and that can just be some global setting like BUTTON_MQTT_SEND = BUTTON_MQTT_SEND_PRESSED, as it was in the 515e660

@stale
Copy link

stale bot commented Aug 26, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Aug 26, 2019
@stale
Copy link

stale bot commented Sep 2, 2019

This issue will be auto-closed because there hasn't been any activity for two months. Feel free to open a new one if you still experience this problem.

@stale stale bot closed this as completed Sep 2, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants