[ble_device_base] Migrate BLE sensor platforms to the neutral layer (batch 3: mopeka_ble, mopeka_pro_check, mopeka_std_check) (#17951)

Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
Edvard Filistovič
2026-08-07 12:59:27 -05:00
committed by GitHub
co-authored by J. Nick Koston
parent d7b5ad77da
commit 715b14aeba
21 changed files with 119 additions and 63 deletions
+13 -10
View File
@@ -1,24 +1,27 @@
import esphome.codegen as cg
from esphome.components import esp32_ble_tracker
from esphome.components import ble_device_base
import esphome.config_validation as cv
from esphome.const import CONF_ID
CODEOWNERS = ["@spbrogan", "@Fabian-Schmidt"]
DEPENDENCIES = ["esp32_ble_tracker"]
AUTO_LOAD = ["ble_device_base"]
CONF_SHOW_SENSORS_WITHOUT_SYNC = "show_sensors_without_sync"
mopeka_ble_ns = cg.esphome_ns.namespace("mopeka_ble")
MopekaListener = mopeka_ble_ns.class_(
"MopekaListener", esp32_ble_tracker.ESPBTDeviceListener
"MopekaListener", ble_device_base.ESPBTDeviceListener
)
CONFIG_SCHEMA = cv.Schema(
{
cv.GenerateID(): cv.declare_id(MopekaListener),
cv.Optional(CONF_SHOW_SENSORS_WITHOUT_SYNC, default=False): cv.boolean,
}
).extend(esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA)
CONFIG_SCHEMA = cv.All(
ble_device_base.rename_legacy_hub_id("mopeka_ble"),
cv.Schema(
{
cv.GenerateID(): cv.declare_id(MopekaListener),
cv.Optional(CONF_SHOW_SENSORS_WITHOUT_SYNC, default=False): cv.boolean,
}
).extend(ble_device_base.BLE_DEVICE_SCHEMA),
)
async def to_code(config):
@@ -27,4 +30,4 @@ async def to_code(config):
cg.add(
var.set_show_sensors_without_sync(config[CONF_SHOW_SENSORS_WITHOUT_SYNC])
)
await esp32_ble_tracker.register_ble_device(var, config)
await ble_device_base.register_ble_device(var, config)
+5 -9
View File
@@ -2,8 +2,6 @@
#include "esphome/core/log.h"
#ifdef USE_ESP32
namespace esphome::mopeka_ble {
static const char *const TAG = "mopeka_ble";
@@ -34,7 +32,7 @@ static const uint8_t MANUFACTURER_NRF52_DATA_LENGTH = 10;
* - Bluetooth data frame size
*/
bool MopekaListener::parse_device(const esp32_ble_tracker::ESPBTDevice &device) {
bool MopekaListener::parse_device(const ble_device_base::ESPBTDevice &device) {
char addr_buf[MAC_ADDRESS_PRETTY_BUFFER_SIZE];
// Fetch information about BLE device.
const auto &service_uuids = device.get_service_uuids();
@@ -50,8 +48,8 @@ bool MopekaListener::parse_device(const esp32_ble_tracker::ESPBTDevice &device)
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)) {
if (service_uuid == ble_device_base::ESPBTUUID::from_uint16(SERVICE_UUID_CC2540)) {
if (manu_data.uuid != ble_device_base::ESPBTUUID::from_uint16(MANUFACTURER_CC2540_ID)) {
return false;
}
@@ -66,8 +64,8 @@ bool MopekaListener::parse_device(const esp32_ble_tracker::ESPBTDevice &device)
}
// 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)) {
} else if (service_uuid == ble_device_base::ESPBTUUID::from_uint16(SERVICE_UUID_NRF52)) {
if (manu_data.uuid != ble_device_base::ESPBTUUID::from_uint16(MANUFACTURER_NRF52_ID)) {
return false;
}
@@ -86,5 +84,3 @@ bool MopekaListener::parse_device(const esp32_ble_tracker::ESPBTDevice &device)
}
} // namespace esphome::mopeka_ble
#endif
+3 -7
View File
@@ -2,16 +2,14 @@
#include <vector>
#include "esphome/components/esp32_ble_tracker/esp32_ble_tracker.h"
#include "esphome/components/ble_device_base/ble_device.h"
#include "esphome/core/component.h"
#ifdef USE_ESP32
namespace esphome::mopeka_ble {
class MopekaListener final : public esp32_ble_tracker::ESPBTDeviceListener {
class MopekaListener final : public ble_device_base::ESPBTDeviceListener {
public:
bool parse_device(const esp32_ble_tracker::ESPBTDevice &device) override;
bool parse_device(const ble_device_base::ESPBTDevice &device) override;
void set_show_sensors_without_sync(bool show_sensors_without_sync) {
show_sensors_without_sync_ = show_sensors_without_sync;
}
@@ -21,5 +19,3 @@ class MopekaListener final : public esp32_ble_tracker::ESPBTDeviceListener {
};
} // namespace esphome::mopeka_ble
#endif
@@ -1,8 +1,6 @@
#include "mopeka_pro_check.h"
#include "esphome/core/log.h"
#ifdef USE_ESP32
namespace esphome::mopeka_pro_check {
static const char *const TAG = "mopeka_pro_check";
@@ -25,7 +23,7 @@ void MopekaProCheck::dump_config() {
* Check if advertisement is for our sensor and if so decode it and
* update the sensor state data.
*/
bool MopekaProCheck::parse_device(const esp32_ble_tracker::ESPBTDevice &device) {
bool MopekaProCheck::parse_device(const ble_device_base::ESPBTDevice &device) {
if (device.address_uint64() != this->address_) {
return false;
}
@@ -154,5 +152,3 @@ SensorReadQuality MopekaProCheck::parse_read_quality_(const std::vector<uint8_t>
}
} // namespace esphome::mopeka_pro_check
#endif
@@ -5,9 +5,7 @@
#include "esphome/core/component.h"
#include "esphome/components/sensor/sensor.h"
#include "esphome/components/esp32_ble_tracker/esp32_ble_tracker.h"
#ifdef USE_ESP32
#include "esphome/components/ble_device_base/ble_device.h"
namespace esphome::mopeka_pro_check {
@@ -27,11 +25,11 @@ enum SensorType {
// measurement may be inaccurate.
enum SensorReadQuality { QUALITY_HIGH = 0x3, QUALITY_MED = 0x2, QUALITY_LOW = 0x1, QUALITY_ZERO = 0x0 };
class MopekaProCheck final : public Component, public esp32_ble_tracker::ESPBTDeviceListener {
class MopekaProCheck final : public Component, public ble_device_base::ESPBTDeviceListener {
public:
void set_address(uint64_t address) { address_ = address; };
bool parse_device(const esp32_ble_tracker::ESPBTDevice &device) override;
bool parse_device(const ble_device_base::ESPBTDevice &device) override;
void dump_config() override;
void set_min_signal_quality(SensorReadQuality min) { this->min_signal_quality_ = min; };
@@ -65,5 +63,3 @@ class MopekaProCheck final : public Component, public esp32_ble_tracker::ESPBTDe
};
} // namespace esphome::mopeka_pro_check
#endif
@@ -1,5 +1,5 @@
import esphome.codegen as cg
from esphome.components import esp32_ble_tracker, sensor
from esphome.components import ble_device_base, sensor
import esphome.config_validation as cv
from esphome.const import (
CONF_BATTERY_LEVEL,
@@ -56,11 +56,11 @@ CONF_SUPPORTED_TANKS_MAP = {
}
CODEOWNERS = ["@spbrogan"]
DEPENDENCIES = ["esp32_ble_tracker"]
AUTO_LOAD = ["ble_device_base"]
mopeka_pro_check_ns = cg.esphome_ns.namespace("mopeka_pro_check")
MopekaProCheck = mopeka_pro_check_ns.class_(
"MopekaProCheck", esp32_ble_tracker.ESPBTDeviceListener, cg.Component
"MopekaProCheck", ble_device_base.ESPBTDeviceListener, cg.Component
)
SensorReadQuality = mopeka_pro_check_ns.enum("SensorReadQuality")
@@ -71,7 +71,8 @@ SIGNAL_QUALITIES = {
"HIGH": SensorReadQuality.QUALITY_HIGH,
}
CONFIG_SCHEMA = (
CONFIG_SCHEMA = cv.All(
ble_device_base.rename_legacy_hub_id("mopeka_pro_check"),
cv.Schema(
{
cv.GenerateID(): cv.declare_id(MopekaProCheck),
@@ -122,15 +123,15 @@ CONFIG_SCHEMA = (
),
}
)
.extend(esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA)
.extend(cv.COMPONENT_SCHEMA)
.extend(ble_device_base.BLE_DEVICE_SCHEMA),
)
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)
await esp32_ble_tracker.register_ble_device(var, config)
await ble_device_base.register_ble_device(var, config)
cg.add(var.set_address(config[CONF_MAC_ADDRESS].as_hex))
@@ -3,8 +3,6 @@
#include "esphome/core/helpers.h"
#include "esphome/core/log.h"
#ifdef USE_ESP32
namespace esphome::mopeka_std_check {
static const char *const TAG = "mopeka_std_check";
@@ -33,7 +31,7 @@ void MopekaStdCheck::dump_config() {
* Check if advertisement is for our sensor and if so decode it and
* update the sensor state data.
*/
bool MopekaStdCheck::parse_device(const esp32_ble_tracker::ESPBTDevice &device) {
bool MopekaStdCheck::parse_device(const ble_device_base::ESPBTDevice &device) {
// Validate address.
if (device.address_uint64() != this->address_) {
return false;
@@ -52,7 +50,7 @@ bool MopekaStdCheck::parse_device(const esp32_ble_tracker::ESPBTDevice &device)
return false;
}
const auto &service_uuid = service_uuids[0];
if (service_uuid != esp32_ble_tracker::ESPBTUUID::from_uint16(SERVICE_UUID)) {
if (service_uuid != ble_device_base::ESPBTUUID::from_uint16(SERVICE_UUID)) {
return false;
}
}
@@ -232,5 +230,3 @@ int8_t MopekaStdCheck::parse_temperature_(const mopeka_std_package *message) {
}
} // namespace esphome::mopeka_std_check
#endif
@@ -3,12 +3,10 @@
#include <cinttypes>
#include <vector>
#include "esphome/components/esp32_ble_tracker/esp32_ble_tracker.h"
#include "esphome/components/ble_device_base/ble_device.h"
#include "esphome/components/sensor/sensor.h"
#include "esphome/core/component.h"
#ifdef USE_ESP32
namespace esphome::mopeka_std_check {
enum SensorType {
@@ -42,11 +40,11 @@ struct mopeka_std_package { // NOLINT(readability-identifier-naming,altera-stru
mopeka_std_values val[3];
} __attribute__((packed));
class MopekaStdCheck final : public Component, public esp32_ble_tracker::ESPBTDeviceListener {
class MopekaStdCheck final : public Component, public ble_device_base::ESPBTDeviceListener {
public:
void set_address(uint64_t address) { address_ = address; };
bool parse_device(const esp32_ble_tracker::ESPBTDevice &device) override;
bool parse_device(const ble_device_base::ESPBTDevice &device) override;
void dump_config() override;
void set_level(sensor::Sensor *level) { this->level_ = level; };
@@ -74,5 +72,3 @@ class MopekaStdCheck final : public Component, public esp32_ble_tracker::ESPBTDe
};
} // namespace esphome::mopeka_std_check
#endif
@@ -1,5 +1,5 @@
import esphome.codegen as cg
from esphome.components import esp32_ble_tracker, sensor
from esphome.components import ble_device_base, sensor
import esphome.config_validation as cv
from esphome.const import (
CONF_BATTERY_LEVEL,
@@ -50,14 +50,15 @@ CONF_SUPPORTED_TANKS_MAP = {
}
CODEOWNERS = ["@Fabian-Schmidt"]
DEPENDENCIES = ["esp32_ble_tracker"]
AUTO_LOAD = ["ble_device_base"]
mopeka_std_check_ns = cg.esphome_ns.namespace("mopeka_std_check")
MopekaStdCheck = mopeka_std_check_ns.class_(
"MopekaStdCheck", esp32_ble_tracker.ESPBTDeviceListener, cg.Component
"MopekaStdCheck", ble_device_base.ESPBTDeviceListener, cg.Component
)
CONFIG_SCHEMA = (
CONFIG_SCHEMA = cv.All(
ble_device_base.rename_legacy_hub_id("mopeka_std_check"),
cv.Schema(
{
cv.GenerateID(): cv.declare_id(MopekaStdCheck),
@@ -93,15 +94,15 @@ CONFIG_SCHEMA = (
),
}
)
.extend(esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA)
.extend(cv.COMPONENT_SCHEMA)
.extend(ble_device_base.BLE_DEVICE_SCHEMA),
)
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)
await esp32_ble_tracker.register_ble_device(var, config)
await ble_device_base.register_ble_device(var, config)
cg.add(var.set_address(config[CONF_MAC_ADDRESS].as_hex))
@@ -0,0 +1 @@
mopeka_ble:
+3
View File
@@ -1,3 +1,6 @@
esp32_ble_tracker:
id: ble_tracker_hub
# Explicit ble_hub_id: pins the neutral binding as a declared key.
mopeka_ble:
ble_hub_id: ble_tracker_hub
@@ -0,0 +1,3 @@
packages:
ln882h_ble_tracker: !include ../ln882h_ble_tracker/common.yaml
mopeka_ble: !include common-ln.yaml
@@ -0,0 +1,8 @@
# Config-only: the CI base board (generic-bk7252, BLE 4.2) cannot compile the
# BLE 5.x tracker, so this fixture proves validation (schema + neutral binding)
# on a non-esp32 platform; codegen and compilation are not exercised here.
bk72xx_ble_tracker:
id: ble_hub
mopeka_ble:
ble_hub_id: ble_hub
@@ -0,0 +1,8 @@
sensor:
- platform: mopeka_pro_check
mac_address: D3:75:F2:DC:16:91
tank_type: 20LB_V
temperature:
name: Propane test temp
level:
name: Propane test level
@@ -1,7 +1,10 @@
esp32_ble_tracker:
id: ble_tracker_hub
sensor:
# Explicit ble_hub_id: pins the neutral binding as a declared key.
- platform: mopeka_pro_check
ble_hub_id: ble_tracker_hub
mac_address: D3:75:F2:DC:16:91
tank_type: CUSTOM
custom_distance_full: 40cm
@@ -0,0 +1,3 @@
packages:
ln882h_ble_tracker: !include ../ln882h_ble_tracker/common.yaml
mopeka_pro_check: !include common-ln.yaml
@@ -0,0 +1,13 @@
# Config-only: the CI base board (generic-bk7252, BLE 4.2) cannot compile the
# BLE 5.x tracker, so this fixture proves validation (schema + neutral binding)
# on a non-esp32 platform; codegen and compilation are not exercised here.
bk72xx_ble_tracker:
id: ble_hub
sensor:
- platform: mopeka_pro_check
ble_hub_id: ble_hub
mac_address: D3:75:F2:DC:16:91
tank_type: 20lb_v
level:
name: BK Mopeka Pro Level
@@ -0,0 +1,8 @@
sensor:
- platform: mopeka_std_check
mac_address: D3:75:F2:DC:16:91
tank_type: Europe_11kg
temperature:
name: Propane test temp
level:
name: Propane test level
@@ -1,8 +1,11 @@
esp32_ble_tracker:
id: ble_tracker_hub
sensor:
# Example using 11kg 100% propane tank.
# Explicit ble_hub_id: pins the neutral binding as a declared key.
- platform: mopeka_std_check
ble_hub_id: ble_tracker_hub
mac_address: D3:75:F2:DC:16:91
tank_type: Europe_11kg
temperature:
@@ -0,0 +1,3 @@
packages:
ln882h_ble_tracker: !include ../ln882h_ble_tracker/common.yaml
mopeka_std_check: !include common-ln.yaml
@@ -0,0 +1,19 @@
# Config-only: the CI base board (generic-bk7252, BLE 4.2) cannot compile the
# BLE 5.x tracker, so this fixture proves validation (schema + neutral binding)
# on a non-esp32 platform; codegen and compilation are not exercised here.
bk72xx_ble_tracker:
id: ble_hub
sensor:
- platform: mopeka_std_check
ble_hub_id: ble_hub
mac_address: D3:75:F2:DC:16:91
tank_type: Europe_11kg
level:
name: BK Mopeka Std Level
# No ble_hub_id: exercises the generated binding real configs use.
- platform: mopeka_std_check
mac_address: D3:75:F2:DC:16:92
tank_type: Europe_11kg
level:
name: BK Propane implicit level