esphome/esphome/components/mopeka_ble/mopeka_ble.cpp
Fabian d16eff5039
Support Mopeka Standard LPG tank bluetooth sensor (#4351)
* Add mopeka standard tank sensor.

* Enhance mopeka ble to find standard sensors.

* Updated `CODEOWNERS` file

* Move default from cpp to py.

* Format documents with esphome settings.

* Linter wants changes.

* Update name of `get_lpg_speed_of_sound`.

* manually update `CODEOWNERS`.

* Manually update CODEOWNER, because `build_codeowners.py. is failing.

* Add comments.

* Use percentage for `propane_butane_mix`.

* add config to `dump_config()`

* Formatting

* Use struct for data parsing and find best data.

* Add `this`.

* Consistant naming of configuration.

* Fix format issues.

* Make clang-tidy happy.

* Adjust loop variable.

---------

Co-authored-by: Your Name <you@example.com>
2023-02-21 21:48:29 +00:00

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