I have with Arlec PC191HA smart plugs with Power Monitoring (which uses bk72xx WB2S and BL0937). I could not find any combination of voltage_divider and current_resistor which gave reasonable values for voltage and current.
I use these plugs to detect when the washing machine has finished, or if the chest freezer door was left open. I don’t need the readings to be particularly accurate - but the figures from default switching of SEL were just ridiculous.
I ended up choosing to keep the SEL pin at reporting voltage permanently, and calculating current from a template. FWIW, this is my yaml code:
sensor:
# PC191HA includes a BL0937 chip for measuring power consumption
# and BL0937 is a variation of hlw8012, but using inverted SEL pin functionality
# Note that the first value reported should be ignored as inaccurate
- platform: hlw8012
model: BL0937 # note that the model must be specified to use special calculation parameters
sel_pin: # I believe that cf_pin reports either Voltage or Current depending on this select pin
inverted: true # determine whether true reports Voltage
number: P24
cf_pin: # current or voltage (ele_pin: 7)
inverted: true # the logic of BL0937 is opposite from HLW8012
number: P7
cf1_pin: # Power (vi_pin: 8)
inverted: true # the logic of BL0937 is opposite from HLW8012
number: P8
### Decided that I want Power and Voltage reported each time (not swapping with Current).
# I can choose not to keep swapping SEL pin, instead setting change_mode_every to a high value
# This means I will have to calculate the value for current (as a template) from power / voltage
initial_mode: "VOLTAGE" # reports VOLTAGE or CURRENT
change_mode_every: 4294967295 # about 4000 years before swapping.
# Adjust according to the actual resistor values on board to calibrate the specific unit
voltage_divider: 770 # LOWER VALUE GIVES LOWER VOLTAGE
current_resistor: 0.001 # HIGHER VALUE GIVES LOWER WATTAGE
# how the power monitoring values are returned to ESPHome
voltage:
name: $devicename Voltage
id: voltage
unit_of_measurement: V
accuracy_decimals: 2
filters:
- skip_initial: 1
power:
name: $devicename Power
id: power_sensor
unit_of_measurement: W
accuracy_decimals: 3
filters:
- skip_initial: 1
- multiply: 0.97
- lambda: if (x < 0.01) {return 0;} else {return x;}
energy:
name: $devicename Energy
id: energy
unit_of_measurement: kWh
accuracy_decimals: 3
filters:
- skip_initial: 1
- multiply: 0.001 # Multiplication factor from W to kW is 0.001
on_value:
then:
- lambda: |-
static float previous_energy_value = 0.0;
float current_energy_value = id(energy).state;
id(total_energy) += current_energy_value - previous_energy_value;
previous_energy_value = current_energy_value;
# instead of alternating reporting Voltage and Current, I will report Current from a template
- platform: template
name: $devicename Current
id: current
unit_of_measurement: A
accuracy_decimals: 3
lambda: |-
return (id(power_sensor).state / id(voltage).state );
filters:
- skip_initial: 2 # give time for data to settle to avoid NaN