MQTT Switch Help

Hi all,

I new to Home assistant and MQTT I have a little experience using Arduino IDE to program NodeMCU’s.
So it seemed like using the MCU with HA and MQTT was a natural progression. However I am struggling.

I have even used pre-written code but still can’t get it working. I can get the MCU to show up as connected in the Mosquitto log but cannot get it to switch on and off.

The code I am using on the NodeMCU is

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

#define MQTT_VERSION MQTT_VERSION_3_1_1

// Wifi: SSID and password
const char* WIFI_SSID = "**********";
const char* WIFI_PASSWORD = "************";

// MQTT: ID, server IP, port, username and password
const PROGMEM char* MQTT_CLIENT_ID = "office_light1";
const PROGMEM char* MQTT_SERVER_IP = "192.168.1.114";
const PROGMEM uint16_t MQTT_SERVER_PORT = 1883;
const PROGMEM char* MQTT_USER = "************";
const PROGMEM char* MQTT_PASSWORD = "************";

// MQTT: topics
const char* MQTT_LIGHT_STATE_TOPIC = "office/light1/status";
const char* MQTT_LIGHT_COMMAND_TOPIC = "office/light1/switch";

// payloads by default (on/off)
const char* LIGHT_ON = "ON";
const char* LIGHT_OFF = "OFF";

const PROGMEM uint8_t LED_PIN = 5;
boolean m_light_state = true; // light is turned off by default

WiFiClient wifiClient;
PubSubClient client(wifiClient);

// function called to publish the state of the light (on/off)
void publishLightState() {
  if (m_light_state) {
    client.publish(MQTT_LIGHT_STATE_TOPIC, LIGHT_ON, true);
  } else {
    client.publish(MQTT_LIGHT_STATE_TOPIC, LIGHT_OFF, true);
  }
}

// function called to turn on/off the light
void setLightState() {
  if (m_light_state) {
    digitalWrite(LED_PIN, LOW);
    Serial.println("INFO: Turn light on...");
  } else {
    digitalWrite(LED_PIN, HIGH);
    Serial.println("INFO: Turn light off...");
  }
}

// function called when a MQTT message arrived
void callback(char* p_topic, byte* p_payload, unsigned int p_length) {
  // concat the payload into a string
  String payload;
  for (uint8_t i = 0; i < p_length; i++) {
    payload.concat((char)p_payload[i]);
  }
  
  // handle message topic
  if (String(MQTT_LIGHT_COMMAND_TOPIC).equals(p_topic)) {
    // test if the payload is equal to "ON" or "OFF"
    if (payload.equals(String(LIGHT_ON))) {
      if (m_light_state != true) {
        m_light_state = true;
        setLightState();
        publishLightState();
      }
    } else if (payload.equals(String(LIGHT_OFF))) {
      if (m_light_state != false) {
        m_light_state = false;
        setLightState();
        publishLightState();
      }
    }
  }
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.println("INFO: Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect(MQTT_CLIENT_ID, MQTT_USER, MQTT_PASSWORD)) {
      Serial.println("INFO: connected");
      // Once connected, publish an announcement...
      publishLightState();
      // ... and resubscribe
      client.subscribe(MQTT_LIGHT_COMMAND_TOPIC);
    } else {
      Serial.print("ERROR: failed, rc=");
      Serial.print(client.state());
      Serial.println("DEBUG: try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup() {
  // init the serial
  Serial.begin(115200);

  // init the led
  pinMode(LED_PIN, OUTPUT);
  analogWriteRange(255);
  setLightState();

  // init the WiFi connection
  Serial.println();
  Serial.println();
  Serial.print("INFO: Connecting to ");
  WiFi.mode(WIFI_STA);
  Serial.println(WIFI_SSID);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

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

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

  // init the MQTT connection
  client.setServer(MQTT_SERVER_IP, MQTT_SERVER_PORT);
  client.setCallback(callback);
}

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

and in Home Assistant

light:
  platform: mqtt
  name: 'Office light'
  state_topic: 'office/light1/status'
  command_topic: 'office/light1/switch'
  optimistic: false

I would be grateful for any help.

The NodeMCU is connected to the MQTT Broker using this information:

MQTT_CLIENT_ID = "office_light1";
MQTT_SERVER_IP = "192.168.1.114";
MQTT_SERVER_PORT = 1883;
MQTT_USER = "************";
MQTT_PASSWORD = "************";

Have you configured Home Assistant to login to the MQTT Broker?

If you use an MQTT cllient, like MQTT Explorer, to publish ON to office/light1/switch, does the light turn on?

If you use Home Assistant’s MQTT Publish page to publish ON to office/light1/switch, does the light turn on?

Screenshot%20from%202019-04-21%2019-47-49

Thanks for the reply

No it still doesn’t work.

I have this entry in the config.yaml
mqtt:
broker: 192.168.1.114

is this correct?

Your NodeMCU is using a username and password to login to the MQTT broker. Did you also configure Home Assistant to login the broker with a username and password? If all you supplied is this then I guess the answer is no.

mqtt:
broker: 192.168.1.114

You said this:

Does Mosquitto’s log show Home Assistant connected? My guess is no.

The code in mosquitto is

 { "logins": [],
  "anonymous": true,
  "customize": {
    "active": false,
    "folder": "mosquitto"
  },
  "certfile": "fullchain.pem",
  "keyfile": "privkey.pem"
}

Which I think means the user name and password isn’t used. Of course I am not sure about that.

The log is as follows after restarting mosquitto

[INFO] Setup mosquitto configuration [WARN] SSL not enabled - No valid certs found!
[INFO] No local user available [INFO] Initialize Hass.io Add-on services
[INFO] Initialize Home Assistant discovery
[INFO] Start Mosquitto daemon 1555915293: mosquitto version 1.5.6 starting
1555915293: Config loaded from /etc/mosquitto.conf.
1555915293: |-- *** auth-plug: startup
1555915293: |-- ** Configured order: http
1555915293: |-- with_tls=false
1555915293: |-- getuser_uri=/login
1555915293: |-- superuser_uri=/superuser
1555915293: |-- aclcheck_uri=/acl
1555915293: |-- getuser_params=(null)
1555915293: |-- superuser_params=(null)
1555915293: |-- aclcheck_params=(null)
1555915293: |-- retry_count=3
1555915293: Opening ipv4 listen socket on port 1883.
1555915293: Opening ipv6 listen socket on port 1883.
1555915293: Opening websockets listen socket on port 1884.
1555915293: Warning: Mosquitto should not be run as root/administrator.
1555915297: |-- mosquitto_auth_unpwd_check(D4VEW557)
1555915297: |-- ** checking backend http
1555915297: |-- url=http://127.0.0.1:8080/login
1555915297: |-- data=username=D4VEW557&password=scooby12345&topic=&acc=-1&clientid= 1555915297: New connection from 192.168.1.107 on port 1883. [INFO] found D4VEW557 on Home Assistant
1555915299: New client connected from 192.168.1.107 as office_switch1 (c1, k15, u’D4VEW557’).
1555915299: |-- getuser(D4VEW557) AUTHENTICATED=1 by http
1555915299: |-- mosquitto_auth_acl_check(…, client id not available, D4VEW557, office/switch1/status, MOSQ_ACL_WRITE)
1555915299: |-- url=http://127.0.0.1:8080/superuser
1555915299: |-- data=username=D4VEW557&password=&topic=&acc=-1&clientid= 1555915299: |-- aclcheck(D4VEW557, office/switch1/status, 2) SUPERUSER=Y by http 1555915299: |-- Cached [0DE93A1F4A3D002D6F447494D8A2AA75F45FCDE7] for (client id not available,D4VEW557,2)
1555915299: |-- mosquitto_auth_acl_check(…, client id not available, D4VEW557, office/switch1/set, MOSQ_ACL_WRITE) 1555915299: |-- url=http://127.0.0.1:8080/superuser 1555915299: |-- data=username=D4VEW557&password=&topic=&acc=-1&clientid= 1555915299: |-- aclcheck(D4VEW557, office/switch1/set, 4) SUPERUSER=Y by http 1555915299: |-- Cached [80452605F7E9926D965B19C0670BD2E43A291C72] for (client id not available,D4VEW557,4) 1555915308: New connection from 192.168.1.114 on port 1883. 1555915308: New client connected from 192.168.1.114 as 00a9a600-f3e2-40a9-92cd-793ef17f86f9 (c1, k60).

Sorry it’s so long but I wasn’t sure what bits were important. I understand some of it but not all.

If you are using the Mosquitto addon it is configured in Integrations and you should not have this in your config:

mqtt:
broker: 192.168.1.114

See here for setup:

Hi,

If i don’t put ‘mqtt broker 192.168.1.114’ in the config file mosquitto wont connect.

In the integrations page it shows MQTT : configuration.yaml as already configured.

Well it’s not configured correctly if you have the integration and configuration code.

Do this:

OK, I have done that it shows Mosquitto is now configured but my switch doesn’t show in the overview anymore

this is how the log looks after restarting (192.168.1.107 is the esp I’m trying to connect)

[INFO] Setup mosquitto configuration
[WARN] SSL not enabled - No valid certs found!
[INFO] No local user available
[INFO] Initialize Hass.io Add-on services
[INFO] Initialize Home Assistant discovery
[INFO] Start Mosquitto daemon
1555931484: mosquitto version 1.5.6 starting
1555931484: Config loaded from /etc/mosquitto.conf.
1555931484: |-- *** auth-plug: startup
1555931484: |-- ** Configured order: http
1555931484: |-- with_tls=false
1555931484: |-- getuser_uri=/login
1555931484: |-- superuser_uri=/superuser
1555931484: |-- aclcheck_uri=/acl
1555931484: |-- getuser_params=(null)
1555931484: |-- superuser_params=(null)
1555931484: |-- aclcheck_params=(null)
1555931484: Opening ipv4 listen socket on port 1883.
1555931484: Opening ipv6 listen socket on port 1883.
1555931484: Opening websockets listen socket on port 1884.
1555931484: |-- retry_count=3
1555931484: Warning: Mosquitto should not be run as root/administrator.
1555931488: New connection from 192.168.1.107 on port 1883.
1555931488: New client connected from 192.168.1.107 as office_light1 (c1, k15).

after a few minutes this appeared.

1555931605: New connection from 172.30.32.1 on port 1883. 
1555931606: Socket error on client &lt;unknown&gt;, disconnecting. 
1555931606: New connection from 172.30.32.1 on port 1883. 
1555931606: |-- mosquitto_auth_unpwd_check(homeassistant) 
1555931606: |-- ** checking backend http 1555931606: |-- url=http://127.0.0.1:8080/login 1555931606: |-- data=username=homeassistant&amp;password=pfjjM5SE_gTBboD_KuUs0LObFLlbGdSF&amp;topic=&amp;acc=-1&amp;clientid= [INFO] found homeassistant on local database 
1555931607: |-- getuser(homeassistant) AUTHENTICATED=1 by http 
1555931607: New client connected from 172.30.32.1 as 62173290-7225-4467-9507-074c2976256b (c1, k60, u'homeassistant'). 
1555931607: |-- mosquitto_auth_acl_check(..., client id not available, homeassistant, homeassistant/#, MOSQ_ACL_WRITE)
 1555931607: |-- url=http://127.0.0.1:8080/superuser 
1555931607: |-- data=username=homeassistant&amp;password=&amp;topic=&amp;acc=-1&amp;clientid= 1555931607: |-- aclcheck(homeassistant, homeassistant/#, 4) SUPERUSER=Y by http 1555931607: |-- Cached [14B58586E557B5F874372491E6CC8249FF3820B8] for (client id not available,homeassistant,4)

Unfortunately, I have no hands-on experience with Hass.io’s Mosquitto Add-on. To my untrained eye, the log still seems to show there may be an authentication problem. I’ll have to bow out and let others help you solve this one. Good luck!

I appreciate any and all help.

You’re not using homeassistant as the username for your devices are you? That’s not allowed (step 2 here): https://www.home-assistant.io/addons/mosquitto/#using-mosquitto-with-hassio

You should also set up ACL: Mosquito update 4.1 - ACL messages in logs

No i haven’t called it home assistant or addon.

Where do I add the file shown link?

Where it says to:

/share/

Go to your config/ directory and go up one level, you should see it.

Could you explain in more detail how to get to this file.

Thanks

There is no file. You have to create it. Read the instructions, they say go to a place and create a file.

I understand that. My question is where do I go to create the file.

Is it as simple as going into my network/hassio/share

And creating the file there,

Yes. Exactly that.

Thanks Tom. I have the the switch displayed and operating.
Its controlling a nodemcu flashed with Tasmota, when I operate the switch in ha it show on the tasmota interface and vice versa. I still can get it to control my relay but still step 1’ connection’ is complete.
Thanks for your help.

1 Like