mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +00:00 
			
		
		
		
	Adding support for the Inkbird IBS-TH1 Mini sensor (#1099)
This commit is contained in:
		| @@ -37,6 +37,7 @@ esphome/components/globals/* @esphome/core | |||||||
| esphome/components/gpio/* @esphome/core | esphome/components/gpio/* @esphome/core | ||||||
| esphome/components/homeassistant/* @OttoWinter | esphome/components/homeassistant/* @OttoWinter | ||||||
| esphome/components/i2c/* @esphome/core | esphome/components/i2c/* @esphome/core | ||||||
|  | esphome/components/inkbird_ibsth1_mini/* @fkirill | ||||||
| esphome/components/inkplate6/* @jesserockz | esphome/components/inkplate6/* @jesserockz | ||||||
| esphome/components/integration/* @OttoWinter | esphome/components/integration/* @OttoWinter | ||||||
| esphome/components/interval/* @esphome/core | esphome/components/interval/* @esphome/core | ||||||
|   | |||||||
							
								
								
									
										0
									
								
								esphome/components/inkbird_ibsth1_mini/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								esphome/components/inkbird_ibsth1_mini/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,86 @@ | |||||||
|  | #include "inkbird_ibsth1_mini.h" | ||||||
|  | #include "esphome/core/log.h" | ||||||
|  |  | ||||||
|  | #ifdef ARDUINO_ARCH_ESP32 | ||||||
|  |  | ||||||
|  | namespace esphome { | ||||||
|  | namespace inkbird_ibsth1_mini { | ||||||
|  |  | ||||||
|  | static const char *TAG = "inkbird_ibsth1_mini"; | ||||||
|  |  | ||||||
|  | void InkbirdIBSTH1_MINI::dump_config() { | ||||||
|  |   ESP_LOGCONFIG(TAG, "Inkbird IBS TH1 MINI"); | ||||||
|  |   LOG_SENSOR("  ", "Temperature", this->temperature_); | ||||||
|  |   LOG_SENSOR("  ", "Humidity", this->humidity_); | ||||||
|  |   LOG_SENSOR("  ", "Battery Level", this->battery_level_); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool InkbirdIBSTH1_MINI::parse_device(const esp32_ble_tracker::ESPBTDevice &device) { | ||||||
|  |   // The below is based on my research and reverse engineering of a single device | ||||||
|  |   // It is entirely possible that some of that may be inaccurate or incomplete | ||||||
|  |  | ||||||
|  |   // for Inkbird IBS-TH1 Mini device we expect | ||||||
|  |   // 1) expected mac address | ||||||
|  |   // 2) device address type == PUBLIC | ||||||
|  |   // 3) no service datas | ||||||
|  |   // 4) one manufacturer datas | ||||||
|  |   // 5) the manufacturer datas should contain a 16-bit uuid amd a 7-byte data vector | ||||||
|  |   // 6) the 7-byte data component should have data[2] == 0 and data[6] == 8 | ||||||
|  |  | ||||||
|  |   // the address should match the address we declared | ||||||
|  |   if (device.address_uint64() != this->address_) { | ||||||
|  |     ESP_LOGVV(TAG, "parse_device(): unknown MAC address."); | ||||||
|  |     return false; | ||||||
|  |   } | ||||||
|  |   if (device.get_address_type() != BLE_ADDR_TYPE_PUBLIC) { | ||||||
|  |     ESP_LOGVV(TAG, "parse_device(): address is not public"); | ||||||
|  |     return false; | ||||||
|  |   } | ||||||
|  |   if (device.get_service_datas().size() != 0) { | ||||||
|  |     ESP_LOGVV(TAG, "parse_device(): service_data is expected to be empty"); | ||||||
|  |     return false; | ||||||
|  |   } | ||||||
|  |   auto mnfDatas = device.get_manufacturer_datas(); | ||||||
|  |   if (mnfDatas.size() != 1) { | ||||||
|  |     ESP_LOGVV(TAG, "parse_device(): manufacturer_datas is expected to have a single element"); | ||||||
|  |     return false; | ||||||
|  |   } | ||||||
|  |   auto mnfData = mnfDatas[0]; | ||||||
|  |   if (mnfData.uuid.get_uuid().len != ESP_UUID_LEN_16) { | ||||||
|  |     ESP_LOGVV(TAG, "parse_device(): manufacturer data element is expected to have uuid of length 16"); | ||||||
|  |     return false; | ||||||
|  |   } | ||||||
|  |   if (mnfData.data.size() != 7) { | ||||||
|  |     ESP_LOGVV(TAG, "parse_device(): manufacturer data element length is expected to be of length 7"); | ||||||
|  |     return false; | ||||||
|  |   } | ||||||
|  |   if ((mnfData.data[2] != 0) || (mnfData.data[6] != 8)) { | ||||||
|  |     ESP_LOGVV(TAG, "parse_device(): unexpected data"); | ||||||
|  |     return false; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // sensor output encoding | ||||||
|  |   // data[5] is a battery level | ||||||
|  |   // data[0] and data[1] is humidity * 100 (in pct) | ||||||
|  |   // uuid is a temperature * 100 (in Celcius) | ||||||
|  |   auto battery_level = mnfData.data[5]; | ||||||
|  |   auto temperature = mnfData.uuid.get_uuid().uuid.uuid16 / 100.0f; | ||||||
|  |   auto humidity = ((mnfData.data[1] << 8) + mnfData.data[0]) / 100.0f; | ||||||
|  |  | ||||||
|  |   if (this->temperature_ != nullptr) { | ||||||
|  |     this->temperature_->publish_state(temperature); | ||||||
|  |   } | ||||||
|  |   if (this->humidity_ != nullptr) { | ||||||
|  |     this->humidity_->publish_state(humidity); | ||||||
|  |   } | ||||||
|  |   if (this->battery_level_ != nullptr) { | ||||||
|  |     this->battery_level_->publish_state(battery_level); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | }  // namespace inkbird_ibsth1_mini | ||||||
|  | }  // namespace esphome | ||||||
|  |  | ||||||
|  | #endif | ||||||
							
								
								
									
										34
									
								
								esphome/components/inkbird_ibsth1_mini/inkbird_ibsth1_mini.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								esphome/components/inkbird_ibsth1_mini/inkbird_ibsth1_mini.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include "esphome/core/component.h" | ||||||
|  | #include "esphome/components/sensor/sensor.h" | ||||||
|  | #include "esphome/components/esp32_ble_tracker/esp32_ble_tracker.h" | ||||||
|  |  | ||||||
|  | #ifdef ARDUINO_ARCH_ESP32 | ||||||
|  |  | ||||||
|  | namespace esphome { | ||||||
|  | namespace inkbird_ibsth1_mini { | ||||||
|  |  | ||||||
|  | class InkbirdIBSTH1_MINI : public Component, public esp32_ble_tracker::ESPBTDeviceListener { | ||||||
|  |  public: | ||||||
|  |   void set_address(uint64_t address) { address_ = address; } | ||||||
|  |  | ||||||
|  |   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_; | ||||||
|  |   sensor::Sensor *temperature_{nullptr}; | ||||||
|  |   sensor::Sensor *humidity_{nullptr}; | ||||||
|  |   sensor::Sensor *battery_level_{nullptr}; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | }  // namespace inkbird_ibsth1_mini | ||||||
|  | }  // namespace esphome | ||||||
|  |  | ||||||
|  | #endif | ||||||
							
								
								
									
										38
									
								
								esphome/components/inkbird_ibsth1_mini/sensor.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								esphome/components/inkbird_ibsth1_mini/sensor.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | |||||||
|  | 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 | ||||||
|  |  | ||||||
|  | CODEOWNERS = ['@fkirill'] | ||||||
|  | DEPENDENCIES = ['esp32_ble_tracker'] | ||||||
|  |  | ||||||
|  | inkbird_ibsth1_mini_ns = cg.esphome_ns.namespace('inkbird_ibsth1_mini') | ||||||
|  | InkbirdUBSTH1_MINI = inkbird_ibsth1_mini_ns.class_( | ||||||
|  |     'InkbirdIBSTH1_MINI', esp32_ble_tracker.ESPBTDeviceListener, cg.Component) | ||||||
|  |  | ||||||
|  | CONFIG_SCHEMA = cv.Schema({ | ||||||
|  |     cv.GenerateID(): cv.declare_id(InkbirdUBSTH1_MINI), | ||||||
|  |     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)) | ||||||
|  |  | ||||||
|  |     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)) | ||||||
| @@ -181,6 +181,14 @@ sensor: | |||||||
|       name: 'ATC Battery-Level' |       name: 'ATC Battery-Level' | ||||||
|     battery_voltage: |     battery_voltage: | ||||||
|       name: 'ATC Battery-Voltage' |       name: 'ATC Battery-Voltage' | ||||||
|  |   - platform: inkbird_ibsth1_mini | ||||||
|  |     mac_address: 38:81:D7:0A:9C:11 | ||||||
|  |     temperature: | ||||||
|  |         name: 'Inkbird IBS-TH1 Temperature' | ||||||
|  |     humidity: | ||||||
|  |         name: 'Inkbird IBS-TH1 Humidity' | ||||||
|  |     battery_level: | ||||||
|  |         name: 'Inkbird IBS-TH1 Battery Level' | ||||||
|  |  | ||||||
| time: | time: | ||||||
|   - platform: homeassistant |   - platform: homeassistant | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user