Buttons and switches - xoseperez/espurna GitHub Wiki

This page is about general options you can compile-in into your ESPurna. Predefined board settings can be found in header file espurna/config/hardware.h and will take precedence over command line flags (-DFLAG=VALUE) and any additional configuration in espurna/config/custom.h. It is recommended to define a custom unique board instead of modifying hardware.h directly, either by using custom.h or manually specifying command line flags. See PlatformIO documentation for more information and the comments on top of the custom.h.

Buttons and switches

Headers configuration and run-time settings

Various C preprocessor flags that are used to configure multiple entities are numbered starting from 1. However, internal logging, MQTT & HTTP API, Terminal commands, Settings, etc., reference each entity using zero-based numbering.

For example, when modifying boot mode for the first relay - in headers it is defined as #define RELAY1_BOOT_MODE <flag>, while the equivalent settings command is set relayBoot0 <number>

Buttons

NOTICE!: Since version 1.15.0 BUTTON[1-8]_CONFIG is used instead of BUTTON[1-8]_MODE

ESPurna supports up to 8 buttons connected to various GPIO pins. These buttons are defined using C preprocessor flag BUTTONx_PIN (x being a number from 1 to 8). Some buttons might be onboard, and you might have the option of connecting some additional, depending on the board you are using.

Each button can operate in number of different modes, configured using BUTTONx_CONFIG bitmask.

  • Button type results in a different events set:
    • BUTTON_PUSHBUTTON - connected button is of push-button type, possible events are: pressed, released, double clicked, long clicked and long-long clicked).
    • BUTTON_SWITCH - connected button is actually a flip-switch, reports eithr pressed or released, depending on the BUTTON_DEFAULT_... flag for the default pin state.
  • Default state of the button, used to determine whether it's pressed or released:
    • BUTTON_DEFAULT_LOW (default)
    • BUTTON_DEFAULT_HIGH
    • BUTTON_DEFAULT_BOOT (read at firmware startup)
  • Internal pull-up / pull-down resistors. When not specified, pin is left floating.
    • BUTTON_SET_PULLUP
    • BUTTON_SET_PULLDOWN (WARNING! ESP8266 only supports pull-down on GPIO16, which in turn does not support pull-up)

For example, using the following build flags:

#define BUTTON3_PIN 2
#define BUTTON3_CONFIG BUTTON_PUSHBUTTON | BUTTON_DEFAULT_LOW

Will set up a pushbutton on GPIO2 (externally pulled-down), which will be pressed when it is connected to the VCC.

Or, using the following flags we will set up a switch on GPIO5 (with internal pull-up), which will read the current pin status on boot. Doing that allows us to leave the external switch in any position. In case firmware reboots, we don't trigger the pressed / released event.

#define BUTTON1_PIN 5
#define BUTTON1_CONFIG BUTTON_SWITCH | BUTTON_SET_PULLUP | BUTTON_DEFAULT_BOOT
#define BUTTON1_PRESS BUTTON_ACTION_TOGGLE
#define BUTTON1_RELEASE BUTTON_ACTION_TOGGLE

Providers

Available since version 1.15.0

By default, buttons can only use ESP8266 GPIOs. However, we support additional 'providers' by setting BUTTONx_PROVIDER build flag or changing btnProvX, replacing x with the correct button index and setting it at runtime with the corresponding integer value of the provider:

Build flag Settings key Description
BUTTONx_PROVIDER btnProvX (default: BUTTON_PROVIDER_GPIO)

Provider types

Build flag Settings value Description
BUTTON_PROVIDER_NONE 0 No-op provider type
BUTTON_PROVIDER_GPIO 1 Generic GPIO
BUTTON_PROVIDER_ANALOG 2 Resistor ladder support. For more info, see #2357. Specific analogRead() value that will trigger the button press can be configured via BUTTON#_ANALOG_LEVEL

GPIO provider

Build flag Settings key Description
BUTTONx_PIN_TYPE btnGpioType One of the GPIO_TYPE_x flags (default: GPIO_TYPE_HARDWARE)

Events

As seen in https://github.com/xoseperez/espurna/blob/b289c77021c4d3fcd70feb25ca14178929f31e6c/code/espurna/button.h#L19-L27:

enum class button_event_t {
    None,
    Pressed,
    Released,
    Click,
    DoubleClick,
    LongClick,
    LongLongClick,
    TripleClick
};

To every button event an action can be assigned by setting the corresponding value to the button event define. The following button events are available

#define BUTTONx_PRESS
#define BUTTONx_RELEASE   (specific to switch)
#define BUTTONx_CLICK
#define BUTTONx_DBLCLICK
#define BUTTONx_LNGCLICK
#define BUTTONx_LNGLNGCLICK

Actions

To every event, one of the following actions can be assigned:

Flag Description
BUTTON_ACTION_NONE
BUTTON_ACTION_TOGGLE Toggle relay
BUTTON_ACTION_ON Turn relay ON
BUTTON_ACTION_OFF Turn relay OFF
BUTTON_ACTION_AP Access point mode
BUTTON_ACTION_RESET Reboot the device
BUTTON_ACTION_FACTORY Erase settings and reboot
BUTTON_ACTION_WPS Save new WiFi connection settings via WPS
BUTTON_ACTION_SMART_CONFIG Save new WiFi connection settings via SmartConfig
BUTTON_ACTION_DIM_UP Lights: increase brightness
BUTTON_ACTION_DIM_DOWN Lights: decrease brightness
BUTTON_ACTION_DISPLAY_ON Thermostat: toggle display
BUTTON_ACTION_CUSTOM Custom action (must be implemented by the module / user)

Button 1 has the following defaults:

#define BUTTONx_PRESS           BUTTON_ACTION_NONE
#define BUTTONx_RELEASE         BUTTON_ACTION_NONE
#define BUTTONx_CLICK           BUTTON_ACTION_TOGGLE
#define BUTTONx_DBLCLICK        BUTTON_ACTION_AP
#define BUTTONx_LNGCLICK        BUTTON_ACTION_RESET
#define BUTTONx_LNGLNGCLICK     BUTTON_ACTION_FACTORY

NOTE: If you plan using button1, please make sure you override these settings.

NOTE: You can always test out configuration by setting btnClick0 (CLICK), btnDclk0 (DBLCLICK), btnLLclk0 (LNGLNGCLICK) etc. from runtime with the correct numeric representation of an action.

NOTE: Since version 1.14.2 BUTTON_ACTION_ is used instead of BUTTON_MODE_

Buttons 2 to 8 BUTTONx_CLICK event is set to BUTTON_ACTION_TOGGLE, while every other event is set to BUTTON_ACTION_NONE.

Settings

Settings key Possible values Description
btnProv# Provider ID, see Providers
btnGpio# 0 ... 16 GPIO for the specified provider
btnGpioType# 0 ... 2 GPIO type, when btnProv# is set to GPIO provider
btnMode# 0 for Pushbutton or 1 for Switch (Pushbutton by default)
btnDefVal# 0 for LOW, 1 for HIGH or 2 to set the value at boot from the first status reading
btnPinMode# 0 for INPUT, 1 for INPUT_PULLUP or 2 INPUT_PULLDOWN
btnPress# Action ID, see Actions What happens after the 'Pressed' event
btnRlse# 'Released' event
btnClick# 'Click' event
btnDclk# 'Double-click' event
btnLclk# 'Long-click' event
btnLLclk# 'Looong-click' event
btnTclk# 'Triple-click' event
btnDebDel# Number of milliseconds Timeout between checking the GPIO value
btnRepDel# Number of milliseconds Timeout between repeated presses (used for Double-click and Triple-click)
btnLclkDel# Number of milliseconds Timeout between 'Pressed' and 'Released' to trigger 'Long-click' event
btnLLclkDel# Number of milliseconds Timeout between 'Pressed' and 'Released' to trigger 'Looong-click' event

Settings are loaded on the firmware boot.

Terminal

Command Description
button shows all configured buttons
button <ID> shows n-th button configuration options

MQTT

By default, MQTT client will report the button event only when it has an associated action. The following build flags control this behaviour:

Build flag Description
BUTTONx_MQTT_SEND_ALL_EVENTS
BUTTON_MQTT_SEND_ALL_EVENTS Global setting for every button (unless, overriden by the BUTTONx flag)
BUTTONx_MQTT_RETAIN
BUTTON_MQTT_RETAIN Global setting for every button (unless, overriden by the BUTTONx flag)

Or, to control this at runtime:

Settings key Possible values Description
btnMqttSendAll# 0 or 1 (default 0) Always send button events
btnMqttRetain# 0 or 1 (default 0) Set 'Retain' flag for the MQTT button event message

Relays

ESPurna supports up to 8 connected relays to various GPIO pins. These relays are defined using C preprocessor flag RELAYx_PIN (x being a number from 1 to 8).

For example, relay 1 is connected to GPIO4:

#define RELAY1_PIN        4

Each relay can operate in one of the following modes defined by RELAYx_TYPE:

  • RELAY_TYPE_NORMAL - High-level-trigger, normally open relay.
  • RELAY_TYPE_INVERSE - Either low-level-trigger, or normally closed relay.
  • RELAY_TYPE_LATCHED- Relay is controlled with two normally-low GPIOs, if set GPIO goes up the relay will turn on, if reset GPIO goes up the relay will turn off
  • RELAY_TYPE_LATCHED_INVERSE- Relay is controlled with two normally-high GPIOs, if set GPIO goes down the relay will turn on, if reset GPIO goes down the relay will turn off

#define RELAY1_TYPE RELAY_TYPE_NORMAL defines that relay 1 is RELAY_TYPE_NORMAL

ON and OFF actions can be delayed for a specified time in milliseconds:

  • RELAYx_DELAY_ON (defaults to 0)
  • RELAYx_DELAY_OFF (defaults to 0)

Pulse mode and time can also be set at build time:

  • RELAYx_PULSE_MODE (defaults to RELAY_PULSE_MODE)
  • RELAYx_PULSE_TIME (float, time in seconds. defaults to 0.0)

Settings

Settings key Possible values Description
relayProv# Provider ID, see Providers
relayName# String Name that will be displayed in the WebUI
relayType# 0 ... 3 Relay type, one of RELAY_TYPE_NORMAL, RELAY_TYPE_INVERSE, RELAY_TYPE_LATCHED or RELAY_TYPE_LATCHED_INVERSE
relayGpio# 0 ... 16 GPIO, when relayProv# is set to GPIO provider
relayResetGpio# 0 ... 16 GPIO, when relayProv# is set to GPIO provider and relay type is LATCHED
relayGpioType# 0 ... 2 GPIO type, when relayProv# is set to GPIO provider
relayPulse# 0, 1 or 2
none, off or on
0 / none disables pulse mode. Otherwise, set normal mode to either off or on
relayTime# Time (seconds, hours) Time after which the relay will switch back to the 'normal' mode
relayName# String Name that will be displayed in the WebUI and published to MQTT as under <root>/desc/relay/# topic
relayBoot# 0 (off), 1 (on), 2 (same as before), 3 (opposite from before). 0 (off) by default Relay status at boot
relayDelayOn# time string, milliseconds precision Delay for the specified time before actually turning the relay ON
relayDelayOff# time string, milliseconds precision Delay for the specified time before actually turning the relay OFF
relayDummy 0 ... 32 Consider using relayProv# instead, DEPRECATED Number of virtual / dummy relays without any provider attached
relayDelayInterlock Time (ms) When relay is in SYNC mode, wait for the specified time until the next relay changes status (default: 0)
relayFloodTime Time (seconds) Window for when relay may change it's status (default: 3.0)
relayFloodChanges Number Maximum amount of relay status changes that may happen during the 'flood window' (default: 5)

Unlike build flag, pulse time string can be either be

  • floating-point number of seconds. For example, 0.5 for 500 milliseconds
  • number followed by s (seconds) for integer number of seconds. For example, 60s for 60 seconds
  • number followed by h (hours) for integer number of hours. For example, 2h for 2 hours
  • a combination of both s and h, for example 5h30s for 5 hours and 30 seconds

Terminal

Command Description
relay shows configuration options
relay <ID> shows n-th relay status and configuration options
relay <ID> <STATUS> change relay by ID (n-th relay) to the specified STATUS. Value of STATUS is one of: 1 / on, 0 / off or 2 / toggle
pulse <ID> <TIME> [<TOGGLE>] 'pulse' relay by ID (n-th relay) to the opposite status after TIME. If TOGGLE is omitted, defaults to 1 and relay immediately switches status to an opposite one when command is entered. When TOGGLE is 0, pulse status remains the same and instead will be changed after the timer for the specified TIME value expires.
pulse.timers currently active 'pulse' timers
unlock <ID> remove active lock for the n-th relay
lock <ID> disallow any status changes for the n-th relay
lock <ID> <STATUS> switch n-th relay to STATUS and disallow any further status changes. STATUS is one of: on, off or none

Providers

Available since version 1.15.0

Build flag Settings value Description
RELAY_PROVIDER_NONE none Disabled
RELAY_PROVIDER_DUMMY dummy No-op (virtual)
RELAY_PROVIDER_GPIO gpio (default) Generic GPIO
RELAY_PROVIDER_DUAL dual For SONOFF DUAL, depends on RELAY_PROVIDER_DUAL_SUPPORT
RELAY_PROVIDER_STM stm For generic relays w/ STM companion MCU, depends on RELAY_PROVIDER_STM_SUPPORT
RELAY_PROVIDER_LIGHT_STATE light-state Control lights state, depends on LIGHT_PROVIDER != LIGHT_PROVIDER_NONE
RELAY_PROVIDER_FAN fan Toggle fan between 'off' and configured speed setting, depends on FAN_SUPPORT (currently, IFAN_SUPPORT for ITEAD IFAN2)
RELAY_PROVIDER_LIGHTFOX lightfox For FOXEL Lightfox DUAL (similar to SONOFF DUAL), depends on FOXEL_LIGHTFOX_DUAL
RELAY_PROVIDER_TUYA tuya For TUYA devices with a companion MCU, depends on TUYA_SUPPORT and TUYA_RELAY#_DPID set to a known DP ID number

LEDs

ESPurna supports up to 8 connected LEDs to various GPIO pins. These LEDs are defined using C preprocessor flag LEDx_PIN (x being a number from 1 to 8). Some LEDs might be onboard, and you might have the option of connecting some additional, depending on the board you are using.

See LED Configuration & Modes.

Tasmota templates

As we cannot use templates directly, we need to translate names given by the Tasmota Device Templates Repository (see top right) into something ESPurna configuration can understand.

Template flag ESPurna Build flag Description
<pin> Relay# RELAY#_PIN <pin>, RELAY#_TYPE RELAY_TYPE_NORMAL
<pin> Relay#i RELAY#_PIN <pin>, RELAY#_TYPE RELAY_TYPE_INVERSE
<pin> Led# LED#_PIN <pin>, LED#_PIN_INVERSE 0, (for other configuration, see LED#_MODE)
<pin> Led#i LED#_PIN <pin>, LED#_PIN_INVERSE 1
<pin> Button# BUTTON#_PIN <pin>, BUTTON#_CONFIG with BUTTON_SET_PULLUP | BUTTON_DEFAULT_HIGH
<pin> Button#i BUTTON#_PIN <pin>, BUTTON#_CONFIG with BUTTON_SET_PULLUP (implicit default LOW)
<pin> Button#in BUTTON#_PIN <pin>, BUTTON#_CONFIG without BUTTON_SET_PULLUP (i.e. floating pin) (implicit default LOW)
<pin> Switch# BUTTON#_PIN <pin>, BUTTON#_CONFIG with BUTTON_SWITCH | BUTTON_SET_PULLUP | BUTTON_DEFAULT_HIGH
<pin> Switch#n BUTTON#_PIN <pin>, BUTTON#_CONFIG without BUTTON_SET_PULLUP

Note that not every configuration option is 1-to-1. For more information, see:

Binding buttons, relays and LEDs

ESPurna has ability to change relay state based on the event coming from a button and set a LED status accordingly.

To do that, one should define BUTTONx_RELAY with a relay number that's "bound" to a switch. So, for example -DBUTTON1_PIN=10 -DRELAY2_PIN=11 -DBUTTON1_RELAY=2 will configure Button1 on GPIO10, Relay2 on GPIO11, and will connect Button1 to Relay2.

To also reflect Relay2 state (as defined above) on a LED1 connected to GPIO02, one should configure: -DLED1_PIN=2 -DLED1_RELAY=2 in addition to the above line.

⚠️ **GitHub.com Fallback** ⚠️