Using excess solar energy variable in heaters and chargers

Hi community,

I set up home assistant to track solar/windpower production and consumption of the whole farm.
I use a Shelly 3EM for reading energy & power import and export (power-flow with positive or negative values).

Then I have templates that calculate the used power and the generated power, added up in Watts over all phases.

I built some ESPhome hardware for measurements based on the PZEM-004, but used also Tasmota plugs temporarely for reading energy production.

Also I made a power controller. The esp8266 outputs a pwm signal, which feeds a dimmer which is capable to regulate a few kilkowatts.

The ESP gets a power value from HA and controlls the power of an heating element.
Also the esp runs a service, where i can send an positive or negative offset to the actual power.
That was a long way, I worked several days to get it running and to calibrate. My knopwledge in coding is very basic.
All works fine so far.

The calibration is not very exact, I think because of voltage differences of the net and deviation of the dimmer because of heating up.
Because its a phase cutting dimmer, the power output is also not linear to the pwm-input.
But I’m inside 10% accuracy.

The YAML of the ESP might be interesting for some:

esphome:
  name: leistungssteller
  friendly_name: Leistungssteller

esp8266:
  board: esp01_1m

# Enable logging
logger:
  level: DEBUG

# Enable Home Assistant API
api:
  encryption:
    key: "xxxxxxxxxxxxxxxxxxxxxx"

    
  
  services:
    - service: adjust_power
      variables:
        offset: float
      then:
        - lambda: |-
            if ((id(output_power).state) + offset >= id(max_power).state)
              { id(output_power).publish_state(id(max_power).state); }
            if ((id(output_power).state) + offset <= 0)
              { id(output_power).publish_state(0); }
            else
              { id(output_power).publish_state(id(output_power).state + offset); }

ota:



wifi:
  ssid: "xxxxxxxxxxxxxxxxxxxx"
  password: ""

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "xxxxxxxxxxx"
    password: "xxxxxxxx"

captive_portal:


output:
  - platform: esp8266_pwm
    pin: GPIO16
    frequency: 1000 Hz
    id: pwm_output
    inverted: True
    min_power: 0.20
    max_power: 0.95
    zero_means_zero: True
    
sensor:
  - platform: homeassistant
    name: "Sollwert"
    entity_id: input_number.dumpload_power
    id: sollwert_vorgabe
    icon: "mdi:radiator"
    device_class: "power"
    unit_of_measurement: "W"
    accuracy_decimals: 0
    internal: True
    on_value:
      then:
        - lambda: |-
            id(output_power).publish_state(x);
       
  # - platform: homeassistant
    # entity_id: sensor.3phase_meter_pzem_pzem_004t_v3_power
    # id: power_flow
            
  - platform: template
    name: "Maximalleistung"
    id: max_power
    lambda: 'return 2120;'
    device_class: "power"
    unit_of_measurement: "W"

  - platform: template
    name: "Leistung"
    id: output_power
    device_class: "power"
    unit_of_measurement: "W"
    on_value:
      then:
        - lambda: |-
            id(pwm).publish_state(x);
            
  - platform: template
    name: "PWM output"
    id: pwm
    accuracy_decimals: 3
    icon: "mdi:pulse"
    filters:
      - calibrate_polynomial:
          degree: 3
          datapoints:
           - 0    -> 0
           - 2    -> 100
           - 36   -> 150
           - 59   -> 200
           - 110  -> 300
           - 182  -> 400
           - 285  -> 500
           - 407  -> 600
           - 550  -> 700
           - 708  -> 800
           - 875  -> 900
           - 1050 -> 1000
           - 1370 -> 1200
           - 1500 -> 1300
           - 1650 -> 1400
           - 1850 -> 1600
           - 2000 -> 1800
           - 2120 -> 1900
      - lambda: 'return x / id(max_power).state;'
    on_value:
      then:
        - lambda: |-
            id(pwm_output).set_level(x);

Now im looking for an automation: The goal is to use up most of the leftover energy in several dump loads in a cascade, each with its own ESPhome dimmer.
Later the same could be used to control an charger.

This is how I made it now via 2 automations in the automation dialog:

- id: '1679041958358'
  alias: Dumpload hoch
  description: ''
  trigger:
  - platform: numeric_state
    entity_id: sensor.power_flow
    for:
      hours: 0
      minutes: 0
      seconds: 0
    below: -100
  condition:
  - condition: numeric_state
    entity_id: sensor.power_flow
    below: -100
  - condition: numeric_state
    entity_id: sensor.leistungssteller_leistung
    above: sensor.leistungssteller_maximalleistung
  action:
  - repeat:
      while:
      - condition: numeric_state
        entity_id: sensor.power_flow
        below: -100
      sequence:
      - delay:
          hours: 0
          minutes: 0
          seconds: 2
          milliseconds: 0
      - service: esphome.leistungssteller_adjust_power
        data:
          offset: 50
  mode: single
- id: '1679074461130'
  alias: Dumpload runter
  description: ''
  trigger:
  - platform: numeric_state
    entity_id: sensor.power_flow
    for:
      hours: 0
      minutes: 0
      seconds: 0
    above: -50
    enabled: true
  condition:
  - condition: numeric_state
    entity_id: sensor.power_flow
    above: -50
    enabled: true
  - condition: numeric_state
    entity_id: sensor.leistungssteller_leistung
    above: 0
  action:
  - repeat:
      while:
      - condition: numeric_state
        entity_id: sensor.power_flow
        above: -50
      sequence:
      - service: esphome.leistungssteller_adjust_power
        data:
          offset: -50
      - delay:
          hours: 0
          minutes: 0
          seconds: 2
          milliseconds: 0
  mode: single

It works, but quite slow!
And somehow I think its not a good way to do.

If I reduce the delay, the power goes to much up and down, because the power_flow entity has some lag.

I also tried the PID-function in ESPhome, but I could not get this working. I think its the wrong application for this.

Whats a good solution for this? I’m really interested how other users would realize this.
Also with (later) distributed loads with priorities and some logic. We have different water heaters etc.

Thanks for advice!
Also for links to similar projects

1 Like

Hi there, I recently developed a solar excess optimizer based on a python module + blueprint for HA. Maybe it’s interesting for you: PV / Solar Excess Optimizer: Auto-control appliances (wallbox, dish washer, heatpump, ...) based on excess solar power

Hi Henrik,
I found your blueprints etc. already these days but I have not tried it yet. Very interesting!

My approach for now is to develop a single power regulator that is adjustable from 0-100% output power for resistive loads. The Hardware is working fine an my first tests are very promising:

Yellow: self used solar power
violet: solar power fed into the grid

Without regulator:

With regulator:

The little in-feed amounts are only because my “dumpload” power was less then solar production.
It is instantly regulating, so at enough solar production there is no movement at the main counter. The only limitation is the measuring speed of the main counter (shelly 3em)
I want to use this distributed on several places (water & room heaters), together with devices with fix consumption.
I think your Solar Excess Optimizer is the right thing for that!

As I see, your code supports dynamic current control. What is the output unit/signal for that, so I can make it compatible?

Hi there,

sorry I did not get a notification about your answer here.
The dynamic current control will set a value between min_current and max_current for the provided number entity. The unit is Ampere.

However I am also thinking about making the script compatible with “dimmer-like” devices which can be regulated from 0-100%. There is also another user who asked for that (see the discussion thread for my blueprint)

Also, as another small note, my script currently is not optimized for instant regulation of appliances. That’s why the minimum regulation/switching interval is 60s. However, that could be something which can be modified to provide a more instant regulation/switching for use cases like yours.

What dimmer did you use? The only ones I can find are of a low amperage.
My electric heater is 2.7Kw

2 Likes

Hello, I am also interested in this project. I tried to configure an esp32 using tasmota as the control part for a pwm module but without very good results. The command is not linear and I cannot maintain strict control using only the part of scenes available in HA. Can you help me with some tips?

Using excess solar energy to power heaters and chargers is a smart move! It’s a great way to make the most of the energy your panels are producing and reduce your reliance on the grid.