MQTT Config for Button Trigger!

Hello!
I found this tutorial: http://www.instructables.com/id/NodeMCU-MQTT-Iot-Project-Switch-Button/

Which I have working, I changed the states as follows:
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
long now = millis();
int status;
//send message every 2 second
if (now - lastMsg > 2000) {
lastMsg = now;
status=digitalRead(BUTTON_PIN);
String msg="Button status: ";
if(status==HIGH )
{
msg= msg+ “Pressed”;
char message[58];
msg.toCharArray(message,58);
Serial.println(message);
//publish sensor data to MQTT broker
client.publish(“buttondata”, message);
}
else
{
msg= msg+ “No Press”;
char message[58];
msg.toCharArray(message,58);
Serial.println(message);
//publish sensor data to MQTT broker
client.publish(“buttondata”, message);
}

I am trying to trigger a basic script with an automation but this doesn’t appear to be working and I am sure its because I am not using the proper topic but I am not sure of the correct format… is the topic buttondata and the payload “pressed”? thanks!

alias: MQTT button
trigger:
- platform: mqtt
topic: buttondata/pressed
condition: []
action:
- data:
  entity_id: script.lightsup_evening
service: homeassistant.toggle
1 Like

This line sends a message with topic ‘buttondata’ and a payload with whatever is in the message variable. Looking back through the code, it looks like this is either Button status: Pressed or Button status: No Press

The documentation for triggering automations from MQTT messages is here

So your trigger section should be

trigger:
  - platform:mqtt
    topic: "buttondata"
    payload: "Button status: Pressed"
1 Like

THANK YOU!
I have been greatly confused with how payloads and such work with MQTT that clarifies it.

1 Like

follow up question if you don’t mind… to make a state for button held, I assume I should make another else (if) statement that reads the state for a different amount of time and then reports it? Do you have any suggestions?

I am not sure what you want to achieve, but I probably can’t help much as I do all of my automations in appdaemon, so I don’t know too much about yaml.

on the ESP (arduino) code. I want to have a MQTT message sent when the button is pressed and held for lets say 3 seconds. A different message then “Pressed”… etc

I suppose I have to augment this:
if(status==HIGH )
with an int so that if status==high for 3000 then do this…

Either that, or determine how long the button was pressed when it is released, and send an appropriate message then.

Check out this library:

1 Like

Hi, I made a small code for you which publishes different payloads if you pushed a button for 2 secs or less. It works on NodeMCU.

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

#define WIFI_AP "xxxxxxxx"
#define WIFI_PASSWORD "xxxxxxxx"

int btn_pin = 5;
bool btn_state = false;
bool btn_state_prev = false;
long btn_pushed_time;
long btn_released_time;
long now;
long difference;

String strTopic;
String strPayload;

const char* mqtt_server = "xxxxxxxx";
WiFiClient espClient;
PubSubClient client(espClient);

void setup()
{
  pinMode(btn_pin, INPUT);

  Serial.begin(115200);

  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}

void loop()
{
  if (!client.connected())
  {
    reconnect();
  }
  publishButtonState();
  client.loop();
}

void callback(char* topic, byte* payload, unsigned int length)
{
  payload[length] = '\0';
  strTopic = String((char*)topic);
  strPayload = String((char*)payload);

  Serial.println(strTopic + ": " + strPayload);
}

void publishButtonState()
{
  btn_state = digitalRead(btn_pin);
  delay(20);
  now = millis();

  if (!btn_state_prev && btn_state)  // button pushed
  {
    btn_state_prev = true;
    btn_pushed_time = now;
  }

  if (btn_state_prev && !btn_state)  // button released
  {
    btn_state_prev = false;
    btn_released_time = now;

    difference = btn_released_time - btn_pushed_time;

    if (difference < 2000)
      client.publish("BUTTON", "SHORT");
    else
      client.publish("BUTTON", "LONG");
  }
}

void setup_wifi()
{
  delay(100);
  Serial.print("Connecting to ");
  Serial.println(WIFI_AP);

  WiFi.begin(WIFI_AP, WIFI_PASSWORD);

  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
}

void reconnect()
{
  while (!client.connected())
  {
    Serial.print("Attempting MQTT connection...");

    if (client.connect("clientId", "clientUsername", "clientPassword"))
    {
      Serial.println("connected");
      client.subscribe("#");
      Serial.println("subscribed to every topic");
    }
    else
    {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      delay(5000);
    }
  }
}