esphome / feature-requests

ESPHome Feature Request Tracker
https://esphome.io/
411 stars 26 forks source link

Platform cse7766: support for power factor #1123

Closed micw closed 2 years ago

micw commented 3 years ago

Describe the problem you have/What new integration you would like

It would be nice if the platform would provide "power factor" as quotient of active power and apparant power. It can easily be calculated outside the platform but I think it would fit very well in a power measurement platform.

Please describe your use case for this integration and alternatives you've tried:

For the power factor without the need of scripting the calculation outside of the platform.

Additional context

An imlementation can be found here: https://github.com/arendst/Tasmota/blob/d4ddc78e6289b4d45e4f0dbb47a40489bd14f768/tasmota/xdrv_03_energy.ino#L943

poldim commented 2 years ago

Similarly, I'm looking for this data from my Sonoff S31. I have one plug that powers my homelab so I like being able to see the power factor of the load as they tend to be far from unity.

image

Markourai commented 2 years ago

Yes, please support this platform (for my sonoff dual r3). It’s already the case on ESPEasy and Tasmota. Thank you

Boh1 commented 2 years ago

I'm also interested in Power Factor support for the S31.

spikeygg commented 2 years ago

Ditto on this request, very interested in native PF reporting on the Sonoff S31 in ESPHome.

mkaatman commented 2 years ago

Hey Guys, Was having a discussion about this on discord.

@jesserockz comment was: "Yes, this is an example of something that is better done in yaml as the platforms should only really expose what the device is exposing."

And here's what we came up with: (plus some extras I had in my config) It updates every 60s

# s31power.yaml
sensor:
  - platform: cse7766 #https://esphome.io/components/sensor/cse7766.html
    power:
      name: $friendly_name Power
      unit_of_measurement: W
      id: wattage
      on_value:   # set or clear in_use template binary sensor depending on whether power usage is over threshold
        - if:
            condition:
              lambda: 'return (x >= id(threshold).state);'
            then:
              - binary_sensor.template.publish:
                  id: in_use
                  state: ON
            else:
              - binary_sensor.template.publish:
                  id: in_use
                  state: OFF
    current:
      id: current
      name: $friendly_name Current
      unit_of_measurement: A
    voltage:
      id: voltage
      name: $friendly_name Voltage
      unit_of_measurement: V
    update_interval: 10s # 20 second effective update rate for Power, 40 second for Current and Voltage.

  # Reports the total Power so-far each day, resets at midnight
  # See https://esphome.io/components/sensor/total_daily_energy.html
  - platform: total_daily_energy
    name: $friendly_name Total Daily Energy
    power_id: wattage
    filters:
        - multiply: 0.001  ## convert Wh to kWh
    unit_of_measurement: kWh

  - platform: template
    name: $friendly_name Power Factor
    id: power_factor
    lambda: return id(wattage).state / id(voltage).state / id(current).state;

number:      # used as a threshold for whether the plugged-in devices is running.
  - platform: template
    name: ${friendly_name} Use Threshold
    min_value: 1
    max_value: 100
    step: 1
    initial_value: 3
    id: threshold
    entity_category: config
    optimistic: true     # required for changing value from home assistant
    restore_value: true
    unit_of_measurement: Watt(s)
    mode: box
    on_value:
      - if:               # set or clear in_use template binary sensor depending on whether power usage is above threshold
          condition:
            lambda: 'return (id(wattage).state >= x);'
          then:
            - binary_sensor.template.publish:
                id: in_use
                state: ON
          else:
            - binary_sensor.template.publish:
                id: in_use
                state: OFF

From my individual device config I do something like:

substitutions:
  name: aquarium-bubbler
  friendly_name: Large Aquarium Bubbler
  device_description: Sonoff s31

packages:
    wifi: !include wifi.yaml
    s31: !include s31.yaml
    s31power: !include s31power.yaml ## I separate out power because I have some s31 lites too

esphome:
  name: $name
  comment: $device_description

# Enable Home Assistant API
api:

debug:

Here's my s31.yaml if it's helpful.

#https://templates.blakadder.com/sonoff_S31.html
#https://www.esphome-devices.com/devices/Sonoff-S31

esp8266:
  board: esp01_1m
  restore_from_flash: true

uart:
  rx_pin: RX
  baud_rate: 4800

logger:
  baud_rate: 0 # (UART logging interferes with cse7766)

status_led:
    pin:
      number: GPIO13
      inverted: true

binary_sensor:
  - platform: gpio
    id: button_in
    name:  $friendly_name Button
    pin:
      number: GPIO0
      mode: INPUT_PULLUP
      inverted: True
    entity_category: ''

    on_press:
        then:
          - if:
              condition: # only toggle relay if button is enabled
                lambda: 'return (id(select_button).state == "Enabled");'
              then:
                switch.toggle: relay

  - platform: template
    id: in_use
    name: $friendly_name Device In Use

switch:
    # blue LED follows relay power state
  - platform: gpio
    id: blue_led
    pin:
      number: GPIO13
      inverted: true

    # relay output
  - platform: gpio
    id: relay
    name: $friendly_name
    pin: GPIO12
    entity_category: ''

    # automatically make blue led equal relay state
    on_turn_on:
      - if:
          condition: # only if blue LED enabled
            lambda: 'return (id(select_led).state == "Enabled");'
          then:
            switch.turn_on: blue_led

    on_turn_off:
      - switch.turn_off: blue_led

button:
  - platform: restart
    id: restart_button
    name: $friendly_name Restart
    entity_category: diagnostic

# clock input from Home Assistant used to calculate total daily energy
time:
  - platform: homeassistant
    id: homeassistant_time

select:
    # option to disable button
  - platform: template
    name: $friendly_name Button
    id: select_button
    optimistic: true
    options:
      - Enabled
      - Disabled
    initial_option: Enabled
    restore_value: true
    icon: mdi:circle-double
    entity_category: config

    # option to disable blue LED
  - platform: template
    name: $friendly_name LED
    id: select_led
    optimistic: true
    entity_category: config
    options:
      - Enabled
      - Disabled
    initial_option: Enabled
    restore_value: true
    icon: mdi:led-on
    on_value:
      then:
      - if:
          condition:
            lambda: 'return ( (id(select_led).state == "Enabled") && id(relay).state );'
          then:
            switch.turn_on: blue_led
          else:
            switch.turn_off: blue_led