ESPHome & Airthings Wave Radon

Newbie here. I’ve an Atom Lite running ESPHome serving as a BLE proxy for Airthings Wave Radon (Gen 2) Sensor. This integration works fine until the Airthings device becomes unavailable at seemingly random times. Reloading the Airthings BLE integration gives me this error:

To fix this issue (temporarily until it happens again), I have to remove the device and re-start the Atom Lite for then to have the device re-discovered (automatically) and then added back in to action.

I have verified (through nRF Connect for Mobile App) that the wave radon signal is alive, strong, and broadcasting, so it’s not an Airthings issue.

Has anyone have experienced something similar?

Hi,

I have an old Airthings Wave Plus and - as far as I remember - it can only connect to one Bluetooth device. I have never used the Airthings App on my phone, since I have my ESP32 getting the data. (I am not using the Airthings integration in HomeAssistant, but the ESPHome integration…)

Could this be your issue?

The first time it happened, I thought that was the issue; i.e., that I still had the Airthings App paired with the Wave Radon, but even after unpairing, it still happened again.

Now, forgive my ignorance, how do you integrate the Wave device without the Airthings BLE integration? in my case the Atom Lite YAML has these settings:

# 3. BLUETOOTH TRACKING
esp32_ble_tracker:
  scan_parameters:
    active: true
esp32_ble:
  max_connections: 5
bluetooth_proxy:
  active: true

which I believe is what makes Home Assistant recognize the device through the Airthings BLE integration, so it’s not that it is connecting twice; it’s simply reading the data relayed by the ESP32 device.

Hi @caerus,

I am using a cheap ESP32 with Bluetooth based on this:

This is my yaml:

# source: https://esphome.io/components/sensor/airthings_ble



# Variablen
substitutions:
  device_name: "esphome-dachzimmer2"
  friendly_name: "Dachzimmer2"
  node_name: "esphome_dachzimmer2"
  device_description: "Sensor liest den Airthings Wave Plus Sensor via Bluetooth aus"




# ESPHome Core Configuration
esphome:
  name: '${device_name}'
  friendly_name: '${friendly_name}'
  comment: '${device_description}'




esp32:
  board: esp32dev
  framework:
    type: esp-idf
    

# Enable logging
logger:
  level: INFO


# Airthings Wave Plus finden
esp32_ble_tracker:
  scan_parameters:
    active: false
# airthings_ble:



# Enable Home Assistant API
api:
  encryption:
    key: "0M3EfqCKcU="

ota:
  - platform: esphome
    password: "6f3feedd8f"


wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  min_auth_mode: WPA2
  manual_ip:
    # Set this to the IP of the ESP
    static_ip: 192.168.30.17
    # Set this to the IP address of the router. Often ends with .1
    gateway: 192.168.30.1
    # The subnet of the network. 255.255.255.0 works for most home networks.
    subnet: 255.255.255.0
    dns1: 192.168.0.5
    dns2: 192.168.30.1
  use_address: ${device_name}.internal
  domain: .internal


# Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: '${device_name}'
    password: !secret ap_password
    ap_timeout: 5min  # AP schaltet sich nach 5 Minuten ab


captive_portal:
    



# enable web interface on device
#web_server:
#  port: 80



# Zeit von HomeAssistant abfragen -> für Last Boot nötig
time:
  - platform: homeassistant
    id: homeassistant_time
    on_time_sync:
      then:
        - lambda: |-
            auto now = id(homeassistant_time).now();
            auto uptime = (int) id(${node_name}_uptime_seconds).state;

            ESP_LOGD("last_boot", "Zeit synchronisiert. Aktuelle Zeit: %d, Uptime: %d", now.timestamp, uptime);

            if (!now.is_valid()) {
              ESP_LOGE("last_boot", "Fehler: Zeit ist ungültig.");
              return;
            }

            if (uptime <= 0) {
              ESP_LOGW("last_boot", "Warnung: Uptime ist noch 0 Sekunden.");
              return;
            }

            id(${node_name}_last_boot_time).publish_state(now.timestamp - uptime);
            ESP_LOGI("last_boot", "Last Boot wurde erfolgreich gesetzt.");




switch:
  - platform: restart
    name: "ESPHome '${friendly_name}' neu starten"


text_sensor:
  # Send IP Address
  - platform: wifi_info
    ip_address:
      name: IP Address




ble_client:
  - mac_address: 80:6F:B0:XX:F0:28
    id: awp_Dach





sensor:
  # Airthings Wave Plus Dachzimmer
  - platform: airthings_wave_plus 
    ble_client_id: awp_Dach
    update_interval: 5min # default
    battery_update_interval: 24h # default
    temperature:
      name: "Dach Temperatur"
      id: awp_Dach_temp
      accuracy_decimals: 1
    radon:
      name: "Dach Radon"
      id: awp_Dach_Radon
    radon_long_term:
      name: "Dach Radon Long Term"
      id: awp_Dach_Radon_long
    pressure:
      name: "Dach Luftdruck"
      id: awp_Dach_pressure
    humidity:
      name: "Dach Feuchtigkeit"
      id: awp_Dach_humidity
    co2:
      name: "Dach CO2"
      id: awp_Dach_co2
    tvoc:
      name: "Dach VOC"
      id: awp_Dach_voc
    illuminance:
      name: "Dach ambient light"
      id: awp_Dach_light
    battery_voltage:
      name: "Dach Batterie Spannung"
      id: awp_Dach_volt



  # Airthings Wave Plus Dachzimmer: Batterieanzeige in %
  - platform: copy
    source_id: awp_Dach_volt
    name: 'Dach Battery Level'
    id: awp_Dach_battery
    unit_of_measurement: "%"
    device_class: battery
    accuracy_decimals: 0
    filters:
      - calibrate_linear:
        - 2.2 -> 0
        - 3.1 -> 100



# Airthings Wave Plus Dachzimmer: Taupunkt berechnen 
  - platform: template
    name: "Dach Taupunkt"
    lambda: |-
      return (243.5*(log(id(awp_Dach_humidity).state/100)+((17.67*id(awp_Dach_temp).state)/
      (243.5+id(awp_Dach_temp).state)))/(17.67-log(id(awp_Dach_humidity).state/100)-
      ((17.67*id(awp_Dach_temp).state)/(243.5+id(awp_Dach_temp).state))));
    device_class: temperature
    state_class: measurement
    unit_of_measurement: °C
    update_interval: 5min
    icon: 'mdi:thermometer-water'




    # Last Boot Sensor definieren (Berechnung findet einmalig beim Boot statt)
  - platform: uptime
    id: ${node_name}_uptime_seconds
    name: "Uptime Sekunden"
    internal: true

  - platform: template
    name: "Last Boot"
    id: ${node_name}_last_boot_time
    device_class: timestamp
    entity_category: diagnostic
    accuracy_decimals: 0
    update_interval: never # Kein regelmäßiges Update nötig


  - platform: internal_temperature
    name: "interne Temperatur"

Please take my appologies for the German fragments within the yaml.

The ESP32 is then integrated into HomeAssistant via the ESPHome-integration.

1 Like

Thank you for your reply. I was able to re-configure using just the ESP32 and avoiding the BLE integration. I will report back if there are no breakup in connectivity. I do think this is likely to succeed.
I found it interesting that the Wave Gen2 does not advertise the pressure sensor. I wonder why?