ESP32 Bluetooth Proxy Devices OK on Primary Network subnet but always show offline in ESPHome when on IoT VLAN Network?

First off, I have looked at many threads and forums on this and cannot find an answer that fits my case; I apologise if I missed something,

I run HA and have some small H&T (Xiaomi) devices that I wanted to connect more reliably in the corners of the house, so went for some cheap Bluetooth Proxy ESP32 devices to play around with. I got them set up OK with the HA BT Proxy setup page initially (for the plain ESP32 device type), then proceeded to use a custom YAML for a non-supported device, an ESP32-C3.

This all worked fine when I was just using an IoT Network setup as a Guest Network, on (Guest Network) GN2 which uses the same subnet as the Primary LAN.

However, tinkering as you do, when I got a VLAN capable Router cheap 2nd hand (ASUS RT-AXX88U Pro) recently I thought I would set up a VLAN (different subnet) for all my IoT Devices, using Guest Network Pro.

Oddly, while the ESP32 devices showed they were actually connected to the new IoT Wifi Network in the Wireless Log, in ESPHome they were constantly shown as “Offline”; and the ‘Logs’ check did not find any Wifi connection, it stopped at:

WARNING Can't connect to ESPHome API for esp32btproxy @ 192.168.53.108: Timeout while connecting to [AddrInfo(family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, proto=6, sockaddr=IPv4Sockaddr(address='192.168.53.108', port=6053))] (TimeoutAPIError)
INFO Trying to connect to esp32btproxy @ 192.168.53.108 in the background

So my question is, what is it about the separate LAN (subnet 53 i.e.192.168.53.1 vs my Primary LAN 192.168.9.1). that might cause this?

I started reading about mDNS but it seemed rather advanced… any ideas that I can investigate and then make adjustments I need to, maybe Router / LAN network related as opposed to ESP32 and YAMLs etc of course) would be really appreciated. Thanks. I know I can put the IoT Network back on the Primary subnet but that sort of defeats the purpose of the VLAN.

I can supply my ESP32 YAML files later if that helps.

As you have read the issue is probably mDNS - it will not cross network boundaries.

Turn on “use ping” for ESPHome, go to:

Settings, Add-ons, ESPHome Device Builder, Configuration, Show unused optional configuration options, use ping for status.

This is assuming they still are reachable from HA and can be pinged from the original network.

Thank you for quick response, appreciated.

Sorry, I forgot to mention I did actually try that (and restarted ESPHome) but it did not seem to get past the issue.

What I have tried (from the many threads on the subject):

  • Updating/Installing with the devices plugged into the HA Server (a RPi4)
  • I have Static IP Address set in the Router
  • I have tried the fast_connect: on (or true) options
  • I have tried the Manual IP Option
  • I have tried setting the ESPHome Device Builder (Configuration Tab) to the ping option (vs using mDNS)
  • I did not try the switch power_save_mode: none option because this is apparently incompatible with esp32_ble
  • I stopped and restarted the ESPHome Addon, I do not have underscores in the device names either in the Router or in the YAML or secrets.

k.

So it is only the BLE proxies that don’t connect? All others work?

That is correct. I have a number of IoT devices that have no problem with the VLAN and appear in HA.

Maybe post yaml for a node that works on the VLAN, and for one that doesn’t.

I’m not quite sure what you mean, I actually only have YAMLs for the ESP32s.

The other devices I was referring to that are on the IoT VLAN are things like a Camera, TPLink Smart Plugs, some Alexa Echo Dots and Sensibo A/C changes, a Fridge etc.

I am posting the yamls in any case.

substitutions:
  name: "esp32btproxy"
  friendly_name: ESP32 BT Proxy
  display_name: esp32btproxy

# ESPHome referenced the github file and I used whatever was NOT in this YAML (which is the default config) 
# packages: #esphome.bluetooth-proxy: github://esphome/bluetooth-proxies/esp32-generic/esp32-generic.yaml@main

esphome:
  name: ${name}
  friendly_name: ${friendly_name}
  min_version: 2025.2.1
  name_add_mac_suffix: false

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

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  fast_connect: off # Optional. Required (true) if connecting to a hidden SSID; suggest disable if setting Manual IP
  # power_save_mode: none # Optional, default for ESP32 is Light; do NOT use with esp32_ble

  ap: # Enable fallback hotspot (captive portal) in case wifi connection fails
    ssid: ${display_name}
    password: !secret wifi_ap_password

# Optional Manual IP 
  manual_ip:
    static_ip: 192.168.53.108
    gateway: 192.168.53.1
    subnet: 255.255.255.0
#    gateway: !secret gateway
#    subnet: !secret subnet

captive_portal:

api:
  encryption:
    key: !secret encryption_key

logger:
  level: DEBUG # Debug=Default; use Verbose if error checking

# Allow Over-The-Air updates
ota:
- platform: esphome
  password: !secret ota_password
  id: ota_esphome

esp32_ble_tracker:
  scan_parameters:
    # We currently use the defaults to ensure Bluetooth
    # can co-exist with WiFi In the future we may be able to
    # enable the built-in coexistence logic in ESP-IDF
    active: true

bluetooth_proxy:
  active: true

button:
  - platform: safe_mode
    id: button_safe_mode
    name: Safe Mode Boot

  - platform: factory_reset
    id: factory_reset_btn
    name: Factory reset

time:
  - platform: homeassistant
    id: homeassistant_time
substitutions: # name substitutions suggested by Digiblur see https://digiblur.com/wiki/ha/esphome-bluetooth-proxy-esp32c3/
  display_name: esp32c3btproxy

esphome:
  name: ${display_name}
  friendly_name: ESP32 C3 BT Proxy
  min_version: 2024.11.0
  name_add_mac_suffix: false

# the next lines are also from Digiblur
  platformio_options:
    board_build.mcu: esp32c3
    board_build.variant: esp32c3  
# added the line below to prevent bootloops when flashing modern bin via serial
    board_build.flash_mode: dio

# Suggested ble_tracker amendments for esp32c3 from https://github.com/esphome/issues/issues/3668#issuecomment-1493423796
# This amendment also fixes the 'WARNING Can't connect to ESPHome API' 'Errno 113 'SocketAPIError'
  on_boot:
   then:
     - wait_until:
         condition:
          wifi.connected:
     - lambda: >
          id(ble_tracker).set_scan_continuous(true);
          id(ble_tracker).start_scan();

esp32: # also from Digiblur
  variant: ESP32C3
  board: esp32-c3-devkitm-1
  framework:
    type: esp-idf
    sdkconfig_options:
      CONFIG_BT_BLE_50_FEATURES_SUPPORTED: y
      CONFIG_BT_BLE_42_FEATURES_SUPPORTED: y
      CONFIG_ESP_TASK_WDT: y
      CONFIG_ESP_TASK_WDT_TIMEOUT_S: "10"    

logger: # Enable logging
  level: DEBUG # Debug=Default; use Verbose if error checking

api: # Enable Home Assistant API; MUST check option under ESPHome Configure!
  encryption:
    key: !secret encryption_key
  
ota: # Allow Over-The-Air updates
- platform: esphome
  password: !secret ota_password
  
wifi:
  reboot_timeout: 3min
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  fast_connect: off # Optional. Required (true) if connecting to a hidden SSID; suggest disable if setting Manual IP

  ap: # Enable fallback hotspot (captive portal) in case wifi connection fails
    ssid: ${display_name}
    password: !secret wifi_ap_password

# Optional Manual IP
#  manual_ip:
#    static_ip: 192.168.53.109
#    gateway: !secret gateway
#    subnet: !secret subnet

# Suggested ble_tracker amendments for esp32c3 from https://github.com/esphome/issues/issues/2941#issuecomment-1842369092
  on_connect:
    - esp32_ble_tracker.start_scan:
        continuous: true
  on_disconnect:
    - esp32_ble_tracker.stop_scan:

captive_portal:
    
bluetooth_proxy:
  active: true # Optional, defaults to false

esp32_ble_tracker:
  id: ble_tracker
  scan_parameters:
    interval: 800ms # default 1100ms
    window: 800ms # default 1100ms
    continuous: true

button:
  - platform: safe_mode
    id: button_safe_mode
    name: Safe Mode

  - platform: factory_reset
    id: factory_reset_btn
    name: Factory Reset

time:
  - platform: homeassistant
    id: homeassistant_time

Apologies - I thought you had other ESPHome devices that worked.

Yaml looks fine - pretty basic config. My only thought is that there is a VLAN firewall rule in play blocking port 6053.

It is usually best practice to have your HA server on the same VLAN as the devices - otherwise you are just defeating the purpose of isolation. Then you allow only the server to be connected to on the second VLAN.

No problem, you have been very patient with my queries, thank you.

OK, I am not 100% sure how to add a Firewall Rule (Asus RT-AX88U Pro) but I can probably manage to find out, there’s a source IP (not sure which, the HA Server or the Device IP?) and a port range, presumably 6053?

On the second point, should I move the server to the IoT Network or just make the IoT subnet the same as the server (which is on the Primary LAN). The second approach is probably easier as I have done that before, to test this offline issue.

Hi again, OK, I have now migrated my HA Server to the same LAN as all my IoT Devices.

Ignoring the security implications of that for now, if any, and referring to the original question regarding connecting I have a further question.

You noted above that my YAML seems OK, although there was one thing I had not said that might have had a bearing on this, it is that I use a Hidden SSID.

While still a little slow (the first time) the connection actually works OK with

fast_connect: true

with that hidden SSID. It also works OK with

fast_connect: off

when I unhide my SSID (which I prefer not to to do).

I read (sorry cannot find it now) on someone’s comment in a YAML to use a manual IP to connect to hidden SSIDs. The Espressif documentation notes a similar thing.

Most folks on the ESPHome subform seem to say that fast connect is the only way to get past a hidden SSID; i.e. it is an imperative to use it.

However with fast connect: off, which I prefer due to the downsides, as I would really like the devices to occupy the mesh nodes I put in various far flung corners of the house, unfortunately just setting up the manual IP still did not work for me; should it or is this just flogging a dead horse?