Loosing my mind. Esphome, deep sleep and Mqtt won't work together

Nothing should happen when you execute the scripts, the script are only “setting the message” on the server, and by the way they need to be Retain: True on both (I think) in order for the ESP to “pick it up” when it is rebooting from sleep and connection to the MQTT server.

The order is this: You set a retained message on the MQTT server, the server does nothing but “holds” this message on this topic. The ESP then wakes up (after your 300s deep sleep), connects to the MQTT server and receives a message (since it is configured to subscribe to that topic), and if a message with the payload ON is received the ESP won’t go back to sleep. You can then issue an update, send a new message with the topic OFF to the server. Reboot the ESP, it will then pick up an OFF payload and initialize sleep again.

This looks correct, assuming that the NodeMCU have a built in voltage divider this is correct… You have 3.2 before your divider, the ESP “sees” 0.95V.

The “raw” value that the ESP is reading is… your output of 0.73 / 2.666667 = 0,27375… that multiplied with the “internal” 3.3V voltage divider (which is probably not that accurate in terms of exact ohm values) gives 3.3 * 0.27375 = 0,903 V which is close enough to your output… I am not an electrical engineer but I think this is correct :slight_smile:

now i just need to figure why the mqtt broker can’t be reached outside the raspberry pi

do the sd card images with HA on them have a firewall i need to disable?

Not that I am aware of. And you have the MQTT broker on the raspberry and they are on the same network as the ESP? And the IP-address set for the broker is correct? And no rules on the WiFi like a guest network that the ESP is connected to? This would prevent the ESP to reach any local devices.

correct

yes, i reach HA at 192.168.0.9:8123 so i assume the broker is at 192.168.0.9

from integrations i click configure on the mqtt broker and i have the options to listen to a topic hence i know it works on the pi itself

nope i have not enabled guest networks, those are unsafe and everyone near my house would be able to connect and download illegal stuff and i would get the blame

my esp had the ip 192.168.0.231 and if i enable webinterface on it i can see the temeperature etc on it, i did that on purpose to test that the BME280 sensor was working correctly and that battery voltage was correct

my thought is that the broker only works on localhost on the pi and not on eth0 hence it would not be reachable on the local network… or that there is some kind of firewall but like you i doubt that

seems you cant make do without them, even if you have “anonymous: true”

at least with ESP OTA set to on it will post to MQTT constantly, now i just need to figure out my dashboard

mind telling me how you made the dashboard, i cant find the mqtt traffic anywhere so i can put it on my dashboard

There isn’t any real dashboard, it’s just the sensors from the device-view added to standard cards. On one of them there is a added footer graph. I realize my code from april is a bit out of date, it holds for the most part but I have switched to auto discovery: true so changes are handled easier and appears on the integration page. I added some sensors and wanted to simplify some things. So now I have them added through the Integration page and can add the cards from that view.

substitutions:
  devicename: wemos_weather_station
  friendly_devicename: weather station

esphome:
  name: $devicename
  platform: ESP8266
  board: d1_mini_pro

wifi:
  fast_connect: true
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  manual_ip:
    static_ip: 192.168.1.201
    gateway: 192.168.1.1
    subnet: 255.255.255.0

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Wemos WS Fallback Hotspot"
    password: !secret ota_password

#NO API when using battery device
#
# api:
#   password: !secret api_password

mqtt:
  broker: '192.168.1.7'
  username: !secret mqtt_username
  password: !secret mqtt_password
  discovery: true
  discovery_retain: true
  birth_message:
  will_message:
  on_message:
    - topic: esp/ota_mode
      payload: 'ON'
      then:
        - deep_sleep.prevent: deep_sleep_1
    #####################  Another way to do deep sleep variations...
    # - topic: esp/sleep_mode_summer
    #   payload: 'ON'
    #   then:
    #     - lambda: |-
    #         id(deep_sleep_1).set_sleep_duration(60000);
    # - topic: esp/sleep_mode_winter
    #   payload: 'ON'
    #   then:
    #     - lambda: |-
    #         id(deep_sleep_1).set_sleep_duration(180000);

# Enable logging
logger:
  level: INFO
  # level: DEBUG

ota:
  password: !secret ota_password

i2c:
  sda: D1
  scl: D2
  scan: true
  id: bus_a

dallas:
  - pin: D5

sensor:
  - platform: dallas
    address: 0x9880000027076228
    name: "Outdoor temperature 2"
    id: temp1
    accuracy_decimals: 2
    filters:
      filter_out: nan

  # OLD DALLAS SENSOR FROM BEFORE BME280
  # - platform: dallas
  #   address: 0x2D80000027110B28
  #   name: "Outdoor temperature 3"
  #   id: temp2
  #   accuracy_decimals: 2
  #   filters:
  #     filter_out: nan

  - platform: bme280
    address: 0x76
    temperature:
      name: "Outdoor temperature 3"
      id: bme280_temperature
    pressure:
      name: "Outdoor pressure"
      id: bme280_pressure
    humidity:
      name: "Outdoor humidity"
      id: bme280_humidity
    
  - platform: wifi_signal
    name: $friendly_devicename signal strength
    unit_of_measurement: "dB"
    icon: mdi:wifi

# Testing VCC instead (disconnected everything to A0). 
# To reduce constant drain from battery to ground trough the resistors  
  - platform: adc
    pin: VCC
    name: $friendly_devicename VCC
    id: vcc_volt
    icon: "mdi:chip"
    unit_of_measurement: "V"
    update_interval: 1s
    accuracy_decimals: 2

  # OLD Battery code
  # - platform: adc
  #   pin: A0
  #   name: $friendly_devicename battery voltage
  #   id: battery_volt
  #   icon: "mdi:battery"
  #   unit_of_measurement: "V"
  #   accuracy_decimals: 2
  #   update_interval: 4s
  #   filters:
  #     - multiply: 6.1

  - platform: uptime
    name: $friendly_devicename run time
    unit_of_measurement: ms
    icon: mdi:timer-outline
    update_interval: 500ms
    filters:
      - multiply: 1000

  - platform: template
    name: "Outdoor absolute humidity"
    lambda: |-
      const float mw = 18.01534;    // molar mass of water g/mol
      const float r = 8.31447215;   // Universal gas constant J/mol/K
      return (6.112 * powf(2.718281828, (17.67 * id(bme280_temperature).state) /
        (id(bme280_temperature).state + 243.5)) * id(bme280_humidity).state * mw) /
        ((273.15 + id(bme280_temperature).state) * r); // in grams/m^3
    accuracy_decimals: 2
    icon: 'mdi:water'
    update_interval: 4s
    unit_of_measurement: 'g/m³'

  - platform: template
    name: "Outdoor dew point"
    lambda: |-
      return (243.5*(log(id(bme280_humidity).state/100)+((17.67*id(bme280_temperature).state)/
      (243.5+id(bme280_temperature).state)))/(17.67-log(id(bme280_humidity).state/100)-
      ((17.67*id(bme280_temperature).state)/(243.5+id(bme280_temperature).state))));
    unit_of_measurement: °C
    update_interval: 4s
    icon: 'mdi:thermometer-alert'

  - platform: mqtt_subscribe
    name: "Sleep time topic"
    id: custom_sleep_time
    unit_of_measurement: ms
    icon: mdi:timer-outline
    accuracy_decimals: 0
    topic: esp/sleep_mode_time
    on_value:
      then:
       - lambda: |-
          id(deep_sleep_1).set_sleep_duration(id(custom_sleep_time).state);

switch:
  - platform: restart
    id: reboot_esp
    name: $friendly_devicename restart switch

deep_sleep:
  id: deep_sleep_1
  sleep_duration: 300s
  run_duration: 1s

those 2 made it show up as device :smiley:

now i just need to jerryrig a coin cell battery and see how long it will last

do i assume right that is how long it sleeps for before each wake up?
and how do i find out how long it should run if i use dhcp? just connect and see how long it takes before i get the first mqtt? i know it might cost me a bit of battery but it makes life a bit more simple

The run duration is not that important. In my case I set it to one second. In reality the esp take more to boot, connect to wifi, go through the code and then go to sleep again. Normal run times (the run time sensor) are reported as around 4000-5000ms. As long as you don’t need more than one value sent for every sleep cycle you can set the run duration to 1s.

now i just need to jerryrig a coin cell battery and see how long it will last

You should have a look at this video by Andreas: https://youtu.be/IYuYTfO6iOs

i think i better use AA or something similar first and see how long they last.
can always scale up from there

I recently had a project where I used deep sleep. Intention was to have the device sleep whilst i was asleep and awake when I woke up. The method was successful but my battery setup still not sufficiently sized so abandoned the idea. Perhaps useful for others though. Source: https://tatham.blog/2021/02/06/esphome-batteries-deep-sleep-and-over-the-air-updates/

I used ha booleans and input numbers to control the prevent and duration respectively. No reliance on mqqt as the API functionality was sufficient for me. Please double check indentation when using this. I copied it from plain text.

deep_sleep:
  id: deep_sleep_control
  sleep_duration: 1min
  
binary_sensor:
  - platform: homeassistant
    id: prevent_deep_sleep
    name: Prevent Deep Sleep
    entity_id: input_boolean.prevent_deep_sleep
    
script:
  - id: consider_deep_sleep
    mode: queued
    then:
      - delay: 30s
      - if:
          condition:
            binary_sensor.is_on: prevent_deep_sleep
          then:
            - logger.log: 'Skipping sleep'
          else:
            - logger.log: "Time to sleep !!! Hibernating"
            - lambda: |-
                id(deep_sleep_control).set_sleep_duration(id(deep_sleep_duration).state);
            - delay: 1s
            - deep_sleep.enter: deep_sleep_control
      - script.execute: consider_deep_sleep
      
sensor:
  - platform: homeassistant
    id: deep_sleep_duration
    name: Deep Sleep Duration
    entity_id: input_number.deepsleep_duration