cogito/esphome_dev/esphome/components/mopeka_ble/mopeka_ble.cpp

91 lines
2.9 KiB
C++

#include "mopeka_ble.h"
#include "esphome/core/log.h"
#ifdef USE_ESP32
namespace esphome {
namespace mopeka_ble {
static const char *const TAG = "mopeka_ble";
// Mopeka Std (CC2540) sensor details
static const uint16_t SERVICE_UUID_CC2540 = 0xADA0;
static const uint16_t MANUFACTURER_CC2540_ID = 0x000D; // Texas Instruments (TI)
static const uint8_t MANUFACTURER_CC2540_DATA_LENGTH = 23;
// Mopeka Pro (NRF52) sensor details
static const uint16_t SERVICE_UUID_NRF52 = 0xFEE5;
static const uint16_t MANUFACTURER_NRF52_ID = 0x0059; // Nordic
static const uint8_t MANUFACTURER_NRF52_DATA_LENGTH = 10;
/**
* Parse all incoming BLE payloads to see if it is a Mopeka BLE advertisement.
* Currently this supports the following products:
*
* - Mopeka Std Check - uses the chip CC2540 by Texas Instruments (TI)
* - Mopeka Pro Check - uses the chip NRF52 by Nordic
*
* If the sync button is pressed, report the MAC so a user can add this as a sensor. Or if user has configured
* `show_sensors_without_sync_` than report all visible sensors.
* Three points are used to identify a sensor:
*
* - Bluetooth service uuid
* - Bluetooth manufacturer id
* - Bluetooth data frame size
*/
bool MopekaListener::parse_device(const esp32_ble_tracker::ESPBTDevice &device) {
// Fetch information about BLE device.
const auto &service_uuids = device.get_service_uuids();
if (service_uuids.size() != 1) {
return false;
}
const auto &service_uuid = service_uuids[0];
const auto &manu_datas = device.get_manufacturer_datas();
if (manu_datas.size() != 1) {
return false;
}
const auto &manu_data = manu_datas[0];
// Is the device maybe a Mopeka Std (CC2540) sensor.
if (service_uuid == esp32_ble_tracker::ESPBTUUID::from_uint16(SERVICE_UUID_CC2540)) {
if (manu_data.uuid != esp32_ble_tracker::ESPBTUUID::from_uint16(MANUFACTURER_CC2540_ID)) {
return false;
}
if (manu_data.data.size() != MANUFACTURER_CC2540_DATA_LENGTH) {
return false;
}
const bool sync_button_pressed = (manu_data.data[3] & 0x80) != 0;
if (this->show_sensors_without_sync_ || sync_button_pressed) {
ESP_LOGI(TAG, "MOPEKA STD (CC2540) SENSOR FOUND: %s", device.address_str().c_str());
}
// Is the device maybe a Mopeka Pro (NRF52) sensor.
} else if (service_uuid == esp32_ble_tracker::ESPBTUUID::from_uint16(SERVICE_UUID_NRF52)) {
if (manu_data.uuid != esp32_ble_tracker::ESPBTUUID::from_uint16(MANUFACTURER_NRF52_ID)) {
return false;
}
if (manu_data.data.size() != MANUFACTURER_NRF52_DATA_LENGTH) {
return false;
}
const bool sync_button_pressed = (manu_data.data[2] & 0x80) != 0;
if (this->show_sensors_without_sync_ || sync_button_pressed) {
ESP_LOGI(TAG, "MOPEKA PRO (NRF52) SENSOR FOUND: %s", device.address_str().c_str());
}
}
return false;
}
} // namespace mopeka_ble
} // namespace esphome
#endif