Need help combining a esp8266, a reed switch, and MQTT

i’d like to combine a esp8266, a reed switch, and MQTT for a wifi enabled door sensor. does anyone have a good tutorial or can point me in the right direction?

Hi @stone, you can try this one.

Although the title says “existing home security sensors” you don’t need to have a previous system. You can build it from scratch.

I’ve build it and works like a charm!

2 Likes

You can take a look at my project here: https://github.com/marthoc/GarHAge. It’s built to control two garage doors (you can ignore that part) but also has the necessary code to read input from reed switches and report status over MQTT. You could use it as is but it wouldn’t be hard to adapt the code just to read reed switch inputs and publish status.

Excellent project @marthocoo! You could add some photos for people to see where to install the reed switches and make all the connections.

Thanks! Agreed, photos would be good, and are my next project once I clean up my garage lol.

You want code or what. I use these 3 things for my garage door. It’s pretty simple.

yeah i was mainly looking for the best code (with MQTT) to flash to the esp8266 and wiring diagram for the reed switch to the esp8266. the HA side looks pretty simple.

Two more options for your use-case:

  • Homie is a framework with a standardised MQTT protocol approach. I am using this in a few sensors and am quite happy with it.
  • ESPEasy appears to be another popular choice, especially if you want less coding and focus on wiring and configuring.

for use with Wemos D1 Minis + Wemos Relay Shield + simple reed switch. I’d like to credit the guy I got most of this code from but I can’t remember. If i figure it out I’ll change it.

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

const char* ssid = "(YOUR_SSID)";
const char* password = "(YOUR_WIRELESS_PASSWORD)";
// Update these with values suitable for your network.
IPAddress ip(XXX.XXX.XXX.XXX);  //Node static IP
IPAddress gateway(XXX.XXX.XXX.XXX);
IPAddress subnet(XXX.XXX.XXX.XXX);
const char* mqtt_server = "YOUR_BROKER_IP";
const char* mqtt_topic = "YOUR_HA_TOPIC";
const char* mqtt_user = "MQTT_HA_USERNAME";
const char* mqtt_password = "MQTT_HA_USERPASS";
const char* mqtt_device_id = "YOUR_MQTT_DEVICEID";
const char* mqtt_lwt = "LAST_WILL_IF_DESIRED";
const boolean mqtt_retain = 0; //set to 0 to resolve reconnect LOP issues
const uint8_t mqtt_qos = 0; //can only be a value of (0, 1, 2)
char vInp13 = 0;
String rx;         // I Use WEMO D1 Mini so these are those pins
int rxLength = 0;
int relayPin = 5; 
int sensorPin = 13;

WiFiClient espClient;
PubSubClient client(espClient);

void setup() {   //I use WEMO D1 Mini + relay board
  pinMode(relayPin, OUTPUT);
  pinMode(sensorPin, INPUT_PULLUP);
  //digitalWrite(relayPin, 1);
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}

void setup_wifi() {
  delay(10);  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  WiFi.config(ip, gateway, subnet);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int length) {\
  Serial.print("RX: ");
  //Convert and clean up the MQTT payload messsage into a String
  rx = String((char *)payload);                    //Payload is a Byte Array, convert to char to load it into the "String" object 
  rxLength = rx.length();                          //Figure out how long the resulting String object is 
  for (int i = length; i <= rxLength; i++)         //Loop through setting extra characters to null as garbage may be there
  {
    rx.setCharAt(i, ' ');
  }
  rx.trim();                                       //Use the Trim function to finish cleaning up the string   
  Serial.print(rx);                                //Print the recieved message to serial
  Serial.println();

    //Evaulate the recieved message to do stuff
    if ((rx == "OpenGarageDoor") && (vInp13 == HIGH)) //normal operations
//  if ((rx == "True") && (vInp13 == HIGH)) //difference in home-assistant, prevent error in log
  {digitalWrite(relayPin, 1);} //Turn the output on / open the door 
  delay(1000);                                     //Wait a second
  digitalWrite(relayPin, 0);                              //Turn the output back off   
  delay(1000);                                     //Let Voltage settle before resuming.  

  if ((rx == "CloseGarageDoor") && (vInp13 == LOW))  //normal operations
//  if ((rx == "False") && (vInp13 == LOW))  //difference in home-assistant, prevent error in log
  {digitalWrite(relayPin, 1);} //Turn the output on / close the door 
  delay(1000);                                     //Wait a second
  digitalWrite(relayPin, 0);                              //Turn the output back off   
  delay(1000);                                     //Let Voltage settle before resuming.  

  if (rx == "Status") //normal operation
//  if (rx == "100")  //difference in home-assistant, prevent error in log
  {
       vInp13 = digitalRead(sensorPin);
       if (vInp13 == LOW)
         {    
            client.publish(mqtt_topic, "Open");
            Serial.println("TX: DoorOpened");
         }
      else
         {
            client.publish(mqtt_topic, "Closed");
            Serial.println("TX: DoorClosed");
        }
  }
}



void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
  Serial.print("Attempting MQTT connection...");
  // Attempt to connect
  //if (client.connect(mqtt_topic,mqtt_user,mqtt_password)) {
  //needs next line for proper connect to mqtt broker that doesn't allow anonymous
  if (client.connect(mqtt_device_id, mqtt_user, mqtt_password, mqtt_topic, mqtt_qos, mqtt_retain, mqtt_lwt)) {
    Serial.println("connected");
  if (digitalRead(sensorPin) != vInp13)
    {
       vInp13 = digitalRead(sensorPin);
       if (vInp13 == LOW)
         {    
            client.publish(mqtt_topic, "Open");
            Serial.println("TX: DoorOpened");
         }
      else
         {
            client.publish(mqtt_topic, "Closed");
            Serial.println("TX: DoorClosed");
        }
  }
      // ... and resubscribe
      client.subscribe(mqtt_topic);
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}
void loop() {

  if (!client.connected()) {
    reconnect();
  }
  if (digitalRead(sensorPin) != vInp13)
    {
       vInp13 = digitalRead(sensorPin);
       if (vInp13 == LOW)
         {    
            client.publish(mqtt_topic, "Open");
            Serial.println("TX: DoorOpened");
         }
       else
        {
           client.publish(mqtt_topic, "Closed");
           Serial.println("TX: DoorClosed");
        }
    }
  client.loop();
  delay(10);  
}
2 Likes

Since no one’s answered the wiring diagram question, it’s pretty straightforward. In some of the code you’ve seen (including mine), a pin is defined as INPUT_PULLUP. This means that the input will read 1 or HIGH unless pulled to ground, when it will read 0 or LOW.

Your reed switch will have at least a common and either a normally open or normally closed terminal (some have all 3: COM, NO, NC). Run one wire from common to either the pin defined as INPUT_PULLUP or ground (it doesn’t matter which). Run the other wire from NC/NO to the opposite you wired the common terminal to (INPUT_PULLUP or GND).

If you’re using a NO reed switch, the input will read HIGH when the door is open, and LOW when closed. Vice versa for a NC switch.

My code in https://github.com/marthoc/GarHAge allows you to specify the type of switch in use as a config option, and sends “open” over a configurable topic when the door opens and “closed” over the same topic when the door closes.

I added a reed to bruh automations multisensor. It works well might be overkill for your case.

yeah, i’m going to be trying your code as soon as AmzP sends my parts.

nice code. got it working fine.

my reed switches are the both NC/NO. is there any benefit to choosing one over the other?

Doesn’t matter at all, as long as you pick the correct config option either NO or NC will work correctly.

is there a limit to the length of wire between the mcu and the reed switch?

I’m sure there probably is a theoretical limit but practically speaking you’re probably ok. My own reed switch is approx 25 feet away from the NodeMCU and it works just fine.

yeah i got it working. thanks for your help and code. works great.

here are my full notes for anyone interested in using GarHAge for just a coupla reed switches.

update config with wifi and MQTT settings and then flash, use nodeMCU ESP-12e settings

(do not need the relay mentioned in the parts list)

WIRING:
——switch 1
wire reed switch NO and COM
COM to D5
NO to any GND

——switch 2
wire reed switch NO and COM
COM to D6
NO to any GND

——— check MQTT
mosquitto_sub -t “#” -v -u username -P password

reset MCU and it should broadcast it’s status to mosquitto.

——— HASS

customize:
    binary_sensor.bedroom_door:
      icon: mdi:home-assistant
      friendly_name: "Bedroom Door"
    binary_sensor.bedroom_window:
      icon: mdi:home-assistant
      friendly_name: "Bedroom Window"

binary_sensor:
  - platform: mqtt
    name: bedroom_door
    state_topic: "door/1/status"
    payload_on: "open"
    payload_off: "closed"
    device_class: opening
    qos: 0
  - platform: mqtt
    name: bedroom_window
    state_topic: "window/1/status"
    payload_on: "open"
    payload_off: "closed"
    device_class: opening
    qos: 0

groups.yaml
  security:
   name: "Security"
   entities:
     - binary_sensor.bedroom_door
     - binary_sensor.bedroom_window

can you share your code for the bruh sensor with a reed switch integrated please? interested in this. Thanks

See here.