Skip to content

Instantly share code, notes, and snippets.

@BrianAker
Created September 2, 2023 04:48
Show Gist options
  • Save BrianAker/64ab1f9d4fa94c62d75c496c808c0043 to your computer and use it in GitHub Desktop.
Save BrianAker/64ab1f9d4fa94c62d75c496c808c0043 to your computer and use it in GitHub Desktop.
Sniff all blue traffic via esp home and insert it into MQTT.
esphome:
name: esp-sniffer
friendly_name: esp-sniffer
includes: std_includes.h
esp32:
board: esp32-s3-devkitc-1
framework:
type: arduino
# Enable logging
logger:
mqtt:
id: mqtt_client
broker: !secret mqtt_broker
username: !secret mqtt_username
password: !secret mqtt_password
discovery: False
# Enable Home Assistant API
api:
encryption:
key: XXXX
ota:
password: XXXX
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
esp32_ble_tracker:
scan_parameters:
active: false
on_ble_advertise:
- then:
- lambda: |-
if (x.get_ibeacon().has_value()) {
std::string uuid;
esp_bt_uuid_t raw_uuid = x.get_ibeacon().value().get_uuid().get_uuid();
char sbuf[64];
char *bpos = sbuf;
switch (raw_uuid.len) {
case ESP_UUID_LEN_128:
for (int8_t i = 0; i <= 15; i++) {
sprintf(bpos, "%02x", raw_uuid.uuid.uuid128[i]);
bpos += 2;
if (i == 6 || i == 8 || i == 10 || i == 12)
sprintf(bpos++, "-");
}
sbuf[47] = '\0';
uuid.assign(sbuf);
break;
default:
uuid = x.get_ibeacon().value().get_uuid().to_string();
std::transform(uuid.begin(), uuid.end(), uuid.begin(), [](unsigned char c){ return std::tolower(c); });
break;
}
char mbuf[32] = {0};
sprintf(mbuf, "-%hu-%hu", x.get_ibeacon().value().get_major(), x.get_ibeacon().value().get_minor());
uuid.append(mbuf);
int8_t tx_power = x.get_ibeacon().value().get_signal_power();
if (tx_power >= 100) {
tx_power = -69;
}
float dist = pow(10, (float)(tx_power - x.get_rssi()) / (10 * 2));
std::stringstream service_uuids;
for (auto uuid : x.get_service_uuids()) {
service_uuids << uuid.to_string() << " ";
}
std::string service_uuids_string = service_uuids.str();
std::stringstream advertised_service;
for (auto data : x.get_service_datas()) {
advertised_service << data.uuid.to_string() << " (length " << data.data.size() << ") ";
}
std::string advertised_service_string = advertised_service.str();
std::stringstream manufacturer_data;
for (auto data : x.get_manufacturer_datas()) {
manufacturer_data << data.uuid.to_string() << " (length " << data.data.size() << ") ";
}
std::string manufacturer_data_string = manufacturer_data.str();
std::stringstream ss;
ss << "beacons/" << x.address_str();
std::string ss_string = ss.str();
ESP_LOGD("ble_adv", "Sending MQTT ble update for '%s' (%s): %.03fm (%d rssi, %d sigpow)",
x.get_name().c_str(), uuid.c_str(), dist, x.get_rssi(), tx_power);
id(mqtt_client).publish_json(ss_string.c_str(), [=](JsonObject root) {
root["id"] = uuid;
root["name"] = x.get_name();
root["address"] = x.address_str().c_str();
root["service_uuids"] = service_uuids_string.c_str();
root["advertised_service"] = advertised_service_string.c_str();
root["manufacturer_data"] = manufacturer_data_string.c_str();
root["distance"] = dist;
root["rssi"] = x.get_rssi();
root["tx_power"] = tx_power;
});
}
@BrianAker
Copy link
Author

You will also need to create a file in your ESPHome directory named std_includes.h with the following contents:
#include // std::stringstream
#include // std::fixed
#include // std::setprecision

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment