mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +00:00 
			
		
		
		
	
							
								
								
									
										0
									
								
								esphome/components/xiaomi_cgd1/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								esphome/components/xiaomi_cgd1/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										43
									
								
								esphome/components/xiaomi_cgd1/sensor.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								esphome/components/xiaomi_cgd1/sensor.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| import esphome.codegen as cg | ||||
| import esphome.config_validation as cv | ||||
| from esphome.components import sensor, esp32_ble_tracker | ||||
| from esphome.const import CONF_BATTERY_LEVEL, CONF_HUMIDITY, CONF_MAC_ADDRESS, CONF_TEMPERATURE, \ | ||||
|     UNIT_CELSIUS, ICON_THERMOMETER, UNIT_PERCENT, ICON_WATER_PERCENT, ICON_BATTERY, CONF_ID, \ | ||||
|     CONF_BINDKEY | ||||
|  | ||||
| DEPENDENCIES = ['esp32_ble_tracker'] | ||||
| AUTO_LOAD = ['xiaomi_ble'] | ||||
|  | ||||
| xiaomi_cgd1_ns = cg.esphome_ns.namespace('xiaomi_cgd1') | ||||
| XiaomiCGD1 = xiaomi_cgd1_ns.class_('XiaomiCGD1', esp32_ble_tracker.ESPBTDeviceListener, | ||||
|                                    cg.Component) | ||||
|  | ||||
| CONFIG_SCHEMA = cv.Schema({ | ||||
|     cv.GenerateID(): cv.declare_id(XiaomiCGD1), | ||||
|     cv.Required(CONF_BINDKEY): cv.bind_key, | ||||
|     cv.Required(CONF_MAC_ADDRESS): cv.mac_address, | ||||
|     cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(UNIT_CELSIUS, ICON_THERMOMETER, 1), | ||||
|     cv.Optional(CONF_HUMIDITY): sensor.sensor_schema(UNIT_PERCENT, ICON_WATER_PERCENT, 1), | ||||
|     cv.Optional(CONF_BATTERY_LEVEL): sensor.sensor_schema(UNIT_PERCENT, ICON_BATTERY, 0), | ||||
| }).extend(esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA).extend(cv.COMPONENT_SCHEMA) | ||||
|  | ||||
|  | ||||
| def to_code(config): | ||||
|     var = cg.new_Pvariable(config[CONF_ID]) | ||||
|     yield cg.register_component(var, config) | ||||
|     yield esp32_ble_tracker.register_ble_device(var, config) | ||||
|  | ||||
|     cg.add(var.set_address(config[CONF_MAC_ADDRESS].as_hex)) | ||||
|     cg.add(var.set_bindkey(config[CONF_BINDKEY])) | ||||
|  | ||||
|     if CONF_TEMPERATURE in config: | ||||
|         sens = yield sensor.new_sensor(config[CONF_TEMPERATURE]) | ||||
|         cg.add(var.set_temperature(sens)) | ||||
|     if CONF_HUMIDITY in config: | ||||
|         sens = yield sensor.new_sensor(config[CONF_HUMIDITY]) | ||||
|         cg.add(var.set_humidity(sens)) | ||||
|     if CONF_BATTERY_LEVEL in config: | ||||
|         sens = yield sensor.new_sensor(config[CONF_BATTERY_LEVEL]) | ||||
|         cg.add(var.set_battery_level(sens)) | ||||
|  | ||||
|     cg.add_library("mbedtls", "cdf462088d") | ||||
							
								
								
									
										77
									
								
								esphome/components/xiaomi_cgd1/xiaomi_cgd1.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								esphome/components/xiaomi_cgd1/xiaomi_cgd1.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,77 @@ | ||||
| #include "xiaomi_cgd1.h" | ||||
| #include "esphome/core/log.h" | ||||
|  | ||||
| #ifdef ARDUINO_ARCH_ESP32 | ||||
|  | ||||
| namespace esphome { | ||||
| namespace xiaomi_cgd1 { | ||||
|  | ||||
| static const char *TAG = "xiaomi_cgd1"; | ||||
|  | ||||
| void XiaomiCGD1::dump_config() { | ||||
|   ESP_LOGCONFIG(TAG, "Xiaomi CGD1"); | ||||
|   ESP_LOGCONFIG(TAG, "  Bindkey: %s", hexencode(this->bindkey_, 16).c_str()); | ||||
|   LOG_SENSOR("  ", "Temperature", this->temperature_); | ||||
|   LOG_SENSOR("  ", "Humidity", this->humidity_); | ||||
|   LOG_SENSOR("  ", "Battery Level", this->battery_level_); | ||||
| } | ||||
|  | ||||
| bool XiaomiCGD1::parse_device(const esp32_ble_tracker::ESPBTDevice &device) { | ||||
|   if (device.address_uint64() != this->address_) { | ||||
|     ESP_LOGVV(TAG, "parse_device(): unknown MAC address."); | ||||
|     return false; | ||||
|   } | ||||
|   ESP_LOGVV(TAG, "parse_device(): MAC address %s found.", device.address_str().c_str()); | ||||
|  | ||||
|   bool success = false; | ||||
|   for (auto &service_data : device.get_service_datas()) { | ||||
|     auto res = xiaomi_ble::parse_xiaomi_header(service_data); | ||||
|     if (!res.has_value()) { | ||||
|       continue; | ||||
|     } | ||||
|     if (res->is_duplicate) { | ||||
|       continue; | ||||
|     } | ||||
|     if (res->has_encryption && | ||||
|         (!(xiaomi_ble::decrypt_xiaomi_payload(const_cast<std::vector<uint8_t> &>(service_data.data), this->bindkey_, | ||||
|                                               this->address_)))) { | ||||
|       continue; | ||||
|     } | ||||
|     if (!(xiaomi_ble::parse_xiaomi_message(service_data.data, *res))) { | ||||
|       continue; | ||||
|     } | ||||
|     if (!(xiaomi_ble::report_xiaomi_results(res, device.address_str()))) { | ||||
|       continue; | ||||
|     } | ||||
|     if (res->temperature.has_value() && this->temperature_ != nullptr) | ||||
|       this->temperature_->publish_state(*res->temperature); | ||||
|     if (res->humidity.has_value() && this->humidity_ != nullptr) | ||||
|       this->humidity_->publish_state(*res->humidity); | ||||
|     if (res->battery_level.has_value() && this->battery_level_ != nullptr) | ||||
|       this->battery_level_->publish_state(*res->battery_level); | ||||
|     success = true; | ||||
|   } | ||||
|  | ||||
|   if (!success) { | ||||
|     return false; | ||||
|   } | ||||
|  | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| void XiaomiCGD1::set_bindkey(const std::string &bindkey) { | ||||
|   memset(bindkey_, 0, 16); | ||||
|   if (bindkey.size() != 32) { | ||||
|     return; | ||||
|   } | ||||
|   char temp[3] = {0}; | ||||
|   for (int i = 0; i < 16; i++) { | ||||
|     strncpy(temp, &(bindkey.c_str()[i * 2]), 2); | ||||
|     bindkey_[i] = std::strtoul(temp, NULL, 16); | ||||
|   } | ||||
| } | ||||
|  | ||||
| }  // namespace xiaomi_cgd1 | ||||
| }  // namespace esphome | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										36
									
								
								esphome/components/xiaomi_cgd1/xiaomi_cgd1.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								esphome/components/xiaomi_cgd1/xiaomi_cgd1.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include "esphome/core/component.h" | ||||
| #include "esphome/components/sensor/sensor.h" | ||||
| #include "esphome/components/esp32_ble_tracker/esp32_ble_tracker.h" | ||||
| #include "esphome/components/xiaomi_ble/xiaomi_ble.h" | ||||
|  | ||||
| #ifdef ARDUINO_ARCH_ESP32 | ||||
|  | ||||
| namespace esphome { | ||||
| namespace xiaomi_cgd1 { | ||||
|  | ||||
| class XiaomiCGD1 : public Component, public esp32_ble_tracker::ESPBTDeviceListener { | ||||
|  public: | ||||
|   void set_address(uint64_t address) { address_ = address; }; | ||||
|   void set_bindkey(const std::string &bindkey); | ||||
|  | ||||
|   bool parse_device(const esp32_ble_tracker::ESPBTDevice &device) override; | ||||
|   void dump_config() override; | ||||
|   float get_setup_priority() const override { return setup_priority::DATA; } | ||||
|   void set_temperature(sensor::Sensor *temperature) { temperature_ = temperature; } | ||||
|   void set_humidity(sensor::Sensor *humidity) { humidity_ = humidity; } | ||||
|   void set_battery_level(sensor::Sensor *battery_level) { battery_level_ = battery_level; } | ||||
|  | ||||
|  protected: | ||||
|   uint64_t address_; | ||||
|   uint8_t bindkey_[16]; | ||||
|   sensor::Sensor *temperature_{nullptr}; | ||||
|   sensor::Sensor *humidity_{nullptr}; | ||||
|   sensor::Sensor *battery_level_{nullptr}; | ||||
| }; | ||||
|  | ||||
| }  // namespace xiaomi_cgd1 | ||||
| }  // namespace esphome | ||||
|  | ||||
| #endif | ||||
		Reference in New Issue
	
	Block a user