Elektroda.com
Elektroda.com
X
Elektroda.com

OpenBeken Command use case -a 'menu' using one button and one LED for 5 relays

btsimonh 1200 15
  • Using commands with MQTT and NodeRed to operate a multi-relay unit from a single button

    This example uses a combination of event handlers in OpenBeken to send button presses to NodeRed, and a NodeRed node to track the button presses and flash a single LED on the device to provide a simple 'menu' of operations on the device.

    The intent is to flash an LED for the number of flashes representing how many times the button has been pressed as feedback to the user to know which relay they will toggle by a double press.

    As the LED flashing is done over MQTT by NodeRed, the result is not perfect, but perfectly useable.

    The device is a Calex power strip with 5 'relays' (4 power sockets and 1 controlled USB outlet). It has two LEDs and a single button.

    The configuration is:
    P6 Rel 5
    P7 Rel 2
    P8 Rel 3
    P9 Rel 1
    P10 LED 6
    P14 Btn 8
    P24 LED 7
    P26 Rel 4

    Note how I have separated the button on channel 8, so that it has no default action.


    Commands to issue to OpenBeken:

    Buttons provide the events OnClick, OnDblClick, OnToggle, OnHold - but these are published against PIN numbers.

    In my case, my single button is on pin 14, and I want to publish the button presses to MQTT. Publishing to MQTT can be done with the command `publish <topic> <value>` which will result in `<value>` being sent to the topic `<devicename>/<topic>/get`.

    I issued these commands to the OpenBeken command line:

    Code:
    addEventHandler OnClick 14 publish button click
    
    addEventHandler OnDblClick 14 publish button dblclick


    Then, in NodeRed, subscribe to
    Code:
    <device>/#
    to receive the MQTT which will be
    Code:
    <device>/button/get click
    
    <device>/button/get dblclick


    We also need to capture the current relay values, which look like
    Code:
    <device>/<channel>/get <value 0|1>



    Once tested, the commands can be run at boot by adding this startup command line in `Change Startup Command Text`:

    Code:
    backlog addEventHandler OnClick 14 publish button click; addEventHandler OnDblClick 14 publish button dblclick



    Controlling the LED



    I chose to use the LED on channel 6 as the feedback to the 'menu' state. To control this over MQTT, we send
    Code:
    <device>/6/set <value 0|1>


    NodeRed flow

    The simple flow in NodeRed looks like this:

    OpenBeken Command use case -a 'menu' using one button and one LED for 5 relays

    The 200msTick inject sends an empty payload on topic 'tick' every 200ms to operate our LED flash logic.

    Button presses are received and acted upon. Each time the OnClick event is received, a variable context.selected is incremented, mod 6 (so it takes values of 0-5). Each time a tick is received, a variable context.counter is incremented mod (7*2) (so range 0-13). If context.selected is non-zero and (context.selected < context.counter/2) the led is turned on if !(context.counter & 1), else the led is turned off. So, the led flashes for the count of context.selected, with a flash period of 2 x 200ms, and overall period of 14 x 200ms.

    Relay set/get MQTT packets are used to know the current state, and if dblclick is received and context.selected != 0, then the relevant relay is toggled.


    Content of CalexButton function node:

    Code: javascript
    Log in, to see the code

    Cool? Ranking DIY
    Can you write similar article? Send message to me and you will get SD card 64GB.
    About Author
    btsimonh
    Level 11  
    Offline 
    btsimonh wrote 63 posts with rating 9, helped 1 times. Been with us since 2022 year.
  • #2
    ferbulous
    Level 13  
    Hi, thanks for the instructions with node red.
    Is it possible to configure the actions for the buttons press that triggers the led directly on the device similarly to tasmota rules?
  • #3
    btsimonh
    Level 11  
    I don't think so at the moment, although it may be fun to try!.
    I was thinking that we could use unused channel values as variables.
    One thing I'm not sure about is if the 'regular' commands can be sub-second triggered (for the 200ms pulse).
  • #4
    p.kaczmarek2
    Level 28  
    Very nice mechanism, @btsimonh . @ferbulous It would indeed not be possible just in OpenBeken in the current state of things, but my scripting addon is almost ready and will be released soon. It will be more user-friendly than Tasmota Rules in my opinion. It will/is designed to integrate flawlessly into the existing system and fit the needs of OBK.
  • #5
    ferbulous
    Level 13  
    @btsimonh hi, I wanna use this for custom action for lights thru nodered (eg single press = toggle, double press = change temp, long = dim)
    How can I set the relay wired to the wifi bulbs as always on? In tasmota there's 'OUTPUT HIGH' for the pin assignment
    Also, is there an example for turning off/on the relay from the button switch if homeassistant/mqtt broker is offline?
  • #6
    p.kaczmarek2
    Level 28  
    Hello @ferbulous , the OUTPUT HIGH is a good idea so I have added it for you:
    https://github.com/openshwprojects/OpenBK7231...mmit/b62d45e7d29246a9b4714ce1208d750915d0ed7e
    NOTE: Please test, but it should be ok.

    "Also, is there an example for turning off/on the relay from the button switch if homeassistant/mqtt broker is offline?"
    Well, all you have to do is set the Relay (or Relay_n, or LED) to the same channel as a Button, and pressing button will toggle the Relay...
    You can also use "toggleChannelOnToggle" - then a state change (not a press) on that pin will toggle relay.
    You can also use "DigitalInput" - then the relay will mimic the state on said input.
  • #7
    ferbulous
    Level 13  
    p.kaczmarek2 wrote:
    https://github.com/openshwprojects/OpenBK7231...mmit/b62d45e7d29246a9b4714ce1208d750915d0ed7e
    NOTE: Please test, but it should be ok.

    Thanks for adding this

    p.kaczmarek2 wrote:
    Well, all you have to do is set the Relay (or Relay_n, or LED) to the same channel as a Button, and pressing button will toggle the Relay...
    You can also use "toggleChannelOnToggle" - then a state change (not a press) on that pin will toggle relay.
    You can also use "DigitalInput" - then the relay will mimic the state on said input.


    Following @btsimonh instructions , i assigned different button number for the pin so it doesn't trigger the relay and sends mqtt command
    Device is 4 gang button switch:
    Button 2 (P16) -> Button 5
    Relay 2 (P7)

    Code:

    backlog addEventHandler OnClick 16 publish button click; addEventHandler OnDblClick 16 publish button dblclick; addEventHandler OnHold 16 publish button Hold


    How do I add 'mqtt offline' condition for button 2 to toggle on/off relay 2?
  • #8
    p.kaczmarek2
    Level 28  
    @ferbulous unless I'm much mistaken, you want to have a fallback behaviour in case that MQTT is offline. You will need a conditional for that. I have a simple idea how I can handle it, please wait at most 24 hours and remind me if I forget. I will add a simple conditional command (yet a very flexible one) that will allow you to choose one of two options, depending on a condition result.
  • #9
    p.kaczmarek2
    Level 28  
    @ferbulous UPDATE - I'm working on it
    Code:

    alias mybri backlog led_dimmer 100; led_enableAll
    alias mydrk backlog led_dimmer 10; led_enableAll
    if MQTTOn then mybri else mydrk

    You will be able to set an alias for an arbitrary command name (that is not yet in use) and then plug it into the "if" command which will accept multiple conditionals and run only one of two specified aliases.
    Of course, you will also be able to type "mybri" or "mydrk" directly in command line, aliases are global.
  • #10
    ferbulous
    Level 13  
    p.kaczmarek2 wrote:
    You will be able to set an alias for an arbitrary command name (that is not yet in use) and then plug it into the "if" command which will accept multiple conditionals and run only one of two specified aliases.
    Of course, you will also be able to type "mybri" or "mydrk" directly in command line, aliases are global.


    Noted, thanks for the example. I can think of 2 approach for this 'detached' mode

    1)
    P7 - OUTPUT HIGH
    P16 - Button 2
    Using OUTPUT HIGH for P7, how can i set in the command for P16 (Button 2) to toggle on/off P7 if mqtt goes offline?

    2)
    P7 - Relay 2
    P16 - Button 5
    Not using OUTPUT HIGH for P7, but setting channel 2 (relay 2, assuming this is correct) to 1 at startup.
    OpenBeken Command use case -a 'menu' using one button and one LED for 5 relays
    P16 - Button 2 set to Button 5 so it doesn't toggle relay 2.
    Can I still have Button 5 to toggle relay 2 when MQTT is offline?
  • #11
    p.kaczmarek2
    Level 28  
    Wait, editing.
    EDIT: From a brief glance at things, it seems that you really could use a "MQTT Connected" and "MQTT Disconnected" events. They are not present in the code yet, but I will look into it.

    That's because... because if you set to "AlwaysHigh" then you can't obviously change it's value later... of course you could change-back the pin role to different one through a script, but then you'd again need to set 'AlwaysHigh' when MQTT is again available.

    Hmm

    PS: Not directly related to question, but here is a secondary syntax for if:
    Code:

       if MQTTOn then "backlog led_dimmer 100; led_enableAll" else "backlog led_dimmer 10; led_enableAll"


    EDIT: @ferbulous I didn't have time to go through all the logic so far but here is a MQTT event. I have just added that one for you:
    Code:

    addEventHandler MQTTState 0 setChannel 1 0
    addEventHandler MQTTState 1 setChannel 1 1

    From now on, MQTTState event with argument 0 is thrown when MQTT becomes offline (due to disconnect or an error) and MQTTState event with argument 1 is thrown when MQTT connects correctly.
    NOTE: As we have spoken before, there might be a certain delay before MQTT realizes that HA server has died. It's not yet addressed.
  • #12
    ferbulous
    Level 13  
    p.kaczmarek2 wrote:
    That's because... because if you set to "AlwaysHigh" then you can't obviously change it's value later... of course you could change-back the pin role to different one through a script, but then you'd again need to set 'AlwaysHigh' when MQTT is again available.


    I see, for option (1) & (2) would require a script to change the pin assignment when it's offline.

    p.kaczmarek2 wrote:
    if MQTTOn then "backlog led_dimmer 100; led_enableAll" else "backlog led_dimmer 10; led_enableAll"

    Is there list of actions available in the command other than led_dimmer? i haven't explored much on this

    Added after 31 [minutes]:

    p.kaczmarek2 wrote:
    addEventHandler MQTTState 0 setChannel 1 0
    addEventHandler MQTTState 1 setChannel 1 1

    From now on, MQTTState event with argument 0 is thrown when MQTT becomes offline (due to disconnect or an error) and MQTTState event with argument 1 is thrown when MQTT connects correctly.

    Thanks for adding this, is there much difference between MQTTState 1 and MQTTOn?
    From what I understand when mqtt is offline, this would turn off relay 1

    Trying to figure out a better logic for this as well
    Could I toggle a specific relay from button press of pin 16? Something like..
    Code:
    addEventHandler MQTTState 0 addEventHandler OnClick 16 toggleChannel 2

    The command use is definitely wrong, but you get my idea
  • #13
    ferbulous
    Level 13  
    @p.kaczmarek2 I think I've got it working now for the detached mode & fallback to normal relay when homeassistant/mqtt offline

    Code:
    backlog addEventHandler OnClick 16 publish button click; 
    
    addEventHandler OnDblClick 16 publish button dblclick;
    addEventHandler OnHold 16 publish button Hold; #sends mqtt payload to be used in node red for custom light actions
    addEventHandler MQTTState 1 setPinRole 7 AlwaysHigh; #set pin7 to alwayshigh when mqtt online for the wifi bulbs to stay online
    addEventHandler MQTTState 0 setPinRole 7 Rel;  #set pin 7 to normal relay when offline, allows button 2(pin 16) to toggle it


    Is it ok though to keep switching the pin role in the long run?
    Also, is it possible to add more than double clicks? In tasmota there's 3x, 4x & 5x clicks.
    I never used 4x & 5x but I do only use 3x press action if I ever need to change/cycle the colors on the lights
  • #14
    p.kaczmarek2
    Level 28  
    Wow, this is very good job, @ferbulous ! I am happy that you managed to get it running. Is there anything else I can help you with?
    (I remember that I still have on N crash report from you pending)
    ferbulous wrote:

    Is it ok though to keep switching the pin role in the long run?

    Very good question. Doing a switch of a pin role does a flash write,e and BK7231 is EN25QH16B according to our research.
    EN25QH16B is able to sustain a minimum of 100K program/erase cycles on each sector or block, which means that you should be able to write the configuration at least 100 000 times before the flash wears out.
    All the remaining is maths. If you assume that your MQTT discconnects 10 times a day, you get 10 000 days which is about 27 years and remember, it's a worse case scenario, flash can endure more than that.
    So it's up to you to decide whether it's right or wrong.
    PS: The 'remember last state' mechanism is using a different flash system, the one designed to use multiple sectors in a round-robin manner, so don't worry about "remembering last state" and about boot counter. For them, one could say that the 100K writes does not apply (they do, but they use multiple blocks for that so the flash cycles are pooled).

    ferbulous wrote:

    Also, is it possible to add more than double clicks? In tasmota there's 3x, 4x & 5x clicks.

    It has never occurred to me that one might need a 3x click, but I will look into that.
    Few days ago I added customizable button times:
    https://github.com/openshwprojects/OpenBK7231T_App/issues/341
  • #15
    ferbulous
    Level 13  
    p.kaczmarek2 wrote:
    (I remember that I still have on N crash report from you pending)

    I just tested with T device, and same crash issue also occurs it seems. I wonder if there's anything else I need to enable in the settings to prevent this crash.
    For now, I'm only controlling openbkt device from tasmota (in the same group) only in ha dashboard.

    p.kaczmarek2 wrote:
    All the remaining is maths. If you assume that your MQTT discconnects 10 times a day, you get 10 000 days which is about 27 years and remember, it's a worse case scenario, flash can endure more than that.

    Thanks for the estimation, looks like I won't to have to worry about it wearing out anytime soon.
    Is there a WIFI off event? This can be pretty useful for device groups if the router itself goes offline

    p.kaczmarek2 wrote:
    It has never occurred to me that one might need a 3x click, but I will look into that.
    Few days ago I added customizable button times:
    https://github.com/openshwprojects/OpenBK7231T_App/issues/341

    Thanks! Looking forward to that
  • #16
    p.kaczmarek2
    Level 28  
    T device LWIP library has been updated today and will be merged soon. Please check later today or tomorrow. It would be good to know if it changes anything, but new LWIP library should handle even 20 MQTT publish calls per second.

    I think I can add a WiFiOff event, but DGR would obviously stop working in the case of router going offline.