MQTT Button using ESP8266

[quote=“thaijames”]humblehacker,

Sorry if I am still confused about what you are trying to do . I am assuming that you want to trigger different scenes or actions remotely using wifi. However I note that you only have one button, but you are trying to publish a number of different values as MQTT topics. Don’t you need one button for each value or topic?

So that when a button is pressed it only publishes that one value or to that one topic?

I would think that you would only want one value published in MQTT at a time so that home assistant can react to it. Otherwise if a number of values are being published rapidly then only the last value will be used.

1
0
0
47
ready
1
0
0
46

Am I understanding you correctly?

Later today I will write a new topic on the process of setting up an RFID reader to interface with an alarm system.
That might give you more insight on how I made it work.[/quote]

Yes you are correct @thaijames. I am only trying to control a single scene. I was attempting to modify @fabaffs original sketch which he had created for multiple scenes, but apparently I didnt strip out as much as I thought. Luckily @fabaff posted his own stripped-down version which is what I’m working off of at present.

[quote=“fabaff”]
I didn’t remove the command topic but toggle an additional LED (nodemcu has more pins than an ESP-01).[/quote]

Can you elaborate more about this? I’m guessing this is why I’m getting a “ready” instead of a 0 value when I push the button. Why would I need an extra pin and LED?

It shouldnt be this compilicated to build a light switch… I’m really starting to question whether its worth going through all this trouble for something that doesnt require opening up a web page… All the automations are great but theres no way I’"ll be able to convince the rest of the family that they need to open a web browser to turn the lights on at night etc…

[quote=“humblehacker”][quote=“fabaff”]
I didn’t remove the command topic but toggle an additional LED (nodemcu has more pins than an ESP-01).[/quote]

Can you elaborate more about this? I’m guessing this is why I’m getting a “ready” instead of a 0 value when I push the button. Why would I need an extra pin and LED?[/quote]

There are several reason for me to do this (visual feedback, remote commanding of the button, etc.)…so, why not simply remove it if you don’t want it?

You get the “ready” message only when the connection to the broker was made. If you get that message could mean that your board was rebooted. Issues with the circuit probably

I think I might’ve phrased my question wrong as I didnt mean to question why you did it that way. Rather I meant to ask if you could explain a little more about how the process works. For some reason I’m having a hard time grasping the concepts behind state and command topics in general. In the past, when I’ve used MQTT, it would be in a somewhat simplistic configuration where pushing a button would simply publish a topic like “home/bedroom/switch/toggle”, The controller would then be set up to listen for these actions by subscribing to the same topic “home/bedroom/switch/toggle” and then either turn a scene on or off.
I’m sure there is a good reason for seperate topics for state and command, I just don’t understand it. In any case my line of questioning isnt meant to suggest I have a better approach. I just want to understand how to make it work.

The MQTT sensor and the Binary sensor are working exactly in that manner. They are just consuming messages. So if you want to use a button you only need to send its state. In sketch it’s done that way. If the button gets pressed then a message is sent on the state topic.

The command topic is for receiving command of a remote device (view from your controller/HA). If the command topic is the same as the state topic then you could end up in a loop. The receiver would consume its own state message which will be interpreted as command and then send a new state message.

Oh ok. Its starting to make a little more sense now. In that case I wonder if this would make sense-
[ul]
1 Add the ESP+Button as an MQTT sensor
2 Create a scene with most lights off for when we’re sleeping
3 Create a “Nightlight” scene for when we need to quickly turn the lights on
4 Create an event that listens for the sensor topic and triggers the nightlight scene
5 Add a condition that triggers the sleep scene if the nightlight is already triggered[/ul]

Or is there a simpler way to toggle between two scenes?

How many programmers does it take to build a lightswitch? :smiley:
If anybody else has succeeded in building a simple wireless toggle switch then by all means please do share your method… Otherwise, I’m going to declare that this seemingly simple function is proving to be anything but! Nevertheless,it is the type of thing where one has to question the value of having so many amazing automations at our calling when its impossible to physically turn anything on or off without a phone or computer…
Anyway, I thought I had it all figured out with adding the toggle button as a sensor rather than a switch but as soon as I restarted HASS with my new config my lights started going all Skynet on me flickering on and off and refusing all commands… I tried a couple different configs but in the end I’m afraid it all comes down to a phenomenon called “bounce” wherein too much interference on an analog pushbutton causes the client to constantly send out events… This Arduino article explains a little bit more- learn.acrobotic.com/tutorials/po … ush-button
The more I think about it, the more it occurs to me that the simple act of toggling an LED on which most of us began our programming journey is very much dependent on simple analog communications e.g power come on=light comes on/power goes off=light goes off and so on… The same process doesn’t carry over all that well to triggering big LEDs over a wireless network apparently…
So I’m back at square one and will gladly entertain any “its not really that complicated” comments if they lead to an actual working solution…

Here’s one way of doing it I guess, but its pretty specific to functioning as a standalone wifi connecting wall switch. It may be possible to dissect the code and extract the pieces that relate to the switching function itself…

Take a look at my post:
https://automic.us/forum/viewtopic.php?f=4&t=43

While it demonstrates turning on and off an alarm using an RFID reader, you can modify it so that by presenting a token you turn on and off what ever you want.

Instead of the RFID reader a key switch, push button or some other mechanism can be used. When I have some free time I will try to come up with some kind of solution.

I know this is an old topic. I hope its still relevant. I want to achieve something very similar ( I think!) to this. I have an esp8266 nodeMCU. Plenty of pins and goodies. I basically want a relay, led, and push button. I want the button to trigger the relay and LED (locally, NOT over Mqtt) then report the relays state to the MQTT broker. I also want it receive on/off from the broker. Im using the default MQTT broker with HASS. I can do the simple MQTT on/off but I have gotten lost in the button!
Any help is much appreciated!

Just few steps behind you, I am there as well. Just curious to know if you reached the desired destination? If yes, would be very much thankful if you could share the config yaml and the sketch please.

I am having esp8266 nodeMCU, HA and mqtt broker bundled with HA. So identical scenario.

Any news on this? :smiley:

I’m trying to do the same thing, without succes.

I’ve accomlished this with a D1 mini and the button shield.

Also cleaned it up with http://www.thingiverse.com/thing:1497889 (got two printed and shipped for $22.46 from itead.cc)

Arduino code:

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

const char *ssid =  "SSID";   // cannot be longer than 32 characters!
const char *pass =  "PASS";   //
const char *mqtt_server = "MQTT_SERVER";
const int mqtt_port = MQTT_PORT;
const char* connection_id = "MQTT_ID";
const char* client_name = "MQTT_NAME";
const char* client_password = "MQTT_PASSWORD";
const char* topic = "MQTT_TOPIC";
char somebigthing[100];

const int buttonPin = D3;
const int ledPin = BUILTIN_LED;

WiFiClient espClient;
PubSubClient client(espClient);

// the current state of the LED and button
int ledState = LOW;
int buttonState = LOW;

// the current and previous readings from the input pin
int thisButtonState = LOW;
int lastButtonState = LOW;

// time is measured in milliseconds and will quickly exceed limitations of an integer, so we use a long for these two
unsigned long lastDebounceTime = 0;  // the time the button state last switched
unsigned long debounceDelay = 50;    // the state must remain the same for this many millis to register the button press

void setup() {
  Serial.begin(9600);
  pinMode(buttonPin, INPUT);
  client.setServer(mqtt_server, mqtt_port); // MQTT!!!
}

void loop() {
  Serial.println("Hello world1");
  WiFi.begin(ssid, pass);
  client.connect(connection_id, client_name, client_password);
  Serial.println("Hello world2");
  // the buttonPin is read multiple times and the value must remain the same for debounceDelay millis to toggle the LED

  // read button state, HIGH when pressed, LOW when not
  thisButtonState = digitalRead(buttonPin);

  // if the current state does not match the previous state
  // the button was just pressed/released, or is transition noise
  if (thisButtonState != lastButtonState) {
    // reset the timer
    lastDebounceTime = millis();
  }

  // once delay millis have elapsed, if the state remains the same, register the press
  if ((millis() - lastDebounceTime) > debounceDelay) {

    // if the button state has changed
    if (thisButtonState != buttonState) {
      buttonState = thisButtonState;

      // only toggle the LED if the buttonState has switched from LOW to HIGH
      if (buttonState == HIGH) {
        ledState = !ledState;
        // toggle the LED
        if (ledState == HIGH) {
          SendOn();
        }
        else {
          SendOff();
        }
      }
    }
  }

  // persist for next loop iteration
  lastButtonState = thisButtonState;
}

void SendOn(){
  strcpy(somebigthing,  "{\"enabled\":\"true\"}");
  client.publish(topic, somebigthing);
}


void SendOff(){
  strcpy(somebigthing,  "{\"enabled\":\"false\"}");
  client.publish(topic, somebigthing);
}
2 Likes

Any luck?

I believe, I have managed to successfully do it. Will be quite happy to help as much as i can. Let me know how to go about it.

@fabaff if i want to use 2 buttons, and 2 led pins,
What would the code look like? can u post please?
thanks

I hate to admit it, but it’s been a while. Can you post the schematics of how you hooked up your ESP8266 so I don’t start out by frying one :wink:
Thanks

1 Like

Hi, i use this:

And its run very good!.
Antoni.

Can anyone help to convert the above code to trigger 4 relays with 4 switches?

I have defined Relays to D1, D2, D3, D4 and D5, D6, D7 and D8 to LED’s on the NodeMCU ESP8266.

Can someone help me on my problem here: Press a button and the mqtt subscribe a command to the HASS