mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	Add support for BL0939 (Sonoff Dual R3 V2 powermeter) (#3300)
This commit is contained in:
		| @@ -31,6 +31,7 @@ esphome/components/bang_bang/* @OttoWinter | |||||||
| esphome/components/bedjet/* @jhansche | esphome/components/bedjet/* @jhansche | ||||||
| esphome/components/bh1750/* @OttoWinter | esphome/components/bh1750/* @OttoWinter | ||||||
| esphome/components/binary_sensor/* @esphome/core | esphome/components/binary_sensor/* @esphome/core | ||||||
|  | esphome/components/bl0939/* @ziceva | ||||||
| esphome/components/bl0940/* @tobias- | esphome/components/bl0940/* @tobias- | ||||||
| esphome/components/ble_client/* @buxtronix | esphome/components/ble_client/* @buxtronix | ||||||
| esphome/components/bme680_bsec/* @trvrnrth | esphome/components/bme680_bsec/* @trvrnrth | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								esphome/components/bl0939/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								esphome/components/bl0939/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | CODEOWNERS = ["@ziceva"] | ||||||
							
								
								
									
										144
									
								
								esphome/components/bl0939/bl0939.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								esphome/components/bl0939/bl0939.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,144 @@ | |||||||
|  | #include "bl0939.h" | ||||||
|  | #include "esphome/core/log.h" | ||||||
|  |  | ||||||
|  | namespace esphome { | ||||||
|  | namespace bl0939 { | ||||||
|  |  | ||||||
|  | static const char *const TAG = "bl0939"; | ||||||
|  |  | ||||||
|  | // https://www.belling.com.cn/media/file_object/bel_product/BL0939/datasheet/BL0939_V1.2_cn.pdf | ||||||
|  | // (unfortunatelly chinese, but the protocol can be understood with some translation tool) | ||||||
|  | static const uint8_t BL0939_READ_COMMAND = 0x55;  // 0x5{A4,A3,A2,A1} | ||||||
|  | static const uint8_t BL0939_FULL_PACKET = 0xAA; | ||||||
|  | static const uint8_t BL0939_PACKET_HEADER = 0x55; | ||||||
|  |  | ||||||
|  | static const uint8_t BL0939_WRITE_COMMAND = 0xA5;  // 0xA{A4,A3,A2,A1} | ||||||
|  | static const uint8_t BL0939_REG_IA_FAST_RMS_CTRL = 0x10; | ||||||
|  | static const uint8_t BL0939_REG_IB_FAST_RMS_CTRL = 0x1E; | ||||||
|  | static const uint8_t BL0939_REG_MODE = 0x18; | ||||||
|  | static const uint8_t BL0939_REG_SOFT_RESET = 0x19; | ||||||
|  | static const uint8_t BL0939_REG_USR_WRPROT = 0x1A; | ||||||
|  | static const uint8_t BL0939_REG_TPS_CTRL = 0x1B; | ||||||
|  |  | ||||||
|  | const uint8_t BL0939_INIT[6][6] = { | ||||||
|  |     // Reset to default | ||||||
|  |     {BL0939_WRITE_COMMAND, BL0939_REG_SOFT_RESET, 0x5A, 0x5A, 0x5A, 0x33}, | ||||||
|  |     // Enable User Operation Write | ||||||
|  |     {BL0939_WRITE_COMMAND, BL0939_REG_USR_WRPROT, 0x55, 0x00, 0x00, 0xEB}, | ||||||
|  |     // 0x0100 = CF_UNABLE energy pulse, AC_FREQ_SEL 50Hz, RMS_UPDATE_SEL 800mS | ||||||
|  |     {BL0939_WRITE_COMMAND, BL0939_REG_MODE, 0x00, 0x10, 0x00, 0x32}, | ||||||
|  |     // 0x47FF = Over-current and leakage alarm on, Automatic temperature measurement, Interval 100mS | ||||||
|  |     {BL0939_WRITE_COMMAND, BL0939_REG_TPS_CTRL, 0xFF, 0x47, 0x00, 0xF9}, | ||||||
|  |     // 0x181C = Half cycle, Fast RMS threshold 6172 | ||||||
|  |     {BL0939_WRITE_COMMAND, BL0939_REG_IA_FAST_RMS_CTRL, 0x1C, 0x18, 0x00, 0x16}, | ||||||
|  |     // 0x181C = Half cycle, Fast RMS threshold 6172 | ||||||
|  |     {BL0939_WRITE_COMMAND, BL0939_REG_IB_FAST_RMS_CTRL, 0x1C, 0x18, 0x00, 0x08}}; | ||||||
|  |  | ||||||
|  | void BL0939::loop() { | ||||||
|  |   DataPacket buffer; | ||||||
|  |   if (!this->available()) { | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |   if (read_array((uint8_t *) &buffer, sizeof(buffer))) { | ||||||
|  |     if (validate_checksum(&buffer)) { | ||||||
|  |       received_package_(&buffer); | ||||||
|  |     } | ||||||
|  |   } else { | ||||||
|  |     ESP_LOGW(TAG, "Junk on wire. Throwing away partial message"); | ||||||
|  |     while (read() >= 0) | ||||||
|  |       ; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool BL0939::validate_checksum(const DataPacket *data) { | ||||||
|  |   uint8_t checksum = BL0939_READ_COMMAND; | ||||||
|  |   // Whole package but checksum | ||||||
|  |   for (uint32_t i = 0; i < sizeof(data->raw) - 1; i++) { | ||||||
|  |     checksum += data->raw[i]; | ||||||
|  |   } | ||||||
|  |   checksum ^= 0xFF; | ||||||
|  |   if (checksum != data->checksum) { | ||||||
|  |     ESP_LOGW(TAG, "BL0939 invalid checksum! 0x%02X != 0x%02X", checksum, data->checksum); | ||||||
|  |   } | ||||||
|  |   return checksum == data->checksum; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void BL0939::update() { | ||||||
|  |   this->flush(); | ||||||
|  |   this->write_byte(BL0939_READ_COMMAND); | ||||||
|  |   this->write_byte(BL0939_FULL_PACKET); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void BL0939::setup() { | ||||||
|  |   for (auto *i : BL0939_INIT) { | ||||||
|  |     this->write_array(i, 6); | ||||||
|  |     delay(1); | ||||||
|  |   } | ||||||
|  |   this->flush(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void BL0939::received_package_(const DataPacket *data) const { | ||||||
|  |   // Bad header | ||||||
|  |   if (data->frame_header != BL0939_PACKET_HEADER) { | ||||||
|  |     ESP_LOGI("bl0939", "Invalid data. Header mismatch: %d", data->frame_header); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   float v_rms = (float) to_uint32_t(data->v_rms) / voltage_reference_; | ||||||
|  |   float ia_rms = (float) to_uint32_t(data->ia_rms) / current_reference_; | ||||||
|  |   float ib_rms = (float) to_uint32_t(data->ib_rms) / current_reference_; | ||||||
|  |   float a_watt = (float) to_int32_t(data->a_watt) / power_reference_; | ||||||
|  |   float b_watt = (float) to_int32_t(data->b_watt) / power_reference_; | ||||||
|  |   int32_t cfa_cnt = to_int32_t(data->cfa_cnt); | ||||||
|  |   int32_t cfb_cnt = to_int32_t(data->cfb_cnt); | ||||||
|  |   float a_energy_consumption = (float) cfa_cnt / energy_reference_; | ||||||
|  |   float b_energy_consumption = (float) cfb_cnt / energy_reference_; | ||||||
|  |   float total_energy_consumption = a_energy_consumption + b_energy_consumption; | ||||||
|  |  | ||||||
|  |   if (voltage_sensor_ != nullptr) { | ||||||
|  |     voltage_sensor_->publish_state(v_rms); | ||||||
|  |   } | ||||||
|  |   if (current_sensor_1_ != nullptr) { | ||||||
|  |     current_sensor_1_->publish_state(ia_rms); | ||||||
|  |   } | ||||||
|  |   if (current_sensor_2_ != nullptr) { | ||||||
|  |     current_sensor_2_->publish_state(ib_rms); | ||||||
|  |   } | ||||||
|  |   if (power_sensor_1_ != nullptr) { | ||||||
|  |     power_sensor_1_->publish_state(a_watt); | ||||||
|  |   } | ||||||
|  |   if (power_sensor_2_ != nullptr) { | ||||||
|  |     power_sensor_2_->publish_state(b_watt); | ||||||
|  |   } | ||||||
|  |   if (energy_sensor_1_ != nullptr) { | ||||||
|  |     energy_sensor_1_->publish_state(a_energy_consumption); | ||||||
|  |   } | ||||||
|  |   if (energy_sensor_2_ != nullptr) { | ||||||
|  |     energy_sensor_2_->publish_state(b_energy_consumption); | ||||||
|  |   } | ||||||
|  |   if (energy_sensor_sum_ != nullptr) { | ||||||
|  |     energy_sensor_sum_->publish_state(total_energy_consumption); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   ESP_LOGV("bl0939", "BL0939: U %fV, I1 %fA, I2 %fA, P1 %fW, P2 %fW, CntA %d, CntB %d, ∫P1 %fkWh, ∫P2 %fkWh", v_rms, | ||||||
|  |            ia_rms, ib_rms, a_watt, b_watt, cfa_cnt, cfb_cnt, a_energy_consumption, b_energy_consumption); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void BL0939::dump_config() {  // NOLINT(readability-function-cognitive-complexity) | ||||||
|  |   ESP_LOGCONFIG(TAG, "BL0939:"); | ||||||
|  |   LOG_SENSOR("", "Voltage", this->voltage_sensor_); | ||||||
|  |   LOG_SENSOR("", "Current 1", this->current_sensor_1_); | ||||||
|  |   LOG_SENSOR("", "Current 2", this->current_sensor_2_); | ||||||
|  |   LOG_SENSOR("", "Power 1", this->power_sensor_1_); | ||||||
|  |   LOG_SENSOR("", "Power 2", this->power_sensor_2_); | ||||||
|  |   LOG_SENSOR("", "Energy 1", this->energy_sensor_1_); | ||||||
|  |   LOG_SENSOR("", "Energy 2", this->energy_sensor_2_); | ||||||
|  |   LOG_SENSOR("", "Energy sum", this->energy_sensor_sum_); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | uint32_t BL0939::to_uint32_t(ube24_t input) { return input.h << 16 | input.m << 8 | input.l; } | ||||||
|  |  | ||||||
|  | int32_t BL0939::to_int32_t(sbe24_t input) { return input.h << 16 | input.m << 8 | input.l; } | ||||||
|  |  | ||||||
|  | }  // namespace bl0939 | ||||||
|  | }  // namespace esphome | ||||||
							
								
								
									
										107
									
								
								esphome/components/bl0939/bl0939.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								esphome/components/bl0939/bl0939.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,107 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include "esphome/core/component.h" | ||||||
|  | #include "esphome/components/uart/uart.h" | ||||||
|  | #include "esphome/components/sensor/sensor.h" | ||||||
|  |  | ||||||
|  | namespace esphome { | ||||||
|  | namespace bl0939 { | ||||||
|  |  | ||||||
|  | // https://datasheet.lcsc.com/lcsc/2108071830_BL-Shanghai-Belling-BL0939_C2841044.pdf | ||||||
|  | // (unfortunatelly chinese, but the formulas can be easily understood) | ||||||
|  | // Sonoff Dual R3 V2 has the exact same resistor values for the current shunts (RL=1miliOhm) | ||||||
|  | // and for the voltage divider (R1=0.51kOhm, R2=5*390kOhm) | ||||||
|  | // as in the manufacturer's reference circuit, so the same formulas were used here (Vref=1.218V) | ||||||
|  | static const float BL0939_IREF = 324004 * 1 / 1.218; | ||||||
|  | static const float BL0939_UREF = 79931 * 0.51 * 1000 / (1.218 * (5 * 390 + 0.51)); | ||||||
|  | static const float BL0939_PREF = 4046 * 1 * 0.51 * 1000 / (1.218 * 1.218 * (5 * 390 + 0.51)); | ||||||
|  | static const float BL0939_EREF = 3.6e6 * 4046 * 1 * 0.51 * 1000 / (1638.4 * 256 * 1.218 * 1.218 * (5 * 390 + 0.51)); | ||||||
|  |  | ||||||
|  | struct ube24_t {  // NOLINT(readability-identifier-naming,altera-struct-pack-align) | ||||||
|  |   uint8_t l; | ||||||
|  |   uint8_t m; | ||||||
|  |   uint8_t h; | ||||||
|  | } __attribute__((packed)); | ||||||
|  |  | ||||||
|  | struct ube16_t {  // NOLINT(readability-identifier-naming,altera-struct-pack-align) | ||||||
|  |   uint8_t l; | ||||||
|  |   uint8_t h; | ||||||
|  | } __attribute__((packed)); | ||||||
|  |  | ||||||
|  | struct sbe24_t {  // NOLINT(readability-identifier-naming,altera-struct-pack-align) | ||||||
|  |   uint8_t l; | ||||||
|  |   uint8_t m; | ||||||
|  |   int8_t h; | ||||||
|  | } __attribute__((packed)); | ||||||
|  |  | ||||||
|  | // Caveat: All these values are big endian (low - middle - high) | ||||||
|  |  | ||||||
|  | union DataPacket {  // NOLINT(altera-struct-pack-align) | ||||||
|  |   uint8_t raw[35]; | ||||||
|  |   struct { | ||||||
|  |     uint8_t frame_header;  // 0x55 according to docs | ||||||
|  |     ube24_t ia_fast_rms; | ||||||
|  |     ube24_t ia_rms; | ||||||
|  |     ube24_t ib_rms; | ||||||
|  |     ube24_t v_rms; | ||||||
|  |     ube24_t ib_fast_rms; | ||||||
|  |     sbe24_t a_watt; | ||||||
|  |     sbe24_t b_watt; | ||||||
|  |     sbe24_t cfa_cnt; | ||||||
|  |     sbe24_t cfb_cnt; | ||||||
|  |     ube16_t tps1; | ||||||
|  |     uint8_t RESERVED1;  // value of 0x00 | ||||||
|  |     ube16_t tps2; | ||||||
|  |     uint8_t RESERVED2;  // value of 0x00 | ||||||
|  |     uint8_t checksum;   // checksum | ||||||
|  |   }; | ||||||
|  | } __attribute__((packed)); | ||||||
|  |  | ||||||
|  | class BL0939 : public PollingComponent, public uart::UARTDevice { | ||||||
|  |  public: | ||||||
|  |   void set_voltage_sensor(sensor::Sensor *voltage_sensor) { voltage_sensor_ = voltage_sensor; } | ||||||
|  |   void set_current_sensor_1(sensor::Sensor *current_sensor_1) { current_sensor_1_ = current_sensor_1; } | ||||||
|  |   void set_current_sensor_2(sensor::Sensor *current_sensor_2) { current_sensor_2_ = current_sensor_2; } | ||||||
|  |   void set_power_sensor_1(sensor::Sensor *power_sensor_1) { power_sensor_1_ = power_sensor_1; } | ||||||
|  |   void set_power_sensor_2(sensor::Sensor *power_sensor_2) { power_sensor_2_ = power_sensor_2; } | ||||||
|  |   void set_energy_sensor_1(sensor::Sensor *energy_sensor_1) { energy_sensor_1_ = energy_sensor_1; } | ||||||
|  |   void set_energy_sensor_2(sensor::Sensor *energy_sensor_2) { energy_sensor_2_ = energy_sensor_2; } | ||||||
|  |   void set_energy_sensor_sum(sensor::Sensor *energy_sensor_sum) { energy_sensor_sum_ = energy_sensor_sum; } | ||||||
|  |  | ||||||
|  |   void loop() override; | ||||||
|  |  | ||||||
|  |   void update() override; | ||||||
|  |   void setup() override; | ||||||
|  |   void dump_config() override; | ||||||
|  |  | ||||||
|  |  protected: | ||||||
|  |   sensor::Sensor *voltage_sensor_; | ||||||
|  |   sensor::Sensor *current_sensor_1_; | ||||||
|  |   sensor::Sensor *current_sensor_2_; | ||||||
|  |   // NB This may be negative as the circuits is seemingly able to measure | ||||||
|  |   // power in both directions | ||||||
|  |   sensor::Sensor *power_sensor_1_; | ||||||
|  |   sensor::Sensor *power_sensor_2_; | ||||||
|  |   sensor::Sensor *energy_sensor_1_; | ||||||
|  |   sensor::Sensor *energy_sensor_2_; | ||||||
|  |   sensor::Sensor *energy_sensor_sum_; | ||||||
|  |  | ||||||
|  |   // Divide by this to turn into Watt | ||||||
|  |   float power_reference_ = BL0939_PREF; | ||||||
|  |   // Divide by this to turn into Volt | ||||||
|  |   float voltage_reference_ = BL0939_UREF; | ||||||
|  |   // Divide by this to turn into Ampere | ||||||
|  |   float current_reference_ = BL0939_IREF; | ||||||
|  |   // Divide by this to turn into kWh | ||||||
|  |   float energy_reference_ = BL0939_EREF; | ||||||
|  |  | ||||||
|  |   static uint32_t to_uint32_t(ube24_t input); | ||||||
|  |  | ||||||
|  |   static int32_t to_int32_t(sbe24_t input); | ||||||
|  |  | ||||||
|  |   static bool validate_checksum(const DataPacket *data); | ||||||
|  |  | ||||||
|  |   void received_package_(const DataPacket *data) const; | ||||||
|  | }; | ||||||
|  | }  // namespace bl0939 | ||||||
|  | }  // namespace esphome | ||||||
							
								
								
									
										123
									
								
								esphome/components/bl0939/sensor.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								esphome/components/bl0939/sensor.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,123 @@ | |||||||
|  | import esphome.codegen as cg | ||||||
|  | import esphome.config_validation as cv | ||||||
|  | from esphome.components import sensor, uart | ||||||
|  | from esphome.const import ( | ||||||
|  |     CONF_ID, | ||||||
|  |     CONF_VOLTAGE, | ||||||
|  |     DEVICE_CLASS_CURRENT, | ||||||
|  |     DEVICE_CLASS_ENERGY, | ||||||
|  |     DEVICE_CLASS_POWER, | ||||||
|  |     DEVICE_CLASS_VOLTAGE, | ||||||
|  |     STATE_CLASS_MEASUREMENT, | ||||||
|  |     UNIT_AMPERE, | ||||||
|  |     UNIT_KILOWATT_HOURS, | ||||||
|  |     UNIT_VOLT, | ||||||
|  |     UNIT_WATT, | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | DEPENDENCIES = ["uart"] | ||||||
|  |  | ||||||
|  | CONF_CURRENT_1 = "current_1" | ||||||
|  | CONF_CURRENT_2 = "current_2" | ||||||
|  | CONF_ACTIVE_POWER_1 = "active_power_1" | ||||||
|  | CONF_ACTIVE_POWER_2 = "active_power_2" | ||||||
|  | CONF_ENERGY_1 = "energy_1" | ||||||
|  | CONF_ENERGY_2 = "energy_2" | ||||||
|  | CONF_ENERGY_TOTAL = "energy_total" | ||||||
|  |  | ||||||
|  | bl0939_ns = cg.esphome_ns.namespace("bl0939") | ||||||
|  | BL0939 = bl0939_ns.class_("BL0939", cg.PollingComponent, uart.UARTDevice) | ||||||
|  |  | ||||||
|  | CONFIG_SCHEMA = ( | ||||||
|  |     cv.Schema( | ||||||
|  |         { | ||||||
|  |             cv.GenerateID(): cv.declare_id(BL0939), | ||||||
|  |             cv.Optional(CONF_VOLTAGE): sensor.sensor_schema( | ||||||
|  |                 unit_of_measurement=UNIT_VOLT, | ||||||
|  |                 accuracy_decimals=1, | ||||||
|  |                 device_class=DEVICE_CLASS_VOLTAGE, | ||||||
|  |                 state_class=STATE_CLASS_MEASUREMENT, | ||||||
|  |             ), | ||||||
|  |             cv.Optional(CONF_CURRENT_1): sensor.sensor_schema( | ||||||
|  |                 unit_of_measurement=UNIT_AMPERE, | ||||||
|  |                 accuracy_decimals=2, | ||||||
|  |                 device_class=DEVICE_CLASS_CURRENT, | ||||||
|  |                 state_class=STATE_CLASS_MEASUREMENT, | ||||||
|  |             ), | ||||||
|  |             cv.Optional(CONF_CURRENT_2): sensor.sensor_schema( | ||||||
|  |                 unit_of_measurement=UNIT_AMPERE, | ||||||
|  |                 accuracy_decimals=2, | ||||||
|  |                 device_class=DEVICE_CLASS_CURRENT, | ||||||
|  |                 state_class=STATE_CLASS_MEASUREMENT, | ||||||
|  |             ), | ||||||
|  |             cv.Optional(CONF_ACTIVE_POWER_1): sensor.sensor_schema( | ||||||
|  |                 unit_of_measurement=UNIT_WATT, | ||||||
|  |                 accuracy_decimals=0, | ||||||
|  |                 device_class=DEVICE_CLASS_POWER, | ||||||
|  |                 state_class=STATE_CLASS_MEASUREMENT, | ||||||
|  |             ), | ||||||
|  |             cv.Optional(CONF_ACTIVE_POWER_2): sensor.sensor_schema( | ||||||
|  |                 unit_of_measurement=UNIT_WATT, | ||||||
|  |                 accuracy_decimals=0, | ||||||
|  |                 device_class=DEVICE_CLASS_POWER, | ||||||
|  |                 state_class=STATE_CLASS_MEASUREMENT, | ||||||
|  |             ), | ||||||
|  |             cv.Optional(CONF_ENERGY_1): sensor.sensor_schema( | ||||||
|  |                 unit_of_measurement=UNIT_KILOWATT_HOURS, | ||||||
|  |                 accuracy_decimals=3, | ||||||
|  |                 device_class=DEVICE_CLASS_ENERGY, | ||||||
|  |             ), | ||||||
|  |             cv.Optional(CONF_ENERGY_2): sensor.sensor_schema( | ||||||
|  |                 unit_of_measurement=UNIT_KILOWATT_HOURS, | ||||||
|  |                 accuracy_decimals=3, | ||||||
|  |                 device_class=DEVICE_CLASS_ENERGY, | ||||||
|  |             ), | ||||||
|  |             cv.Optional(CONF_ENERGY_TOTAL): sensor.sensor_schema( | ||||||
|  |                 unit_of_measurement=UNIT_KILOWATT_HOURS, | ||||||
|  |                 accuracy_decimals=3, | ||||||
|  |                 device_class=DEVICE_CLASS_ENERGY, | ||||||
|  |             ), | ||||||
|  |         } | ||||||
|  |     ) | ||||||
|  |     .extend(cv.polling_component_schema("60s")) | ||||||
|  |     .extend(uart.UART_DEVICE_SCHEMA) | ||||||
|  | ) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | async def to_code(config): | ||||||
|  |     var = cg.new_Pvariable(config[CONF_ID]) | ||||||
|  |     await cg.register_component(var, config) | ||||||
|  |     await uart.register_uart_device(var, config) | ||||||
|  |  | ||||||
|  |     if CONF_VOLTAGE in config: | ||||||
|  |         conf = config[CONF_VOLTAGE] | ||||||
|  |         sens = await sensor.new_sensor(conf) | ||||||
|  |         cg.add(var.set_voltage_sensor(sens)) | ||||||
|  |     if CONF_CURRENT_1 in config: | ||||||
|  |         conf = config[CONF_CURRENT_1] | ||||||
|  |         sens = await sensor.new_sensor(conf) | ||||||
|  |         cg.add(var.set_current_sensor_1(sens)) | ||||||
|  |     if CONF_CURRENT_2 in config: | ||||||
|  |         conf = config[CONF_CURRENT_2] | ||||||
|  |         sens = await sensor.new_sensor(conf) | ||||||
|  |         cg.add(var.set_current_sensor_2(sens)) | ||||||
|  |     if CONF_ACTIVE_POWER_1 in config: | ||||||
|  |         conf = config[CONF_ACTIVE_POWER_1] | ||||||
|  |         sens = await sensor.new_sensor(conf) | ||||||
|  |         cg.add(var.set_power_sensor_1(sens)) | ||||||
|  |     if CONF_ACTIVE_POWER_2 in config: | ||||||
|  |         conf = config[CONF_ACTIVE_POWER_2] | ||||||
|  |         sens = await sensor.new_sensor(conf) | ||||||
|  |         cg.add(var.set_power_sensor_2(sens)) | ||||||
|  |     if CONF_ENERGY_1 in config: | ||||||
|  |         conf = config[CONF_ENERGY_1] | ||||||
|  |         sens = await sensor.new_sensor(conf) | ||||||
|  |         cg.add(var.set_energy_sensor_1(sens)) | ||||||
|  |     if CONF_ENERGY_2 in config: | ||||||
|  |         conf = config[CONF_ENERGY_2] | ||||||
|  |         sens = await sensor.new_sensor(conf) | ||||||
|  |         cg.add(var.set_energy_sensor_2(sens)) | ||||||
|  |     if CONF_ENERGY_TOTAL in config: | ||||||
|  |         conf = config[CONF_ENERGY_TOTAL] | ||||||
|  |         sens = await sensor.new_sensor(conf) | ||||||
|  |         cg.add(var.set_energy_sensor_sum(sens)) | ||||||
| @@ -256,6 +256,12 @@ uart: | |||||||
|     tx_pin: GPIO4 |     tx_pin: GPIO4 | ||||||
|     rx_pin: GPIO5 |     rx_pin: GPIO5 | ||||||
|     baud_rate: 38400 |     baud_rate: 38400 | ||||||
|  |   - id: uart8 | ||||||
|  |     tx_pin: GPIO4 | ||||||
|  |     rx_pin: GPIO5 | ||||||
|  |     baud_rate: 4800 | ||||||
|  |     parity: NONE | ||||||
|  |     stop_bits: 2 | ||||||
|     # Specifically added for testing debug with no options at all. |     # Specifically added for testing debug with no options at all. | ||||||
|     debug: |     debug: | ||||||
|  |  | ||||||
| @@ -477,6 +483,24 @@ sensor: | |||||||
|     active_power_b: |     active_power_b: | ||||||
|       name: ADE7953 Active Power B |       name: ADE7953 Active Power B | ||||||
|       id: ade7953_active_power_b |       id: ade7953_active_power_b | ||||||
|  |   - platform: bl0939 | ||||||
|  |     uart_id: uart8 | ||||||
|  |     voltage: | ||||||
|  |       name: 'BL0939 Voltage' | ||||||
|  |     current_1: | ||||||
|  |       name: 'BL0939 Current 1' | ||||||
|  |     current_2: | ||||||
|  |       name: 'BL0939 Current 2' | ||||||
|  |     active_power_1: | ||||||
|  |       name: 'BL0939 Active Power 1' | ||||||
|  |     active_power_2: | ||||||
|  |       name: 'BL0939 Active Power 2' | ||||||
|  |     energy_1: | ||||||
|  |       name: 'BL0939 Energy 1' | ||||||
|  |     energy_2: | ||||||
|  |       name: 'BL0939 Energy 2' | ||||||
|  |     energy_total: | ||||||
|  |       name: 'BL0939 Total energy' | ||||||
|   - platform: bl0940 |   - platform: bl0940 | ||||||
|     uart_id: uart3 |     uart_id: uart3 | ||||||
|     voltage: |     voltage: | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user