How to add ESP8266 with PIR motion sensor


I try to add a ESP8266 with a PIR Motion sensor to do some automation.
I followed this tutorial to load code on the ESP8266

And this is my final code what i have upload to the ESP.

char* ssid = "*"; //Wi-Fi AP Name
char* password = "*!"; //Wi-Fi Password
char* mqtt_server = ""; //MQTT Server IP
char* mqtt_username = "*"; //MQTT Username
char* mqtt_password = "*"; //MQTT Password
char* mqtt_name = "Motion Sensor 1"; //MQTT device name
char* mqtt_topic = "MotionSensor1"; //MQTT topic for communication
char* mqtt_ending = "/data"; //MQTT subsection for communication
int pirPin = D0;  //set the GPIO which you will connect the PIR sensor
bool lowPower = false; //set to true if you want low power use, slower alerts but more battery
int delayTime = 2000; //ONLY FOR LOW POWER - how long motion detected should be active

#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <PubSubClient.h>
WiFiClient mainESP;
PubSubClient MQTT(mainESP);
long lastMsg = 0;
char msg[50];
int value = 0;
int pir = 1;

char* mqtt_subtopic = "/data"; //MQTT topic for communication
char* mqtt_maintopic = mqtt_topic;

void setup() {
  strcat(mqtt_maintopic, mqtt_subtopic);
  pinMode(pirPin, INPUT);

void loop() {
  if (!lowPower && WiFi.status() != WL_CONNECTED) startWiFi();

  if ((digitalRead(pirPin)) == 0) delay(250);

  else {
    if (WiFi.status() != WL_CONNECTED) startWiFi();
    if (!MQTT.connected()) reconnect();
    MQTT.publish(mqtt_topic, "TRUE");
    Serial.println("Message Published: TRUE");
    while (digitalRead(pirPin) == 1) {
      if (!MQTT.connected()) reconnect();
      MQTT.publish(mqtt_topic, "TRUE");
      Serial.println("Message Published: TRUE");
    pir = 0;
    if (!MQTT.connected()) reconnect();
    if (lowPower) delay(delayTime);
    MQTT.publish(mqtt_topic, "FALSE");
    Serial.println("Message Published: FALSE");
  if (lowPower) {

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print("] ");
  for (int i = 0; i < length; i++) {

void reconnect() {
  while (!MQTT.connected()) {
    Serial.print("Attempting MQTT connection...");
    if (MQTT.connect(mqtt_name,mqtt_username,mqtt_password)) {
    } else {
      Serial.print("failed, rc=");
      Serial.println(" try again in 5 seconds");
      for (int i = 0; i < 5000; i++) {

void startWiFi() {
  WiFi.begin(ssid, password);
  while (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("Connection Failed! Rebooting...");
  Serial.print("IP address: ");
  MQTT.setServer(mqtt_server, 1883);

Now i try to add in Home-Assistant with the following code:

  - platform: mqtt
    name: "MotionGang"
    state_topic: "MotionSensor1"
    value_template: '{{ value_json.motion }}'

Now the sensor shows up but with the status unkown.
Who can help me how to add this right?

Please use mosquitto_sub or another mqtt client and paste a message (topic + payload) of your device into the thread.

First thing’s first: let’s figure out if your ESP8266 is actually publishing messages when it should.

One easy way is to use mosquitto_sub (a Linux command line tool included in the package mosquitto-clients) but you can use any MQTT client.

With mosquitto_sub, type:

mosquitto_sub -h -u username -P password -v -t “#”

Obviously replace username and password with the auth info for your broker.

This will subscribe you to all topics on the broker. Now start the ESP8266 device. Do you see a message published? Try to trigger the motion sensing. Do you see a message published? If so, you will be able to see what topic and payload is being sent by your device. Does this match what HASS is expecting?

And second, according to your code, the state topic is not “MotionSensor1” but “MotionSensor1/data” (I think?). Without looking any further at the code, this may be your issue.

That was a mistyping, from a old file.

This is what the MQTT server received:

Client mosqsub/23453-PiServer received PUBLISH (d0, q0, r0, m0, 'MotionSensor1/data', ... (4 bytes))
Client mosqsub/23453-PiServer received PUBLISH (d0, q0, r0, m0, 'MotionSensor1/data', ... (4 bytes))
Client mosqsub/23453-PiServer received PUBLISH (d0, q0, r0, m0, 'MotionSensor1/data', ... (4 bytes))
Client mosqsub/23453-PiServer received PUBLISH (d0, q0, r0, m0, 'MotionSensor1/data', ... (4 bytes))
Client mosqsub/23453-PiServer received PUBLISH (d0, q0, r0, m0, 'MotionSensor1/data', ... (4 bytes))

I think what I would do is this:

  - platform: mqtt
    state_topic: "MotionSensor1/data"
    name: "MotionGang"
    payload_on: "TRUE"
    payload_off: "FALSE"
    device_class: motion

I was right, the topic is “MotionSensor1/data”, according to the output from mosquitto_sub that you posted.

Leave out value template because you don’t need to extract a value from the payload.

1 Like

And one other thing, you may want to check that your device actually eventually sends a “FALSE” payload when motion is no longer detected or the dead time ends or whatever, since otherwise HASS will always show that motion was detected if that’s the last payload it’s received.