mirror of
https://github.com/esphome/esphome.git
synced 2025-04-14 14:50:32 +01:00
merging in sormy branch rd200v2
This commit is contained in:
commit
1b95eac2ac
@ -13,7 +13,7 @@ static const char *const TAG = "radon_eye_ble";
|
||||
bool RadonEyeListener::parse_device(const esp32_ble_tracker::ESPBTDevice &device) {
|
||||
if (not device.get_name().empty()) {
|
||||
// Vector containing the prefixes to search for
|
||||
std::vector<std::string> prefixes = {"FR:R", "FR:I", "FR:H"};
|
||||
std::vector<std::string> prefixes = {"FR:"};
|
||||
|
||||
// Check if the device name starts with any of the prefixes
|
||||
if (std::any_of(prefixes.begin(), prefixes.end(),
|
||||
|
@ -7,6 +7,22 @@ namespace radon_eye_rd200 {
|
||||
|
||||
static const char *const TAG = "radon_eye_rd200";
|
||||
|
||||
static const esp32_ble_tracker::ESPBTUUID SERVICE_UUID_V1 =
|
||||
esp32_ble_tracker::ESPBTUUID::from_raw("00001523-1212-efde-1523-785feabcd123");
|
||||
static const esp32_ble_tracker::ESPBTUUID WRITE_CHARACTERISTIC_UUID_V1 =
|
||||
esp32_ble_tracker::ESPBTUUID::from_raw("00001524-1212-efde-1523-785feabcd123");
|
||||
static const esp32_ble_tracker::ESPBTUUID READ_CHARACTERISTIC_UUID_V1 =
|
||||
esp32_ble_tracker::ESPBTUUID::from_raw("00001525-1212-efde-1523-785feabcd123");
|
||||
static const uint8_t WRITE_COMMAND_V1 = 0x50;
|
||||
|
||||
static const esp32_ble_tracker::ESPBTUUID SERVICE_UUID_V2 =
|
||||
esp32_ble_tracker::ESPBTUUID::from_raw("00001523-0000-1000-8000-00805f9b34fb");
|
||||
static const esp32_ble_tracker::ESPBTUUID WRITE_CHARACTERISTIC_UUID_V2 =
|
||||
esp32_ble_tracker::ESPBTUUID::from_raw("00001524-0000-1000-8000-00805f9b34fb");
|
||||
static const esp32_ble_tracker::ESPBTUUID READ_CHARACTERISTIC_UUID_V2 =
|
||||
esp32_ble_tracker::ESPBTUUID::from_raw("00001525-0000-1000-8000-00805f9b34fb");
|
||||
static const uint8_t WRITE_COMMAND_V2 = 0x40;
|
||||
|
||||
void RadonEyeRD200::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if,
|
||||
esp_ble_gattc_cb_param_t *param) {
|
||||
switch (event) {
|
||||
@ -23,6 +39,22 @@ void RadonEyeRD200::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
|
||||
}
|
||||
|
||||
case ESP_GATTC_SEARCH_CMPL_EVT: {
|
||||
if (this->parent()->get_service(SERVICE_UUID_V1) != nullptr) {
|
||||
service_uuid_ = SERVICE_UUID_V1;
|
||||
sensors_write_characteristic_uuid_ = WRITE_CHARACTERISTIC_UUID_V1;
|
||||
sensors_read_characteristic_uuid_ = READ_CHARACTERISTIC_UUID_V1;
|
||||
write_command_ = WRITE_COMMAND_V1;
|
||||
} else if (this->parent()->get_service(SERVICE_UUID_V2) != nullptr) {
|
||||
service_uuid_ = SERVICE_UUID_V2;
|
||||
sensors_write_characteristic_uuid_ = WRITE_CHARACTERISTIC_UUID_V2;
|
||||
sensors_read_characteristic_uuid_ = READ_CHARACTERISTIC_UUID_V2;
|
||||
write_command_ = WRITE_COMMAND_V2;
|
||||
} else {
|
||||
ESP_LOGW(TAG, "No supported device has been found, disconnecting");
|
||||
parent()->set_enabled(false);
|
||||
break;
|
||||
}
|
||||
|
||||
this->read_handle_ = 0;
|
||||
auto *chr = this->parent()->get_characteristic(service_uuid_, sensors_read_characteristic_uuid_);
|
||||
if (chr == nullptr) {
|
||||
@ -32,7 +64,6 @@ void RadonEyeRD200::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
|
||||
}
|
||||
this->read_handle_ = chr->handle;
|
||||
|
||||
// Write a 0x50 to the write characteristic.
|
||||
auto *write_chr = this->parent()->get_characteristic(service_uuid_, sensors_write_characteristic_uuid_);
|
||||
if (write_chr == nullptr) {
|
||||
ESP_LOGW(TAG, "No sensor write characteristic found at service %s char %s", service_uuid_.to_string().c_str(),
|
||||
@ -43,19 +74,14 @@ void RadonEyeRD200::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
|
||||
|
||||
this->node_state = esp32_ble_tracker::ClientState::ESTABLISHED;
|
||||
|
||||
request_read_values_();
|
||||
|
||||
write_query_message_();
|
||||
|
||||
request_read_values_();
|
||||
break;
|
||||
}
|
||||
|
||||
case ESP_GATTC_READ_CHAR_EVT: {
|
||||
if (param->read.conn_id != this->parent()->get_conn_id())
|
||||
break;
|
||||
if (param->read.status != ESP_GATT_OK) {
|
||||
ESP_LOGW(TAG, "Error reading char at handle %d, status=%d", param->read.handle, param->read.status);
|
||||
break;
|
||||
}
|
||||
case ESP_GATTC_NOTIFY_EVT: {
|
||||
if (param->read.handle == this->read_handle_) {
|
||||
read_sensors_(param->read.value, param->read.value_len);
|
||||
}
|
||||
@ -68,48 +94,48 @@ void RadonEyeRD200::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
|
||||
}
|
||||
|
||||
void RadonEyeRD200::read_sensors_(uint8_t *value, uint16_t value_len) {
|
||||
if (value_len < 20) {
|
||||
ESP_LOGD(TAG, "Invalid read");
|
||||
if (value_len < 1) {
|
||||
ESP_LOGW(TAG, "Unexpected empty message");
|
||||
return;
|
||||
}
|
||||
|
||||
// Example data
|
||||
// [13:08:47][D][radon_eye_rd200:107]: result bytes: 5010 85EBB940 00000000 00000000 2200 2500 0000
|
||||
ESP_LOGV(TAG, "result bytes: %02X%02X %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X %02X%02X %02X%02X",
|
||||
value[0], value[1], value[2], value[3], value[4], value[5], value[6], value[7], value[8], value[9],
|
||||
value[10], value[11], value[12], value[13], value[14], value[15], value[16], value[17], value[18],
|
||||
value[19]);
|
||||
uint8_t command = value[0];
|
||||
|
||||
if (value[0] != 0x50) {
|
||||
// This isn't a sensor reading.
|
||||
if ((command == WRITE_COMMAND_V1 && value_len < 20) || (command == WRITE_COMMAND_V2 && value_len < 68)) {
|
||||
ESP_LOGW(TAG, "Unexpected command 0x%02X message length %d", command, value_len);
|
||||
return;
|
||||
}
|
||||
|
||||
// Example data V1:
|
||||
// 501085EBB9400000000000000000220025000000
|
||||
// Example data V2:
|
||||
// 4042323230313033525532303338330652443230304e56322e302e3200014a00060a00080000000300010079300000e01108001c00020000003822005c8f423fa4709d3f
|
||||
ESP_LOGV(TAG, "radon sensors raw bytes");
|
||||
ESP_LOG_BUFFER_HEX_LEVEL(TAG, value, value_len, ESP_LOG_VERBOSE);
|
||||
|
||||
// Convert from pCi/L to Bq/m³
|
||||
constexpr float convert_to_bwpm3 = 37.0;
|
||||
|
||||
RadonValue radon_value;
|
||||
radon_value.chars[0] = value[2];
|
||||
radon_value.chars[1] = value[3];
|
||||
radon_value.chars[2] = value[4];
|
||||
radon_value.chars[3] = value[5];
|
||||
float radon_now = radon_value.number * convert_to_bwpm3;
|
||||
float radon_now; // in Bq/m³
|
||||
float radon_day; // in Bq/m³
|
||||
float radon_month; // in Bq/m³
|
||||
if (command == WRITE_COMMAND_V1) {
|
||||
radon_now = *(float *) (value + 2) * convert_to_bwpm3;
|
||||
radon_day = *(float *) (value + 6) * convert_to_bwpm3;
|
||||
radon_month = *(float *) (value + 10) * convert_to_bwpm3;
|
||||
} else if (command == WRITE_COMMAND_V2) {
|
||||
radon_now = *(uint16_t *) (value + 33);
|
||||
radon_day = *(uint16_t *) (value + 35);
|
||||
radon_month = *(uint16_t *) (value + 37);
|
||||
} else {
|
||||
ESP_LOGW(TAG, "Unexpected command value: 0x%02X", command);
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_valid_radon_value_(radon_now)) {
|
||||
radon_sensor_->publish_state(radon_now);
|
||||
}
|
||||
|
||||
radon_value.chars[0] = value[6];
|
||||
radon_value.chars[1] = value[7];
|
||||
radon_value.chars[2] = value[8];
|
||||
radon_value.chars[3] = value[9];
|
||||
float radon_day = radon_value.number * convert_to_bwpm3;
|
||||
|
||||
radon_value.chars[0] = value[10];
|
||||
radon_value.chars[1] = value[11];
|
||||
radon_value.chars[2] = value[12];
|
||||
radon_value.chars[3] = value[13];
|
||||
float radon_month = radon_value.number * convert_to_bwpm3;
|
||||
|
||||
if (is_valid_radon_value_(radon_month)) {
|
||||
ESP_LOGV(TAG, "Radon Long Term based on month");
|
||||
radon_long_term_sensor_->publish_state(radon_month);
|
||||
@ -129,7 +155,7 @@ void RadonEyeRD200::read_sensors_(uint8_t *value, uint16_t value_len) {
|
||||
parent()->set_enabled(false);
|
||||
}
|
||||
|
||||
bool RadonEyeRD200::is_valid_radon_value_(float radon) { return radon > 0.0 and radon < 37000; }
|
||||
bool RadonEyeRD200::is_valid_radon_value_(float radon) { return radon >= 0.0 and radon < 37000; }
|
||||
|
||||
void RadonEyeRD200::update() {
|
||||
if (this->node_state != esp32_ble_tracker::ClientState::ESTABLISHED) {
|
||||
@ -144,10 +170,9 @@ void RadonEyeRD200::update() {
|
||||
}
|
||||
|
||||
void RadonEyeRD200::write_query_message_() {
|
||||
ESP_LOGV(TAG, "writing 0x50 to write service");
|
||||
int request = 0x50;
|
||||
ESP_LOGV(TAG, "writing 0x%02x to write service", write_command_);
|
||||
auto status = esp_ble_gattc_write_char_descr(this->parent()->get_gattc_if(), this->parent()->get_conn_id(),
|
||||
this->write_handle_, sizeof(request), (uint8_t *) &request,
|
||||
this->write_handle_, sizeof(write_command_), (uint8_t *) &write_command_,
|
||||
ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
|
||||
if (status) {
|
||||
ESP_LOGW(TAG, "Error sending write request for sensor, status=%d", status);
|
||||
@ -155,10 +180,10 @@ void RadonEyeRD200::write_query_message_() {
|
||||
}
|
||||
|
||||
void RadonEyeRD200::request_read_values_() {
|
||||
auto status = esp_ble_gattc_read_char(this->parent()->get_gattc_if(), this->parent()->get_conn_id(),
|
||||
this->read_handle_, ESP_GATT_AUTH_REQ_NONE);
|
||||
auto status = esp_ble_gattc_register_for_notify(this->parent()->get_gattc_if(), this->parent()->get_remote_bda(),
|
||||
this->read_handle_);
|
||||
if (status) {
|
||||
ESP_LOGW(TAG, "Error sending read request for sensor, status=%d", status);
|
||||
ESP_LOGW(TAG, "Error registering for sensor notify, status=%d", status);
|
||||
}
|
||||
}
|
||||
|
||||
@ -167,11 +192,7 @@ void RadonEyeRD200::dump_config() {
|
||||
LOG_SENSOR(" ", "Radon Long Term", this->radon_long_term_sensor_);
|
||||
}
|
||||
|
||||
RadonEyeRD200::RadonEyeRD200()
|
||||
: PollingComponent(10000),
|
||||
service_uuid_(esp32_ble_tracker::ESPBTUUID::from_raw(SERVICE_UUID)),
|
||||
sensors_write_characteristic_uuid_(esp32_ble_tracker::ESPBTUUID::from_raw(WRITE_CHARACTERISTIC_UUID)),
|
||||
sensors_read_characteristic_uuid_(esp32_ble_tracker::ESPBTUUID::from_raw(READ_CHARACTERISTIC_UUID)) {}
|
||||
RadonEyeRD200::RadonEyeRD200() : PollingComponent(10000) {}
|
||||
|
||||
} // namespace radon_eye_rd200
|
||||
} // namespace esphome
|
||||
|
@ -14,10 +14,6 @@
|
||||
namespace esphome {
|
||||
namespace radon_eye_rd200 {
|
||||
|
||||
static const char *const SERVICE_UUID = "00001523-1212-efde-1523-785feabcd123";
|
||||
static const char *const WRITE_CHARACTERISTIC_UUID = "00001524-1212-efde-1523-785feabcd123";
|
||||
static const char *const READ_CHARACTERISTIC_UUID = "00001525-1212-efde-1523-785feabcd123";
|
||||
|
||||
class RadonEyeRD200 : public PollingComponent, public ble_client::BLEClientNode {
|
||||
public:
|
||||
RadonEyeRD200();
|
||||
@ -41,16 +37,12 @@ class RadonEyeRD200 : public PollingComponent, public ble_client::BLEClientNode
|
||||
sensor::Sensor *radon_sensor_{nullptr};
|
||||
sensor::Sensor *radon_long_term_sensor_{nullptr};
|
||||
|
||||
uint8_t write_command_;
|
||||
uint16_t read_handle_;
|
||||
uint16_t write_handle_;
|
||||
esp32_ble_tracker::ESPBTUUID service_uuid_;
|
||||
esp32_ble_tracker::ESPBTUUID sensors_write_characteristic_uuid_;
|
||||
esp32_ble_tracker::ESPBTUUID sensors_read_characteristic_uuid_;
|
||||
|
||||
union RadonValue {
|
||||
char chars[4];
|
||||
float number;
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace radon_eye_rd200
|
||||
|
Loading…
x
Reference in New Issue
Block a user