How can I periodically broadcast the latest switch state to all ESP-NOW nodes using packet_transport?

Hello everyone,
I am using ESPHome with the packet_transport ESP-NOW backend. My setup includes one hub device and multiple nodes. The nodes successfully receive sensor values from the hub when the hub sends data proactively.
However, I need the opposite flow as well:

I want the hub to periodically broadcast (every few seconds) the current state of a GPIO switch to all nodes, so each node can stay synchronized with the hub.

My questions are:

  1. How can I make the hub push the latest switch state using packet_transport at a fixed interval?
  2. Is there a built-in mechanism for publishing a switch state (similar to sensor update intervals)?
  3. Do I need to wrap the switch state inside a virtual sensor and publish it via packet_transport.sensors:?
  4. Is there any recommended way to ensure all nodes always stay synchronized with the hub’s switch state, even if they reboot?

Below is a simplified version of my hub configuration:
espnow:
id: espnow_component
channel: 5
peers:
- ${mac_node}

packet_transport:

  • platform: espnow
    update_interval: 5s
    id: transport_unicast
    espnow_id: espnow_component
    peer_address: ${mac_node}
    #encryption: “HubSecret123”
    sensors:

    • temp_sensor

    binary_sensors:

    • hub_signal_sender

sensor:

  • platform: internal_temperature
    update_interval: 60s
    id: temp_sensor
    name: “Test Temperature”

switch:

  • platform: template
    id: hub_led_switch
    name: “Control Node LED”
    optimistic: true

I need guidance on how to periodically transmit this relay state through ESP-NOW to all nodes.

Any suggestions or best practices would be appreciated.

I don’t see any “opposite flow” here. In both cases Hub sends data to nodes.

If you want to send the switch state, make a template binary sensor and use it just same way you use temp sensor.

binary_sensor:
  - platform: template
    name: "Hub LED State"
    device_class: light
    lambda: |-
      return id(hub_led_switch).state;

Ps. Post your code using code tags.

espnow:
  id: espnow_component
  
  peers: 
     - ${mac_node}

packet_transport:
  - platform: espnow
    update_interval: 5s
    id: transport_unicast
    espnow_id: espnow_component
    peer_address: ${mac_node}
    #encryption: "HubSecret123"
    sensors:
      - temp_sensor

    binary_sensors:
      - hub_signal_sender
    
  
    

sensor:
  - platform: internal_temperature
    update_interval: 60s
    id: temp_sensor
    name: "Test Temperature"
 







switch:
  - platform: template
    id: hub_led_switch
    name: "Control Node LED"
    optimistic: true
    



binary_sensor:
  - platform: template
    id: hub_signal_sender
    name: "Internal Signal Sender"
    internal: true
    lambda: |-
      return id(hub_led_switch).state;
    

I noticed that binary sensors sent via packet_transport only transmit their state when it changes, unlike normal sensors which can send their value periodically.

That’s how binary sensors are, they get updated only by state change of something instead of polling. Makes sense?


Binary sensors only updating on state-change is exactly the problem.
In ESP-NOW setups this behavior is not acceptable, because nodes that reboot or miss packets never receive the current state unless it changes again.

Regular sensors support periodic updates. Binary sensors don’t — and that creates a permanent desync between hub and nodes.

We need a way for packet_transport binary sensors to push their state on an interval, same as normal sensors. Without periodic transmission, binary states cannot stay synchronized across devices.

Makes sense.

Try with normal sensor, you can flip it back to binary on the receiving side if needed.

sensor:
  - platform: template
    name: "Hub LED Numeric Sensor"
    lambda: |-
      return id(hub_led_switch).state ? 1 : 0
    update_interval: 60s

numeric to binary conversions is not an ideal long-term solution

I didn’t say it’s ideal :wink:


If update_interval is added to binary_sensor, the problem will be fully resolved. Periodic retransmission would allow nodes to always receive the current state, even without a state change.


I doubt they will change binary sensor from event-driven to polling, but you can try… Better option would be parameter for packet_transport to broadcast all sensors independently if the state has changed or not.

For now I believe you have to go with less ideal solutions.

1 Like

That is what is supposed to happen (already does for UDP) using the packet_transport update interval. See [packet_transport] Ensure retransmission at update intervals by clydebarrow · Pull Request #12472 · esphome/esphome · GitHub

You should be using the binary_sensor switch platform rather than template.

2 Likes