mirror of
https://github.com/esphome/esphome.git
synced 2026-01-10 12:10:48 -07:00
[bthome_mithermometer] Add BTHome parsing for Xiaomi Mijia BLE Sensors (#12635)
This commit is contained in:
@@ -91,6 +91,7 @@ esphome/components/bmp3xx_spi/* @latonita
|
|||||||
esphome/components/bmp581/* @kahrendt
|
esphome/components/bmp581/* @kahrendt
|
||||||
esphome/components/bp1658cj/* @Cossid
|
esphome/components/bp1658cj/* @Cossid
|
||||||
esphome/components/bp5758d/* @Cossid
|
esphome/components/bp5758d/* @Cossid
|
||||||
|
esphome/components/bthome_mithermometer/* @nagyrobi
|
||||||
esphome/components/button/* @esphome/core
|
esphome/components/button/* @esphome/core
|
||||||
esphome/components/bytebuffer/* @clydebarrow
|
esphome/components/bytebuffer/* @clydebarrow
|
||||||
esphome/components/camera/* @bdraco @DT-art1
|
esphome/components/camera/* @bdraco @DT-art1
|
||||||
|
|||||||
36
esphome/components/bthome_mithermometer/__init__.py
Normal file
36
esphome/components/bthome_mithermometer/__init__.py
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import esphome.codegen as cg
|
||||||
|
from esphome.components import esp32_ble_tracker
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome.const import CONF_ID, CONF_MAC_ADDRESS
|
||||||
|
|
||||||
|
CODEOWNERS = ["@nagyrobi"]
|
||||||
|
DEPENDENCIES = ["esp32_ble_tracker"]
|
||||||
|
|
||||||
|
BLE_DEVICE_SCHEMA = esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA
|
||||||
|
|
||||||
|
bthome_mithermometer_ns = cg.esphome_ns.namespace("bthome_mithermometer")
|
||||||
|
BTHomeMiThermometer = bthome_mithermometer_ns.class_(
|
||||||
|
"BTHomeMiThermometer", esp32_ble_tracker.ESPBTDeviceListener, cg.Component
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def bthome_mithermometer_base_schema(extra_schema=None):
|
||||||
|
if extra_schema is None:
|
||||||
|
extra_schema = {}
|
||||||
|
return (
|
||||||
|
cv.Schema(
|
||||||
|
{
|
||||||
|
cv.GenerateID(CONF_ID): cv.declare_id(BTHomeMiThermometer),
|
||||||
|
cv.Required(CONF_MAC_ADDRESS): cv.mac_address,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.extend(BLE_DEVICE_SCHEMA)
|
||||||
|
.extend(cv.COMPONENT_SCHEMA)
|
||||||
|
.extend(extra_schema)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def setup_bthome_mithermometer(var, config):
|
||||||
|
await cg.register_component(var, config)
|
||||||
|
await esp32_ble_tracker.register_ble_device(var, config)
|
||||||
|
cg.add(var.set_address(config[CONF_MAC_ADDRESS].as_hex))
|
||||||
298
esphome/components/bthome_mithermometer/bthome_ble.cpp
Normal file
298
esphome/components/bthome_mithermometer/bthome_ble.cpp
Normal file
@@ -0,0 +1,298 @@
|
|||||||
|
#include "bthome_ble.h"
|
||||||
|
|
||||||
|
#include "esphome/core/helpers.h"
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
#ifdef USE_ESP32
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace bthome_mithermometer {
|
||||||
|
|
||||||
|
static const char *const TAG = "bthome_mithermometer";
|
||||||
|
|
||||||
|
static std::string format_mac_address(uint64_t address) {
|
||||||
|
std::array<uint8_t, MAC_ADDRESS_SIZE> mac{};
|
||||||
|
for (size_t i = 0; i < MAC_ADDRESS_SIZE; i++) {
|
||||||
|
mac[i] = (address >> ((MAC_ADDRESS_SIZE - 1 - i) * 8)) & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
char buffer[MAC_ADDRESS_SIZE * 3];
|
||||||
|
format_mac_addr_upper(mac.data(), buffer);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool get_bthome_value_length(uint8_t obj_type, size_t &value_length) {
|
||||||
|
switch (obj_type) {
|
||||||
|
case 0x00: // packet id
|
||||||
|
case 0x01: // battery
|
||||||
|
case 0x09: // count (uint8)
|
||||||
|
case 0x0F: // generic boolean
|
||||||
|
case 0x10: // power (bool)
|
||||||
|
case 0x11: // opening
|
||||||
|
case 0x15: // battery low
|
||||||
|
case 0x16: // battery charging
|
||||||
|
case 0x17: // carbon monoxide
|
||||||
|
case 0x18: // cold
|
||||||
|
case 0x19: // connectivity
|
||||||
|
case 0x1A: // door
|
||||||
|
case 0x1B: // garage door
|
||||||
|
case 0x1C: // gas
|
||||||
|
case 0x1D: // heat
|
||||||
|
case 0x1E: // light
|
||||||
|
case 0x1F: // lock
|
||||||
|
case 0x20: // moisture
|
||||||
|
case 0x21: // motion
|
||||||
|
case 0x22: // moving
|
||||||
|
case 0x23: // occupancy
|
||||||
|
case 0x24: // plug
|
||||||
|
case 0x25: // presence
|
||||||
|
case 0x26: // problem
|
||||||
|
case 0x27: // running
|
||||||
|
case 0x28: // safety
|
||||||
|
case 0x29: // smoke
|
||||||
|
case 0x2A: // sound
|
||||||
|
case 0x2B: // tamper
|
||||||
|
case 0x2C: // vibration
|
||||||
|
case 0x2D: // water leak
|
||||||
|
case 0x2E: // humidity (uint8)
|
||||||
|
case 0x2F: // moisture (uint8)
|
||||||
|
case 0x46: // UV index
|
||||||
|
case 0x57: // temperature (sint8)
|
||||||
|
case 0x58: // temperature (0.35C step)
|
||||||
|
case 0x59: // count (sint8)
|
||||||
|
case 0x60: // channel
|
||||||
|
value_length = 1;
|
||||||
|
return true;
|
||||||
|
case 0x02: // temperature (0.01C)
|
||||||
|
case 0x03: // humidity
|
||||||
|
case 0x06: // mass (kg)
|
||||||
|
case 0x07: // mass (lb)
|
||||||
|
case 0x08: // dewpoint
|
||||||
|
case 0x0C: // voltage (mV)
|
||||||
|
case 0x0D: // pm2.5
|
||||||
|
case 0x0E: // pm10
|
||||||
|
case 0x12: // CO2
|
||||||
|
case 0x13: // TVOC
|
||||||
|
case 0x14: // moisture
|
||||||
|
case 0x3D: // count (uint16)
|
||||||
|
case 0x3F: // rotation
|
||||||
|
case 0x40: // distance (mm)
|
||||||
|
case 0x41: // distance (m)
|
||||||
|
case 0x43: // current (A)
|
||||||
|
case 0x44: // speed
|
||||||
|
case 0x45: // temperature (0.1C)
|
||||||
|
case 0x47: // volume (L)
|
||||||
|
case 0x48: // volume (mL)
|
||||||
|
case 0x49: // volume flow rate
|
||||||
|
case 0x4A: // voltage (0.1V)
|
||||||
|
case 0x51: // acceleration
|
||||||
|
case 0x52: // gyroscope
|
||||||
|
case 0x56: // conductivity
|
||||||
|
case 0x5A: // count (sint16)
|
||||||
|
case 0x5D: // current (sint16)
|
||||||
|
case 0x5E: // direction
|
||||||
|
case 0x5F: // precipitation
|
||||||
|
case 0x61: // rotational speed
|
||||||
|
case 0xF0: // button event
|
||||||
|
value_length = 2;
|
||||||
|
return true;
|
||||||
|
case 0x04: // pressure
|
||||||
|
case 0x05: // illuminance
|
||||||
|
case 0x0A: // energy
|
||||||
|
case 0x0B: // power
|
||||||
|
case 0x42: // duration
|
||||||
|
case 0x4B: // gas (uint24)
|
||||||
|
case 0xF2: // firmware version (uint24)
|
||||||
|
value_length = 3;
|
||||||
|
return true;
|
||||||
|
case 0x3E: // count (uint32)
|
||||||
|
case 0x4C: // gas (uint32)
|
||||||
|
case 0x4D: // energy (uint32)
|
||||||
|
case 0x4E: // volume (uint32)
|
||||||
|
case 0x4F: // water (uint32)
|
||||||
|
case 0x50: // timestamp
|
||||||
|
case 0x55: // volume storage
|
||||||
|
case 0x5B: // count (sint32)
|
||||||
|
case 0x5C: // power (sint32)
|
||||||
|
case 0x62: // speed (sint32)
|
||||||
|
case 0x63: // acceleration (sint32)
|
||||||
|
case 0xF1: // firmware version (uint32)
|
||||||
|
value_length = 4;
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BTHomeMiThermometer::dump_config() {
|
||||||
|
ESP_LOGCONFIG(TAG, "BTHome MiThermometer");
|
||||||
|
ESP_LOGCONFIG(TAG, " MAC Address: %s", format_mac_address(this->address_).c_str());
|
||||||
|
LOG_SENSOR(" ", "Temperature", this->temperature_);
|
||||||
|
LOG_SENSOR(" ", "Humidity", this->humidity_);
|
||||||
|
LOG_SENSOR(" ", "Battery Level", this->battery_level_);
|
||||||
|
LOG_SENSOR(" ", "Battery Voltage", this->battery_voltage_);
|
||||||
|
LOG_SENSOR(" ", "Signal Strength", this->signal_strength_);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BTHomeMiThermometer::parse_device(const esp32_ble_tracker::ESPBTDevice &device) {
|
||||||
|
bool matched = false;
|
||||||
|
for (auto &service_data : device.get_service_datas()) {
|
||||||
|
if (this->handle_service_data_(service_data, device)) {
|
||||||
|
matched = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (matched && this->signal_strength_ != nullptr) {
|
||||||
|
this->signal_strength_->publish_state(device.get_rssi());
|
||||||
|
}
|
||||||
|
return matched;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BTHomeMiThermometer::handle_service_data_(const esp32_ble_tracker::ServiceData &service_data,
|
||||||
|
const esp32_ble_tracker::ESPBTDevice &device) {
|
||||||
|
if (!service_data.uuid.contains(0xD2, 0xFC)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto &data = service_data.data;
|
||||||
|
if (data.size() < 2) {
|
||||||
|
ESP_LOGVV(TAG, "BTHome data too short: %zu", data.size());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t adv_info = data[0];
|
||||||
|
const bool is_encrypted = adv_info & 0x01;
|
||||||
|
const bool mac_included = adv_info & 0x02;
|
||||||
|
const bool is_trigger_based = adv_info & 0x04;
|
||||||
|
const uint8_t version = (adv_info >> 5) & 0x07;
|
||||||
|
|
||||||
|
if (version != 0x02) {
|
||||||
|
ESP_LOGVV(TAG, "Unsupported BTHome version %u", version);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_encrypted) {
|
||||||
|
ESP_LOGV(TAG, "Ignoring encrypted BTHome frame from %s", device.address_str().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t payload_index = 1;
|
||||||
|
uint64_t source_address = device.address_uint64();
|
||||||
|
|
||||||
|
if (mac_included) {
|
||||||
|
if (data.size() < 7) {
|
||||||
|
ESP_LOGVV(TAG, "BTHome payload missing MAC address");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
source_address = 0;
|
||||||
|
for (int i = 5; i >= 0; i--) {
|
||||||
|
source_address = (source_address << 8) | data[1 + i];
|
||||||
|
}
|
||||||
|
payload_index = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (source_address != this->address_) {
|
||||||
|
ESP_LOGVV(TAG, "BTHome frame from unexpected device %s", format_mac_address(source_address).c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (payload_index >= data.size()) {
|
||||||
|
ESP_LOGVV(TAG, "BTHome payload empty after header");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool reported = false;
|
||||||
|
size_t offset = payload_index;
|
||||||
|
uint8_t last_type = 0;
|
||||||
|
|
||||||
|
while (offset < data.size()) {
|
||||||
|
const uint8_t obj_type = data[offset++];
|
||||||
|
size_t value_length = 0;
|
||||||
|
bool has_length_byte = obj_type == 0x53; // text objects include explicit length
|
||||||
|
|
||||||
|
if (has_length_byte) {
|
||||||
|
if (offset >= data.size()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
value_length = data[offset++];
|
||||||
|
} else {
|
||||||
|
if (!get_bthome_value_length(obj_type, value_length)) {
|
||||||
|
ESP_LOGVV(TAG, "Unknown BTHome object 0x%02X", obj_type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value_length == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offset + value_length > data.size()) {
|
||||||
|
ESP_LOGVV(TAG, "BTHome object length exceeds payload");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t *value = &data[offset];
|
||||||
|
offset += value_length;
|
||||||
|
|
||||||
|
if (obj_type < last_type) {
|
||||||
|
ESP_LOGVV(TAG, "BTHome objects not in ascending order");
|
||||||
|
}
|
||||||
|
last_type = obj_type;
|
||||||
|
|
||||||
|
switch (obj_type) {
|
||||||
|
case 0x00: { // packet id
|
||||||
|
const uint8_t packet_id = value[0];
|
||||||
|
if (this->last_packet_id_.has_value() && *this->last_packet_id_ == packet_id) {
|
||||||
|
return reported;
|
||||||
|
}
|
||||||
|
this->last_packet_id_ = packet_id;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x01: { // battery percentage
|
||||||
|
if (this->battery_level_ != nullptr) {
|
||||||
|
this->battery_level_->publish_state(value[0]);
|
||||||
|
reported = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x0C: { // battery voltage (mV)
|
||||||
|
if (this->battery_voltage_ != nullptr) {
|
||||||
|
const uint16_t raw = encode_uint16(value[1], value[0]);
|
||||||
|
this->battery_voltage_->publish_state(raw * 0.001f);
|
||||||
|
reported = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x02: { // temperature
|
||||||
|
if (this->temperature_ != nullptr) {
|
||||||
|
const int16_t raw = encode_uint16(value[1], value[0]);
|
||||||
|
this->temperature_->publish_state(raw * 0.01f);
|
||||||
|
reported = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x03: { // humidity
|
||||||
|
if (this->humidity_ != nullptr) {
|
||||||
|
const uint16_t raw = encode_uint16(value[1], value[0]);
|
||||||
|
this->humidity_->publish_state(raw * 0.01f);
|
||||||
|
reported = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reported) {
|
||||||
|
ESP_LOGD(TAG, "BTHome data%sfrom %s", is_trigger_based ? " (triggered) " : " ", device.address_str().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
return reported;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace bthome_mithermometer
|
||||||
|
} // namespace esphome
|
||||||
|
|
||||||
|
#endif
|
||||||
44
esphome/components/bthome_mithermometer/bthome_ble.h
Normal file
44
esphome/components/bthome_mithermometer/bthome_ble.h
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/components/esp32_ble_tracker/esp32_ble_tracker.h"
|
||||||
|
#include "esphome/components/sensor/sensor.h"
|
||||||
|
#include "esphome/core/component.h"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#ifdef USE_ESP32
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace bthome_mithermometer {
|
||||||
|
|
||||||
|
class BTHomeMiThermometer : public esp32_ble_tracker::ESPBTDeviceListener, public Component {
|
||||||
|
public:
|
||||||
|
void set_address(uint64_t address) { this->address_ = address; }
|
||||||
|
|
||||||
|
void set_temperature(sensor::Sensor *temperature) { this->temperature_ = temperature; }
|
||||||
|
void set_humidity(sensor::Sensor *humidity) { this->humidity_ = humidity; }
|
||||||
|
void set_battery_level(sensor::Sensor *battery_level) { this->battery_level_ = battery_level; }
|
||||||
|
void set_battery_voltage(sensor::Sensor *battery_voltage) { this->battery_voltage_ = battery_voltage; }
|
||||||
|
void set_signal_strength(sensor::Sensor *signal_strength) { this->signal_strength_ = signal_strength; }
|
||||||
|
|
||||||
|
void dump_config() override;
|
||||||
|
bool parse_device(const esp32_ble_tracker::ESPBTDevice &device) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool handle_service_data_(const esp32_ble_tracker::ServiceData &service_data,
|
||||||
|
const esp32_ble_tracker::ESPBTDevice &device);
|
||||||
|
|
||||||
|
uint64_t address_{0};
|
||||||
|
optional<uint8_t> last_packet_id_{};
|
||||||
|
|
||||||
|
sensor::Sensor *temperature_{nullptr};
|
||||||
|
sensor::Sensor *humidity_{nullptr};
|
||||||
|
sensor::Sensor *battery_level_{nullptr};
|
||||||
|
sensor::Sensor *battery_voltage_{nullptr};
|
||||||
|
sensor::Sensor *signal_strength_{nullptr};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace bthome_mithermometer
|
||||||
|
} // namespace esphome
|
||||||
|
|
||||||
|
#endif
|
||||||
88
esphome/components/bthome_mithermometer/sensor.py
Normal file
88
esphome/components/bthome_mithermometer/sensor.py
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
import esphome.codegen as cg
|
||||||
|
from esphome.components import sensor
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome.const import (
|
||||||
|
CONF_BATTERY_LEVEL,
|
||||||
|
CONF_BATTERY_VOLTAGE,
|
||||||
|
CONF_HUMIDITY,
|
||||||
|
CONF_ID,
|
||||||
|
CONF_SIGNAL_STRENGTH,
|
||||||
|
CONF_TEMPERATURE,
|
||||||
|
DEVICE_CLASS_BATTERY,
|
||||||
|
DEVICE_CLASS_HUMIDITY,
|
||||||
|
DEVICE_CLASS_SIGNAL_STRENGTH,
|
||||||
|
DEVICE_CLASS_TEMPERATURE,
|
||||||
|
DEVICE_CLASS_VOLTAGE,
|
||||||
|
ENTITY_CATEGORY_DIAGNOSTIC,
|
||||||
|
STATE_CLASS_MEASUREMENT,
|
||||||
|
UNIT_CELSIUS,
|
||||||
|
UNIT_DECIBEL_MILLIWATT,
|
||||||
|
UNIT_PERCENT,
|
||||||
|
UNIT_VOLT,
|
||||||
|
)
|
||||||
|
|
||||||
|
from . import bthome_mithermometer_base_schema, setup_bthome_mithermometer
|
||||||
|
|
||||||
|
CODEOWNERS = ["@nagyrobi"]
|
||||||
|
|
||||||
|
DEPENDENCIES = ["esp32_ble_tracker"]
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = bthome_mithermometer_base_schema(
|
||||||
|
{
|
||||||
|
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(
|
||||||
|
unit_of_measurement=UNIT_CELSIUS,
|
||||||
|
accuracy_decimals=2,
|
||||||
|
device_class=DEVICE_CLASS_TEMPERATURE,
|
||||||
|
state_class=STATE_CLASS_MEASUREMENT,
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_HUMIDITY): sensor.sensor_schema(
|
||||||
|
unit_of_measurement=UNIT_PERCENT,
|
||||||
|
accuracy_decimals=2,
|
||||||
|
device_class=DEVICE_CLASS_HUMIDITY,
|
||||||
|
state_class=STATE_CLASS_MEASUREMENT,
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_BATTERY_LEVEL): sensor.sensor_schema(
|
||||||
|
unit_of_measurement=UNIT_PERCENT,
|
||||||
|
accuracy_decimals=0,
|
||||||
|
device_class=DEVICE_CLASS_BATTERY,
|
||||||
|
state_class=STATE_CLASS_MEASUREMENT,
|
||||||
|
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_BATTERY_VOLTAGE): sensor.sensor_schema(
|
||||||
|
unit_of_measurement=UNIT_VOLT,
|
||||||
|
accuracy_decimals=3,
|
||||||
|
device_class=DEVICE_CLASS_VOLTAGE,
|
||||||
|
state_class=STATE_CLASS_MEASUREMENT,
|
||||||
|
icon="mdi:battery-plus",
|
||||||
|
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_SIGNAL_STRENGTH): sensor.sensor_schema(
|
||||||
|
unit_of_measurement=UNIT_DECIBEL_MILLIWATT,
|
||||||
|
accuracy_decimals=0,
|
||||||
|
device_class=DEVICE_CLASS_SIGNAL_STRENGTH,
|
||||||
|
state_class=STATE_CLASS_MEASUREMENT,
|
||||||
|
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def to_code(config):
|
||||||
|
var = cg.new_Pvariable(config[CONF_ID])
|
||||||
|
await setup_bthome_mithermometer(var, config)
|
||||||
|
|
||||||
|
if temp_sens := config.get(CONF_TEMPERATURE):
|
||||||
|
sens = await sensor.new_sensor(temp_sens)
|
||||||
|
cg.add(var.set_temperature(sens))
|
||||||
|
if humi_sens := config.get(CONF_HUMIDITY):
|
||||||
|
sens = await sensor.new_sensor(humi_sens)
|
||||||
|
cg.add(var.set_humidity(sens))
|
||||||
|
if batl_sens := config.get(CONF_BATTERY_LEVEL):
|
||||||
|
sens = await sensor.new_sensor(batl_sens)
|
||||||
|
cg.add(var.set_battery_level(sens))
|
||||||
|
if batv_sens := config.get(CONF_BATTERY_VOLTAGE):
|
||||||
|
sens = await sensor.new_sensor(batv_sens)
|
||||||
|
cg.add(var.set_battery_voltage(sens))
|
||||||
|
if sgnl_sens := config.get(CONF_SIGNAL_STRENGTH):
|
||||||
|
sens = await sensor.new_sensor(sgnl_sens)
|
||||||
|
cg.add(var.set_signal_strength(sens))
|
||||||
15
tests/components/bthome_mithermometer/common.yaml
Normal file
15
tests/components/bthome_mithermometer/common.yaml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
esp32_ble_tracker:
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: bthome_mithermometer
|
||||||
|
mac_address: A4:C1:38:4E:16:78
|
||||||
|
temperature:
|
||||||
|
name: "BTHome Temperature"
|
||||||
|
humidity:
|
||||||
|
name: "BTHome Humidity"
|
||||||
|
battery_level:
|
||||||
|
name: "BTHome Battery"
|
||||||
|
battery_voltage:
|
||||||
|
name: "BTHome Battery Voltage"
|
||||||
|
signal_strength:
|
||||||
|
name: "BTHome Signal"
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
packages:
|
||||||
|
ble: !include ../../test_build_components/common/ble/esp32-idf.yaml
|
||||||
|
|
||||||
|
<<: !include common.yaml
|
||||||
Reference in New Issue
Block a user