How to set a limit/timeout on how long the ESP tries to connect to WiFi before going back to deep sleep?

I have a temperature sensor running the attached ESPHome code.

The esp wakes up, reads the sensor, connects to WiFi, connects to MQTT, updates the values, and then goes to deep sleep for 5min. Normally, the “awaketime” (see code) it returns is around 4 seconds. So unless it’s doing some stuff before and/or after setting “t1” and “t2”, I assume it’s awake for 4 seconds and asleep for 5min.

The reason for this (the deep sleep) is because the ESP’s own heat generation severely influences the temperature sensor if powered on and connected all the time.

The problem I have with the current code is that when the ESP fails to connect because for example the WiFi signal is too weak, it keeps trying forever. And by the time it finally connects, the temperature sensor has been heated up too much by the ESP and the datapoint is useless.

How could I program it to try connecting for 5s max, and if it fails to do so, go to sleep and try again next time?

esphome:
  name: esp-am2320
  platform: ESP8266
  board: d1_mini
  on_boot:
    - globals.set:
            id: t1
            value: !lambda 'return millis();'  
    - wait_until: mqtt.connected
    - component.update: 'esp_am2320'
    - component.update: 'am2320_rssi'
    - globals.set:
            id: t2
            value: !lambda 'return millis();'
    - component.update: 'am2320_timeawake'
    - delay: 0.25s
    - deep_sleep.enter:
globals:
  - id: t1
    type: int
    restore_value: no
    initial_value: "0"
  - id: t2
    type: int
    restore_value: no
    initial_value: "0"
    
wifi:
  ssid: !secret wifi_ssid_iot_d
  password: !secret wifi_password
  manual_ip:
    static_ip: 192.168.2.50
    gateway: 192.168.2.254
    subnet: 255.255.255.0
    dns1: 192.168.2.254
  fast_connect: true

logger:

mqtt:
  broker: 192.168.2.8
  username: 'secret'
  password: 'secret'
  birth_message:
  will_message:

ota:
  password: 'secret'

deep_sleep:
  run_duration: 30s
  sleep_duration: 5min

# Example configuration entry
i2c:

sensor:
  - platform: am2320
    setup_priority: -100
    id: 'esp_am2320'
    temperature:
      name: "Living Room Temperature"
      id: "temp_livingroom"
    humidity:
      name: "Living Room Humidity"
      id: "humidity_livingroom"
    update_interval: never
    
  - platform: wifi_signal
    name: "AM2320 WiFi Signal"
    update_interval: never
    id: "am2320_rssi" 
    
  - platform: template
    name: "AM2320 TimeAwake"
    id: "am2320_timeawake"
    lambda: |-
      return (id(t2) - id(t1));
    accuracy_decimals: 0
    update_interval: never
    icon: 'mdi:clock'
    unit_of_measurement: 'ms'

Thanks in advance!

P.S. The 0.25s delay is only there because I was not sure if without it, the ESP might go to sleep before the component.update() was finished. If it’s unnecessary, please also let me know. =)

did you look at the espome documentation? looking at the wifi component might make sense as your question is about wifi and this is specefically addressed in that documentation.

I did, but did not find a solution there.

Do you mean the “reboot_timeout” setting? If I understand correctly, that would cause it to reboot and try to connect to WiFi (immediately) again. Not go back to deep sleep for 5min.

So if the WiFi signal is too weak, it would just keep rebooting/connecting/rebooting/connecting/etc. Right?

What I’m trying to achieve is something like:

Pseudo-code:
connectToWiFi(5); #where 5 stands for “try for 5s”
If (wifi.connected) {do stuff}
Else {deepsleep}

i misunderstood the problem but, yes it will do a boot loop if it can’t connect. You’re likely just not giving it enough time to connect. How long does it take to update in the logs? Is this just a temp/humidity sensor? what’s with also connecting to a broker and to the API?

something simple you could also do is add a transistor to control the power to the temp sensor. This way its not being powered and heating up unless it meets the condition that wifi is connected. This isn’t helpful, i know but some things are better suited for battery powered than other things. Temp/humidity sensors are really easy to power with mains and then hide the esp/sensor somewhere out of sight. It’s far more reliable and let’s you get a real-time stream of data.

It is indeed just a Wemos D1 Mini with a temp/humidity sensor AM2320. Nothing fancy. It has worked fine this way for months.

The problem is it’s now temporarily inside my refrigerator where the wifi signal barely reaches it when the door is closed. Mostly, it connects and updates fine (awaketime ±4.000ms). But then someone moves the milk carton and it cannot connect at all. Then when someone opens the fridge door at some point, it suddenly updates with awaketime 500.000ms and a big temperature spike.

About using both MQTT and API. I actually didn’t even notice that until now you mentioned it. I wrote this code months ago and I guess I messed up. I remember having some problems the API way and then I tried to switch to MQTT to fix it. But I guess it ended up somewhere halfway when I got it to work. And left it like that. Until you just mentioned it, I thought “component.update”, updated it via MQTT.

I guess the whole MQTT section can be removed.

But about your suggestion not having enough time to connect. That’s the point. I don’t want it to try for too long, because that heats up the sensor too much. When it takes 20s to connect, a temperature spike can already be observed.

About your second post. It’s not the sensor that is self-heating. The ESP itself is getting warm and the sensor is located right next to it inside the same casing.
I’m not sure if the ESP heats the air in the casing. Or if it conducts the heat through the same plastic they are both glued to. But either way: ESP on for too long ==> sensor gives temperature spike.

I know, it’s a bad design. When I made it, I underestimated how quickly and how much the ESP heats up.

I actually made a “how not to make a temp sensor” topic after I built it. =p

ya, it updates via API and i’m not sure if the mqtt section that isn’t being used is having an impact on connection speeds or not but, if it’s not being used at all, it’s just one less thing(task) the esp has to do within the limited window it’s awake so personally i’d remove it. One thing you could do since I assume drilling holes for a probe isn’t something your eager to do? you could just take 2 readings and apply an offset. So, for example put an esp/temp sensor in there that isn’t in a case and see what the differences are between that esp and the one in the enclosure. So if at 10 seconds the difference is 1.5 degrees higher inside the enclosure than the one in open air than apply that difference as an offset. The fridge should stay at an ideal temperature with little fluctuation so you should be able to calculate with good accuracy, how much the temp rises over a period of time in it’s enclosure

Yeah, I thought about doing that at some point in time. But a reading every 5min has been fine for me. It still is. I don’t really need real-time updates. Plus, the offset would be different at different ambient temperatures (in this current fridge case that would not be an issue indeed).

But it wouldn’t help with this current problem. Because the time it’s “stuck” connecting varies. The longer it’s stuck, the hotter it gets. Of course it stabilises at some point. But then I’d have to calibrate it for multiple “TimeAwake” durations.

I thought that is a bit too much compared to “simply” having it give up after 5 or 10s of trying to make a connection and go back to sleep. But I guess it’s not as simple as I thought.

There is always the backup option of skipping ESPHome alltogether and program it manually with the Arduino IDE and MQTT. That way I know how to do it. But I was hoping for a way to do it with ESPHome.

If you can’t reliably establish a network connection then switching to mqtt doesnt solve your problem, you still have the same problem. You wouldn’t use a static value for the offset. The offset would be directly correlated to the time it takes. If after 10 seconds the temp raises by 1 degree then you a .1 degree change per second so if it takes 10 seconds one time and 7 another time, you just multiply the time by the rate of .1 to get your offset each time. IDK man, I’d rather discuss the relevance of a temp sensor in the fridge opposed to a more practical approach of a reed switch on the door or a power monitoring device. Neither will give you the temperature but they will give you data just as useful. Has the door been left open? Is the fridge power requirements spiking from what is normal and indicating a problem? Either of those will draw your attention to an issue with your fridge without fighting with getting a signal though a fridge or having the thing in the way in the fridge. You know what they say? There’s more than one way to skin a cat! You can fight the thing all the way or you can whack it over the head and skin it easier.

It’s not that MQTT vs API will solve the problem. But being able to go back to deep sleep after 10s of failing to connect to WIFI. I can do that no problem with the Arduino IDE. I just don’t know how to do it using ESPHome. And as far as I know, I can’t use the HA API when programming it with the Arduino IDE.

I don’t need a door sensor. It has one built in which starts beeping after 2min of door open. And I already monitor the energy consumption using a Tuya plug. Which is actually why I want to monitor the temperature for a couple of days, because the power consumption is raising some questions. But that’s a long and offtopic story.

I’m not sure how to go about accessing HA api in Arduino but I know you can. When people make new esphome integrations, they’re often with Arduino and use all the common libraries. I’ve never been interested in a fridge temp but you’ve got voltage going to a door sensor and the lights. Seems like it would be easier to pull power from one of those spots than anything else. IDK though, i’m a little bias because i’m not a big fan of battery powered. The antenna on the esp32 is supposed to be better(stronger). Have you tried either using an esp32 or if you have any mini wifi AP’s then move those closer to your fridge to get a better signal? What’s weird is I have a barn on my property that’s 50’ from the house with sheet metal panels covering the walls and i have esp nodes out there without an AP and they get 40% signal strength. I installed a landscape light controller on my screened in porch and the wifi kept dropping out, yet it’s 50’ closer to the router than the barn esp nodes. I can only surmise that some things cause more interference than others.

I don’t see a benefit of powering it from the fridge. The wifi signal wouldn’t improve that way. Even if the ESP was on all the tine it would theoretically last 6 days on the (10Ah) powerbank drawing 70mA. If I’d want it there permanently, that would be a different story. But I only need it to log for 2 days.

The wifi router is actually only 50-75cm away. The fridge is against the (plaster and thin wood) wall. And right behind that wall is the router. I think the fridge is simply a good Faraday cage. Plus the (probably grounded) condensor on the back is also an excellent RF forcefield. =p
And also the Wemos D1 antennas suck in general in my opinion. Compared to my phone’s wifi for example. My phone can stream 1080p video @ 5 Mbit (IP Webcam) from inside the fridge. The Wemos can barely connect to the wifi.
Or maybe there is just a large variance between modules where some are good and some are bad. But in my experience, all 8266s with pcb antennas I worked with until now have had MUCH less range than my phone. Never tried 32s.

If I would put a repeater somewhere in the kitchen (on the fridge side of the wall and not behind the condensor), it would probably solve it. But I don’t feel like buying a repeater just for those 2 days of logging. Especially since the current signal is enough to connect fine 4 out of 5 times.

I will just write a temporary firmware in Arduino IDE which makes it go to back to deep sleep when it fails to connect for 10s.

If someone knows how to do this in ESPHome, please share so others can benefit from it it they face a similar problem. And so I know how to for the future.

I just do my own timeout.

esphome:
  on_boot:
    then:
      - script.execute: sleep_no_connect

script:
  - id: sleep_no_connect
    then:
      - delay: 20s
      - if:
          condition:
            [whatever shows not connected in your case]
          then:
            - deep_sleep.enter: deep_sleep_1

Thanks! I think that is partially what I’m was looking for.

So I put this:

then:
      - script.execute: sleep_no_connect 

Above my other stuff in the “on_boot” section?

And do I understand correctly that this way the esp will always first wait for 10s, before proceeding with the other stuff (updating sensors)?

So:

  • Wait 10s
  • Check wifi connection
  • if not connected: deep sleep, if connected: proceed
  • component.update
  • deep sleep

If so, is there also a way to have it like this:?

  • component update
  • when component.update is finished, deep sleep
  • 10s after component.update started, check wifi connection
  • if not connected, abort component update and deep sleep

The way I’ve done it the script starts immediately on boot, and will put the ESP to sleep after 20 seconds if the condition is met, in my case I test for “haven’t connected to home assistant yet”. Everything else still runs in parallel.

In your case it seems you’re hanging on the “wait until MQTT is connected”, so if you set the condition as “mqtt not connected” it’d go to sleep if still not connected after the set timeout, seems to be what you want.

Aah OK. That is indeed exactly what I was trying to accomplish. I thought it would run sequentially, not in parallel.

Will try it tomorrow. Thanks!