OK, I wrote a working version.
First you have to create a file “include_set.h”. Containing only one line:
#include <set>
To the esphome section add that:
esphome:
name: corona
platform: ESP32
board: featheresp32
includes:
- include_set.h
on_boot:
priority: 801
then:
- lambda: |
id(ids_seen) = new std::set<std::string>();
Add or change your a globals section:
globals:
- id: ids_seen
type: void*
restore_value: no
And your exposure notifification section should look like:
exposure_notifications:
on_exposure_notification:
then:
- if:
condition:
lambda: |
auto ids_seen_set = (std::set<std::string>*)id(ids_seen);
auto id_as_str = hexencode(x.rolling_proximity_identifier);
if( !ids_seen_set->count( id_as_str ) )
{
ids_seen_set->insert(id_as_str);
ESP_LOGD("main", "Got new notification:");
ESP_LOGD("main", " RPI: %s", id_as_str.c_str() );
ESP_LOGD("main", " RSSI: %d", x.rssi);
return true;
}
else
{
ESP_LOGD("main", "Got existing notification:");
ESP_LOGD("main", " RPI: %s", id_as_str.c_str() );
return false;
}
then:
- text_sensor.template.publish:
id: latest_coronamelder_detected
state: !lambda 'return hexencode(x.rolling_proximity_identifier).c_str();'
It will push every new id into a set and only publish the state when a new id is seen.
Be car full: Every new id will take some RAM. Depending on your board and how many ids you see, your device can get out of memory. You could add an “interval” or “time” section with a daily interval to clear the list once a day/night. They are rolling (very 15 minutes) anyway. But: I think few 100 ids or more should not be problem.
I use a different version:
sensor:
- platform: template
name: "corona_warn_user_last_60s"
update_interval: 60s
unit_of_measurement: User
accuracy_decimals: 0
lambda: !lambda |-
auto idset = (std::set<std::string>*)id(ids_seen);
auto count = idset->size();
idset->clear();
return count;
esp32_ble_tracker:
exposure_notifications:
on_exposure_notification:
then:
lambda: |
auto ids_seen_set = (std::set<std::string>*)id(ids_seen);
auto id_as_str = hexencode(x.rolling_proximity_identifier);
if( !ids_seen_set->count( id_as_str ) )
{
ids_seen_set->insert(id_as_str);
ESP_LOGD("main", "Got new notification:");
ESP_LOGD("main", " RPI: %s", id_as_str.c_str() );
ESP_LOGD("main", " RSSI: %d", x.rssi);
}
That creates a sensor returning the number of users in range of the device using the Corona app.
Sadly the range of my esp32 is really low. Maybe one or two meters without walls.