core: Platform esphome does not generate unique IDs

The problem

I see the following in my logs:

Platform esphome does not generate unique IDs. ID 8caab5c0c1e2-wifisignal already exists - ignoring sensor.house_energy_meter_wifi_signal
Platform esphome does not generate unique IDs. ID 8caab5c07d6d-wifisignal already exists - ignoring sensor.co2meter_wifi_signal

But as can be seen from the log the id is unique… Help? I have had this issue since 2022.1.0 when I started using esphome.

What version of Home Assistant Core has the issue?

2022.3.2

What was the last working version of Home Assistant Core?

No response

What type of installation are you running?

Home Assistant OS

Integration causing the issue

ESPHOME

Link to integration documentation on our website

https://esphome.io/

Diagnostics information

No response

Example YAML snippet

co2.yaml

---
substitutions:
  device_name: co2meter
  friendly_name: co2meter
  device_description: "Measure your co2 in house"
  tx_pin: D1
  rx_pin: D2
  baud_rate: "9600"
  sda_pin: D6
  scl_pin: D5
  
esphome:
  name: '${device_name}'
  comment: '${device_description}'
  project:
    name: "aqi.home_assistant_co2"
    version: "1.1.3"
  platform: ESP8266
  board: nodemcuv2

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: '${device_name}'

captive_portal:

# Enable logging
logger:
  level: info

# Enable improv over serial
improv_serial:

# Enable Home Assistant API
api:
  services:
    - service: mhz19_calibrate_zero
      then:
        - mhz19.calibrate_zero: "${friendly_name}_mhz19sensor"

ota:
  safe_mode: true
  reboot_timeout: 10min
  num_attempts: 5

web_server:
  port: 80

# Sensors for ESP version and WIFI information
text_sensor:
  - platform: version
    hide_timestamp: true
    name: "${friendly_name} - ESPHome Version"
  - platform: wifi_info
    ip_address:
      name: "${friendly_name} - IP Address"
      icon: mdi:wifi
    ssid:
      name: "${friendly_name} - Connected SSID"
      icon: mdi:wifi-strength-2

time:
  - platform: homeassistant

uart:
  rx_pin: "${rx_pin}"
  tx_pin: "${tx_pin}"
  baud_rate: "${baud_rate}"
  id: myuart1

i2c:
  sda: "${sda_pin}"
  scl: "${scl_pin}"
  scan: True

font:
  - file: "BebasNeue-Regular.ttf"
    id: my_font0
    size: 4
  - file: "BebasNeue-Regular.ttf"
    id: my_font1
    size: 8
  - file: "BebasNeue-Regular.ttf"
    id: my_font2
    size: 13
  - file: "BebasNeue-Regular.ttf"
    id: my_font3
    size: 18

sensor:
  - platform: wifi_signal
    name: "${friendly_name} WiFi Signal"
    update_interval: 30s
    id: "${device_name}_wifi_signal"
  - platform: wifi_signal
    name: "${friendly_name} WiFi Signal Gemiddelde"
    update_interval: 30s
    filters:
    - exponential_moving_average:
        alpha: 0.003 # We want ~6 hour averaging, at 10s update, that's 6*3600/10 = 2160 points, thus alpha should be 2/2160 ~ 0.001 
        send_every: 1
    id: "${device_name}_wifi_signal_gem"


  - platform: mhz19
    id: "${friendly_name}_mhz19sensor"
    co2:
      name: "MH-Z19 CO2"
      id: "${friendly_name}_mhz_19_co2"
    temperature:
      name: "MH-Z19 Temperature"
      id: "${friendly_name}_mhz_19_T"
    update_interval: 30s
    uart_id: myuart1
    automatic_baseline_calibration: false
  - platform: mhz19
    id: "${friendly_name}_mhz19sensor_gem"
    co2:
      name: "MH-Z19 CO2 Gemiddelde"
      id: "${friendly_name}_mhz_19_co2_gem"
      filters:
      - exponential_moving_average:
          alpha: 0.003 # We want ~6 hour averaging, at 10s update, that's 6*3600/10 = 2160 points, thus alpha should be 2/2160 ~ 0.001 
          send_every: 1
    temperature:
      name: "MH-Z19 Temperature Gemiddelde"
      id: "${friendly_name}_mhz_19_T_gem"
      filters:
      - exponential_moving_average:
          alpha: 0.003 # We want ~6 hour averaging, at 10s update, that's 6*3600/10 = 2160 points, thus alpha should be 2/2160 ~ 0.001 
          send_every: 1
    update_interval: 30s
    uart_id: myuart1
    automatic_baseline_calibration: false



  - platform: bmp280
    temperature:
      name: "BME280 Temperature"
      oversampling: 16x
      id: "${friendly_name}_bme_280_temp"
    pressure:
      name: "BME280 Pressure"
      id: "${friendly_name}_bme_280_press"
    address: 0x76
    update_interval: 30s
  - platform: bmp280
    temperature:
      name: "BME280 Temperature Gemiddelde"
      oversampling: 16x
      id: "${friendly_name}_bme_280_temp_gem"
      filters:
      - exponential_moving_average:
          alpha: 0.003 # We want ~6 hour averaging, at 10s update, that's 6*3600/10 = 2160 points, thus alpha should be 2/2160 ~ 0.001 
          send_every: 1
    pressure:
      name: "BME280 Pressure Gemiddelde"
      id: "${friendly_name}_bme_280_press_gem"
      filters:
      - exponential_moving_average:
          alpha: 0.003 # We want ~6 hour averaging, at 10s update, that's 6*3600/10 = 2160 points, thus alpha should be 2/2160 ~ 0.001 
          send_every: 1
    address: 0x76
    update_interval: 30s

display:
  - platform: ssd1306_i2c
    model: "SH1106 128x64"
    address: 0x3C
    pages:
      - id: page1
        lambda: |-
          // Print time in HH:MM format
          // it.strftime(40, 0, id(my_font1), TextAlign::BASELINE_LEFT, "%H:%M", id(sntp_time).now());
          
          it.printf(1,  0, id(my_font2), "CO2");
          it.printf(28, 0, id(my_font3), "%d (%d)  PPM", int(id(${friendly_name}_mhz_19_co2).state), int(id(${friendly_name}_mhz_19_co2_gem).state));
          
          it.printf(1, 17, id(my_font2), "TEMP");
          it.printf(28, 16, id(my_font3), "%.1f (%.1f)  °C", id(${friendly_name}_bme_280_temp).state, id(${friendly_name}_bme_280_temp_gem).state);
          
          it.printf(1, 33, id(my_font2), "Pres");
          it.printf(28, 32, id(my_font3), "%d (%d)  HPa", int(id(${friendly_name}_bme_280_press).state), int(id(${friendly_name}_bme_280_press_gem).state));
          
          it.printf(1, 50, id(my_font2), "WiFi");
          it.printf(28, 48, id(my_font3), "%.1f (%.1f)  dBm", (id(${device_name}_wifi_signal).state), (id(${device_name}_wifi_signal_gem).state));

and homeassistant glow

---
substitutions:
  device_name: home-assistant-glow
  id_name: homeassistantglow
  friendly_name: "House Energy Meter"
  device_description: "Measure your energy consumption with the pulse LED on your smart meter"
  pulse_pin: D1
  status_led: D4
  # imp/kWh rate ⬇ #
  pulse_rate: '5000'

dashboard_import:
  package_import_url: github://klaasnicolaas/home-assistant-glow/home_assistant_glow.yaml

esphome:
  name: '${device_name}'
  comment: '${device_description}'
  project:
    name: "klaasnicolaas.home_assistant_glow"
    version: "3.0.0"
  platform: ESP8266
  board: nodemcuv2

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: '${device_name}'

captive_portal:

# Enable logging
logger:
  level: info

# Enable improv over serial
improv_serial:

# Enable Home Assistant API
api:
  services:
  - service: reset_total
    then:
      - pulse_meter.set_total_pulses:
          id: "${id_name}_sensor_energy_pulse_meter"
          value: 0

ota:
  safe_mode: true
  reboot_timeout: 10min
  num_attempts: 5

web_server:
  port: 80

time:
  - platform: homeassistant

# Sensors for ESP version and WIFI information
text_sensor:
  - platform: version
    hide_timestamp: true
    name: "${friendly_name} - ESPHome Version"
  - platform: wifi_info
    ip_address:
      name: "${friendly_name} - IP Address"
      icon: mdi:wifi
    ssid:
      name: "${friendly_name} - Connected SSID"
      icon: mdi:wifi-strength-2

sensor:
  - platform: wifi_signal
    name: "${friendly_name} - WiFi Signal"
    update_interval: 120s
    id: "${id_name}_wifi_signal"
  - platform: wifi_signal
    name: "${friendly_name} WiFi Signal Gemiddelde"
    update_interval: 120s
    filters:
    - exponential_moving_average:
        alpha: 0.01 # We want ~6 hour averaging, at 10s update, that's 6*3600/120 = 2160 points, thus alpha should be 2/2160 ~ 0.001 
        send_every: 1
    id: "${id_name}_wifi_signal_gem"

  - platform: pulse_meter
    name: '${friendly_name} - Power Consumption'
    id: "${id_name}_sensor_energy_pulse_meter"
    unit_of_measurement: 'W'
    state_class: measurement
    device_class: power
    icon: mdi:flash-outline
    accuracy_decimals: 0
    pin: ${pulse_pin}
    # internal_filter: 100ms
    filters:
      # multiply value = (60 / imp value) * 1000
      # - multiply: 60
      - lambda: return x * ((60.0 / ${pulse_rate}) * 1000.0);
    total:
      name: '${friendly_name} - Total Energy'
      id: "${id_name}_sensor_total_energy"
      unit_of_measurement: 'kWh'
      icon: mdi:circle-slice-3
      state_class: total_increasing
      device_class: energy
      accuracy_decimals: 3
      filters:
        # multiply value = 1 / imp value
        # - multiply: 0.001
        - lambda: return x * (1.0 / ${pulse_rate});
  # Total day useage
  - platform: total_daily_energy
    name: '${friendly_name} - Daily Energy'
    id: "${id_name}_sensor_total_daily_energy"
    power_id: "${id_name}_sensor_energy_pulse_meter"
    unit_of_measurement: 'kWh'
    icon: mdi:circle-slice-3
    state_class: total_increasing
    device_class: energy
    accuracy_decimals: 3
    filters:
      # Multiplication factor from W to kW is 0.001
      - multiply: 0.001


### Anything in the logs that might be useful for us?

_No response_

### Additional information

_No response_

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 23 (8 by maintainers)

Most upvoted comments

Can it be that my avareage signal wifi is not working?

Yes, that’s it (“Two or more wifi_signal entries are in your config”). You can only have one of wifi_signal entry in your config at the moment

It uses different names and uses different ID’s too.

Yes, for most sensors that would work. But wifi_signal sets the unique_id (different thing from id) itself to the mac address of the ESP chip -wifisignal. The user can’t change the unique_id. Tbh, it’s too easy to get this wrong for the user, so we should either implement some incremeting counter like _2 or IMO better, just remove the unique_id here. Then you can’t even get this issue with situation 3 in my previous post).

After looking through the entity platform code, I believe the only way to get that message is if two entities with the same unique_id are registered during a HA session. That means, it doesn’t matter what friendly_name it had, what device/config_entry it belonged to historically, only that not two entities with equal are async_add_entities()'d.

You can test this with this config

sensor:
- platform: wifi_signal
  name: Test32 Wifi Signal

and changing the sensor name to Test32 Wifi Signal 1 / moving it to another ESP chip, all of those work fine (at least for me).

The real cause likely is one of these:

  1. Two or more wifi_signal entries are in your config
  2. You have two config entries pointing to the same device - should no longer be possible if the device is running firmware 2021.11+ and https://github.com/home-assistant/core/pull/64559
  3. You have a stale config entry that was set up with this ESP chip, but isn’t connecting anymore (thus re-registers entities from storage, and doesn’t get notified the old entity no longer exists), and a new config entry for the same ESP chip.

Note: These are dependent on the unique ID being based on the mac address of the ESP. For entities with the default unique ID generation, I think this issue should be resolved with fw 2021.11+ and https://github.com/home-assistant/core/pull/64559.