MQTT Cover and/or binary sensor don't check actual state on HA startup

If it helps I’ve seen issues like this with espurna firmware which is fixed by a “state topic” which is a value which the device publishes to and HA listens to and then updates the GUI accordingly. On some devices there’s a refresh interval you can set.

Would be interesting to listen to all mqtt traffic from your device and see what it’s publishing

I’m sure that this could be accomplished more simply in python or some other scripting language, but I’m just more familiar with C#. I stuck it in a shell_command and use it like this:

shell_command:
  set_garagedoor_state: /home/hass/config/bin/DeviceStateChanger.exe localhost:8123 cover.garagedoor state {% if is_state('input_boolean.garagedoor_state', 'off') -%} closed {%- else -%} open {%- endif %}

Here’s the automation that uses it:

automation:
  - id: SetVariablesOnStartup
    alias: Home Assistant Startup
    initial_state: 'ON'
    trigger:
      - platform: homeassistant
        event: start
    action:
      - delay: '00:00:15'
      - service: shell_command.set_garagedoor_state

Here’s the code that I wrote for the utility:

namespace DeviceStateChanger
{
    using System;
    using System.IO;
    using System.Net;
    using System.Web.Script.Serialization;

    class Program
    {
        static void Main(string[] args)
        {
            // expected arguments:
            // 0: serverName:port
            // 1: device name
            // 2: parameter
            // 3: value
            dynamic objectInfo = null;
            var homeAssistantAuthKey = new Properties.Settings()["HomeAssistantAuthKey"];
            var webserviceUri = new Uri($"http://{args[0]}/api/states/{args[1]}");
            var serializer = new JavaScriptSerializer();

            // Call into HA to retrieve the current state of the device
            {
                var request = WebRequest.CreateHttp(webserviceUri);
                request.Method = "GET";
                request.ContentType = "application/json";
                request.Headers.Add("Authorization", $"Bearer {homeAssistantAuthKey}");

                using (var response = request.GetResponse())
                {
                    using (var responseReader = new StreamReader(response.GetResponseStream()))
                    {
                        objectInfo = serializer.DeserializeObject(responseReader.ReadToEnd());
                    }
                }
            }

            // Set new state
            Console.WriteLine($"{args[1]} existing state = {objectInfo[args[2]]}");
            objectInfo[args[2]] = args[3];
            Console.WriteLine($"{args[1]} updated state = {objectInfo[args[2]]}");
            Console.WriteLine();

            // Tell HA about the updated state
            {
                var request = WebRequest.CreateHttp(webserviceUri);
                request.Method = "POST";
                request.ContentType = "application/json";
                request.Headers.Add("Authorization", $"Bearer {homeAssistantAuthKey}");
                using (var requestWriter = new StreamWriter(request.GetRequestStream()))
                {
                    var jsonString = serializer.Serialize(objectInfo);
                    requestWriter.Write(jsonString);
                    requestWriter.Flush();
                }

                using (var response = request.GetResponse())
                {
                    using (var responseReader = new StreamReader(response.GetResponseStream()))
                    {
                        Console.WriteLine(responseReader.ReadToEnd());
                        Console.WriteLine();
                    }
                }
            }
        }
    }
}

Did you try my suggestion? I watched the video you posted and I’m now more certain that it would work.

GPIO14 is listed as Sensor. Tasmota’s default setting for SensorRetain is off (same as for ButtonRetain and PowerRetain).

Run “SensorRetain 1” in the console to enable it. That’ll make the broker retain the Sensor’s value and subscriber’s will receive it upon connection (as opposed to receiving nothing).

For good measure, confirm PowerRetain is disabled.

I did try that, but to no avail. So far, my clunky solution has been the only thing that’s worked for me.

That’s odd … but I won’t press the issue. If what you have now works, great!

Wanted to come back here and detail exactly what was the cause of my issue, because now I finally understand it :slight_smile:

The problem was originally caused by my use of the “retain: true” flag in my cover entity. After learning a bit more about what the MQTT retain flag does, I realized that MQTT was just doing its job. If my garage Sonoff ever dropped off the wifi, when it came back on, it would look for any retained MQTT commands that were available for it. Because the ‘open’ and ‘close’ MQTT commands were the same, it would effectively toggle the state no matter what when it re-joined the network.

To ultimately fix the issue, I set the retain flag on the sonoff instead of the cover entity in Home Assistant. I set both the PowerRetain and SwitchRetain options on the sonoff. Some people above suggested this option, and I was convinced that I couldn’t use retain. It was only because open and close were the same in that cover entity that the retain flag was screwing me. Settiing the retain flag for the particular MQTT commands was fine.

The binary_sensor wasn’t picking up its state on HomeAssistant restart because I didn’t have the state MQTT command retained. This was fixed by setting the SwitchRetain flag on the sonoff.

Because of this, my garage door no longer suddenly opens in the middle of the night, and I don’t need the crazy solution I came up with above. I almost certainly didn’t need to install mosquitto, but I have it now, so that’s cool.

Live and learn. Hopefully someone else can benefit from my troubles.

1 Like

25 days ago I wrote:

You later replied you tried my suggestion yet it didn’t work. That made absolutely no sense to me, but I didn’t press the issue because you had already moved to another solution.

So what happened in the intervening 20+ days that ultimately made it work?

What “made it work” was some good old fashioned learning :slight_smile: I had made assumptions that were ultimately proven wrong. You were 100% correct from the beginning. I didn’t really understand ‘MQTT retain’.

When I said I had tried using ‘retain’ it was the home assistant “retain: true” option on the cover entity. Like I said in my mea culpa post, that completely breaks down because it doesn’t distinguish between PowerRetain and SwitchRetain, and the ‘open’ and ‘close’ commands are the same.

I have the same issue of “unknown” starus after restart. I’m a newbies in HASS, co could you please describe in layman’s terms what exactly you did, to solve this issue. Did you change sometthing in Tasmota console or in HASS?