Skip to content

Instantly share code, notes, and snippets.

@ashald
Created January 19, 2022 23:14
Show Gist options
  • Save ashald/67a228b689c9e40af33426e926d397fb to your computer and use it in GitHub Desktop.
Save ashald/67a228b689c9e40af33426e926d397fb to your computer and use it in GitHub Desktop.
ESPHome-based data exchange between nodes over BLE
#include "esphome.h"
#include <BLEDevice.h>
class BleAddress : public PollingComponent, public TextSensor {
public:
// constructor
BleAddress() : PollingComponent(15000) {}
float get_setup_priority() const override { return esphome::setup_priority::LATE; }
void setup() override {
// This will be called by App.setup()
}
void update() override {
publish_state(BLEDevice::getAddress().toString());
}
};
esphome:
name: ${client_name}
# ...common config omitted for brevity...
# Apparently it's required by ble_client component defined below
esp32_ble_tracker:
ble_client:
- mac_address: !secret server_ble_mac # read it from server logs
id: ble_server
text_sensor:
- id: ble_time
name: "Time Retrieved over BLE"
platform: template
- id: ble_kitchen_co2
name: "Kitchen CO2 over BLE"
platform: template
# For some reasons, there is only BLE sensor, and there is no BLE text_sensor in ESPHome as of today
# Tha being said, it allows executing custom code upon rertieving the data over BLE
# But by default it just only consumes the 1st bye.
# Here we repeatedly employ a pattern where we define sensors that always would return 0,
# but as a side-effect it actually retrieves the entire string over BLE and pushes it into one of text sensors above.
# Such hacks are not needed for numbers, obviously.
sensor:
- name: "Time read over BLE"
platform: ble_client
ble_client_id: ble_server # refer to the conenction to the server defined above
service_uuid: !secret ble_service # here and below, using !secret for easy cross-config value sharing
characteristic_uuid: !secret ble_characteristic_time
# Here we actually do the magic of consuming value read over BLE as `x`,
# converting it to a string, and then pushing it into the proper text_sensor defined above.
# Then we return 0 just so that this particular sensor instance is happy.
lambda: |-
std::string value(x.begin(), x.end());
id(ble_time).publish_state(value);
return 0;
- name: "Kitchen CO2 read over BLE"
platform: ble_client
ble_client_id: ble_server # refer to the conenction to the server defined above
service_uuid: !secret ble_service # here and below, using !secret for easy cross-config value sharing
characteristic_uuid: !secret ble_characteristic_kitchen_co2
# Here we actually do the magic of consuming value read over BLE as `x`,
# converting it to a string, and then pushing it into the proper text_sensor defined above.
# Then we return 0 just so that this particular sensor instance is happy.
lambda: |-
std::string value(x.begin(), x.end());
id(ble_kitchen_co2).publish_state(value);
return 0;
esphome:
name: ${server_name}
includes:
- ble_address.h # Tiny custom sensor providing us with BLE MAC address we'd need to configure client
# ...common config omitted for brevity...
external_components:
- source: github://wifwucite/esphome-ble-controller # Amazing component that exports ESP sensors as BLE services
time:
- platform: homeassistant
id: ntp
text_sensor:
- platform: custom
lambda: |-
auto ble_address = new BleAddress();
App.register_component(ble_address);
return {ble_address};
text_sensors:
id: ble_address
internal: True
on_value:
then:
- lambda: |-
ESP_LOGD("main", "BLE Address is: %s", x.c_str());
- id: timestamp
name: "Timestamp"
platform: template
update_interval: 10s
lambda: |-
return id(ntp).now().strftime("%Y-%m-%dT%H:%M:%S");
# Import from HA
- id: kitchen_co2
name: "Kitchen CO2"
platform: homeassistant
entity_id: sensor.kitchen_co2_scd30
esp32_ble_controller:
security_mode: none # https://esphome.io/components/sensor/ble_client.html doesn't support security
on_connected:
- component.update: timestamp # make sure time most recent whenever someone connects
services:
- service: !secret ble_service # here and below, using !secret for easy cross-config value sharing
characteristics:
- characteristic: !secret ble_characteristic_time
exposes: timestamp
- characteristic: !secret ble_characteristic_kitchen_co2
exposes: kitchen_co2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment