Virtual Mains Battery

I have created a virtual mains battery. Probably not the first, but I did not find any reference to something similar on the forum. So:

I have a solar installation in combination with a good old fashioned bidirectional utility meter. I can feed power back into the net and recuperate that energy at a later moment. So essentially I have a 100% efficient battery with infinite capacity.

I get the produced power from my solar installation and I measure the power consumption of the house. With those two numbers I can calculate the power going into the battery and the power taken from the utility. Power will flow into the virtual battery if the produced power is higher than the consumed power. Power will flow out the virtual battery if the solar power is less than the consumed power and the virtual battery is not empty.

Part of my dashboard looks like this:

The battery is now empty. But in the Power balance you can see we had some sun yesterday, that charged the battery, until it was again discharged in the early morning hours. This is one day in December, in the summer the battery will accumulate charge that will be consumed over weeks if not months after.

The relavant configuration.yaml file snippets:

# Sensors

sensor:

    # SMA inverter
  - platform: template
    sensors:
        solar_power:
            value_template: "{{ states('sensor.sma_grid_power') | float(0) | round(0) }}"
            unit_of_measurement: "W"
     
    # calculate electric power flows
  - platform: template
    sensors:
        battery_power:
            value_template: >
                {% if is_state("binary_sensor.battery_empty", "off") %}
                    {{ '%0.0f' | format(states('sensor.solar_power') | float - states('sensor.mains_power') | float) }}
                {% else %}
                    {{ '%0.0f' | format([ (states('sensor.solar_power') | float - states('sensor.mains_power') | float), 0 ] | max) }}
                {% endif %}
            unit_of_measurement: 'W'
            
        utility_power:
            value_template: >
               {{ '%0.0f' | format(states('sensor.mains_power') | float - states('sensor.solar_power') | float + states('sensor.battery_power') | float) }}
            unit_of_measurement: 'W'
                
        actual_power:
            value_template: >
               {{ '%0.0f' | format(states('sensor.mains_power') | float - states('sensor.solar_power') | float) }}
            unit_of_measurement: 'W'

        actual_current:
            value_template: >
               {{ '%0.1f' | format(states('sensor.mains_current') | float - states('sensor.sma_current_numeric') | float) }}
            unit_of_measurement: 'A'

    # calculate electric energy
  - platform: integration
    source: sensor.solar_power
    name: energy_produced
    method: left
    unit_prefix: k
    unit_time: h
    round: 3
    
  - platform: integration
    source: sensor.battery_power
    name: energy_stored
    method: left
    unit_prefix: k
    unit_time: h
    round: 3
    
  - platform: integration
    source: sensor.mains_power
    name: energy_consumed
    method: left
    unit_prefix: k
    unit_time: h
    round: 3

  - platform: integration
    source: sensor.utility_power
    name: energy_imported
    method: left
    unit_prefix: k
    unit_time: h
    round: 3

    # Battery storage (virtual mains battery)
  - platform: template
    sensors:
        battery_empty:
            value_template: "{{ states('sensor.energy_stored_meter') <= '0' }}"
            icon_template: >
                {% if is_state('binary_sensor.battery_empty', 'on') %}
                    mdi:battery-alert
                {% else %}
                    mdi:battery
                {% endif %}

# Meters

utility_meter:

    # Electric energy meters
    # solar
    energy_produced_meter:
        source: sensor.energy_produced
        cycle: yearly

    # virtual battery (charge or discharge)
    energy_stored_meter:
        source: sensor.energy_stored
        net_consumption: true
        cycle: yearly
        
    # consumption
    energy_consumed_meter:
        source: sensor.energy_consumed
        cycle: yearly

    # net consumption
    energy_imported_meter:
        source: sensor.energy_imported
        cycle: yearly

NOTES:
There is no battery state of charge calculation because the capacity is infinitive.

There is very small monthly fee (13 euro) that I pay to be allowed to feed back into the net. That is a very good price for 100% efficient battery with infinite capacity!

Once a year I pay the balance for net consumption, or if I have over-produced loose that overproduction. The annual meter reset takes care of that.

Nice work!
I’m also implementing a similar code right now for my new virtual battery contract.
Those are nice and simple sensor snippets :+1:
For the SoC you’re right as the capacity is infinity, however we can calculate a State of Energy = SoE. Then use that value in some automation to optimize our home energy flow.

@davidusb @VdR Nice. I would like to set up something similar. My energy provider has something similar on a monthyl basis. Whatever I produce and feed into the grid, gets cumulated. And then each month (this is on monthly basis) - if there is enough balance in “virtual battery”, it will deduct it from there.
So I am wondering if you can advise how to set things up and do calculations at each month start - basically look at last month, add what was produced to the virtual battery, deduct what I used from grid (if there was enough balance on virtual), etc.
I am wondering how would that be possible.

My iverter has sensors for each of needed values (delivered to the grid, yield, overall consumption…) so this is really only matter of running calculations at the month start.

If I understand you correctly, you need exactly what I have, with a small change to the ‘energy_stored_meter’. Mine is reset every year, you need to reset every month. All required configuration elements shown in the snippets.

Depending on your sensors, i.e. what power values you measure, what you measure and what you calculate from the power balance (first image) can be different.

Note that in my case any available charge in the battery is used before the grid is used (all mathematically of course). So I do not calculate how much I store in the year cumulatively, I calculate how much energy is stored in the virtual battery instantaneously.

I now also have a real time power flow chart on the dashboard. See below. Solar producing 2062 W (clouded day), house using 823 W, the balance goes back to the grid, but is shown as charging the virtual battery.

Definition of that card:

type: vertical-stack
cards:

  - type: custom:tesla-style-solar-power-card
    show_w_not_kw: 1
    name: Power Flow
    generation_to_house_entity: sensor.generation_to_house
    generation_to_battery_entity: sensor.battery_power_charge
    battery_to_house_entity: sensor.battery_power_discharge
    grid_to_house_entity: sensor.utility_power
    appliance1_consumption_entity: sensor.ev_charger_power
    grid_icon: mdi:transmission-tower
    generation_icon: mdi:solar-panel-large
    house_icon: mdi:home
    battery_icon: mdi:battery
    appliance1_icon: mdi:car-sports
    hide_inactive_lines: 1

  - type: entities
    title: Energy Balance 2022
    entities:
      - entity: sensor.energy_produced_meter
        name: Produced
        icon: mdi:chart-bar
      - entity: sensor.energy_consumed_meter
        name: Consumed
        icon: mdi:chart-bar
      - entity: sensor.energy_stored_meter_corrected
        icon: mdi:chart-bar
        name: Stored
      - entity: sensor.energy_imported_meter
        name: Imported
        icon: mdi:chart-bar

@VdR not entirely sure what you mean by “reset”.
The way it works is - for example:

It is May. My house consumes 500kWh, where 200kWh I produce with solar and use at that time, 300kWh I receive from the grid, + I export 1000kWh (as energy that I produced but could not use at that time). So at the end of May, my virtual battery balance is 1000kWh.

Then in June, I consume 500kWh again, where 300kWh is what I produce and use at that time, 200kWh I receive from the grid, + export 1200kWh. So at the end of june, it will be 2200kWh in virtual battery, however I used 200kWh, so the balance will be 2000.

Therefore while I can show how much do I export during month, it is always 1st day of the month when I need to do the calculations. + Think of scenario where I will have no energy in virtual battery, so that I can’t go to negative values.

It is simple to set up sensors and monitor all - production, export, yield, however I am looking for some inspiration as to how run those calculations periodically, on the first day of the month (let’s say immediately after midnight).

With reset I mean that the meter measuring the energy stored in the virtual battery, is reset to zero. So in my case, any energy stored at the end of the year, cannot be recuperated the year after, it is donated to the electricity company, so the meter is reset to zero. In reality in my case, with two EVs I will not have a positive balance mid winter. From what I understand in your case this reset has to happen every month.

I’m still not sure how you want to deal with your solar overproduction. What you overproduce today, could be used tomorrow. So do you want to see the net usage calculate in real time (as I do), or do you want to just add up all overproduction for the month? Either is possible, just have to adjust the calculation of the energy flows.

In general if you want to run some calculations at a certain time you define an automation for that. In your case that automation would have a trigger to run at then of every month.

1 Like