F520 Energy Managemet

Hi Luciano,
perhaps it is easier to measure the power output from the PV meter and the power of the energy meter … in this way you can understand the difference between the powers involved.

Hi I did this with my 2 f520, one for PV in eand one for consumption out, the out calculate out+in in same time, I use rules for subtract the PV to the in/out in this case I know the consumption and the production, but what I want is the amount total per day, week month, on sitemap because the old http page from btcino is not very attractive et not easy to access also I have only the new tablet witch can’t read these data, some of you succeed to have these data on rrdj4 or graphana?

Hi there. Yes i’ve been able to log values in influxdb+graphana. This is a screenshot.

great job can you explain the how to ? want to do the same …for sure

Ok, this is a quite long story. First of all let me explain the screenshot.
Chart on the top compare power generated (yellow) with total power consumed (orange), so you can see how your power generated is covering power consumption needs.
In the bottom charts you have Energy generated in the last 30 days (yellow) and energy consumed in the last 30 days (orange).
Dark yellow bars represent energy generated and not consumed (i.e. sent “ToGrid”). Light yellow represent energy generated AND consumed (i.e. "AutoCons"umed).
Dark orange is energy consumed, not generated by me (i.e. got “FromGrid”) and light orange is again AutoCons(umed).

I have a Fronius inverter and a couple of toroids attached to a Bticino F520.
Items are defined as follows:

// Power items (real-time)
Number Energy_PowerGenerated    "Potenza generata [%.0f W]"     <energy>    { channel="fronius:powerinverter:myFroniusBridge:myInverter:inverterdatachannelpac" }
Number Energy_PowerFromGrid     "Potenza prelevata [%.0f W]"    <energy>    { channel="openwebnet:bus_energy_central_unit:OWNBridge:EnergyFromGrid:power" }
Number Energy_PowerConsumption  "Potenza consumata [%.0f W]"    <energy>    { channel="openwebnet:bus_energy_central_unit:OWNBridge:EnergyConsumption:power" }
Number Energy_PowerToGrid       "Potenza immessa [%.0f W]"      <energy>    // calculated
Number Energy_PowerAutoCons     "Potenza autocons [%.0f W]"     <energy>    // calculated
Number Energy_PowerBalance      "Potenza bilancio [%.0f W]"     <energy>    // calculated

// Energy items (today)
Number Energy_Generated         "Energia generata [%.1f kWh]"   <energy>    { channel="fronius:powerinverter:myFroniusBridge:myInverter:inverterdatachanneldayenergy" }
Number Energy_Consumption       "Energia consumata [%.1f kWh]"  <energy>    { http="<[ifdb_energy_cons:5000:JSONPATH($.results[0].series[0].values[0][1])]" }
Number Energy_FromGrid          "Energia prelevata [%.1f kWh]"  <energy>    { http="<[ifdb_energy_fromG:5000:JSONPATH($.results[0].series[0].values[0][1])]" }
Number Energy_ToGrid            "Energia immessa [%.1f kWh]"    <energy>    // calculated
Number Energy_AutoCons          "Energia autocons [%.1f kWh]"   <energy>    // calculated

as you can see I have “power” itemes (for real-time power readings) and “energy” items, which measure energy in kWh.
Please also note that some items are pure readings, other are calculated.

Here are my rules for calculated items:

rule "rule_energytogrid"
when
  Item Energy_FromGrid changed or
  Item Energy_Consumption changed or
  Item Energy_Generated changed
then
  Energy_AutoCons.postUpdate(Energy_Consumption.state as Number - Energy_FromGrid.state as Number)
  Energy_ToGrid.postUpdate(Energy_Generated.state as Number - Energy_AutoCons.state as Number)
end

rule "rule_energycalc"
when
  System started or
  Item Energy_PowerFromGrid changed or
  Item Energy_PowerConsumption changed or
  Item Energy_PowerGenerated changed 
then
  var Number pinv = 0.0
  if (Energy_PowerGenerated.state != NULL) {
    pinv = (Energy_PowerGenerated.state as Number)
  }

  var Number pfromgrid = 0.0
  if (Energy_PowerFromGrid.state != NULL) {
    pfromgrid = (Energy_PowerFromGrid.state as Number)
  }

  var Number ptogrid = pinv
  var Number pcons = pfromgrid
  if (Energy_PowerConsumption.state != NULL) {
    pcons = (Energy_PowerConsumption.state as Number)
    ptogrid = ptogrid - pcons
  }

  if (ptogrid < 0 || pfromgrid > 0) {
    ptogrid = 0
  }
  Energy_PowerToGrid.postUpdate(ptogrid)
  Energy_PowerAutoCons.postUpdate(pcons-pfromgrid)
  Energy_PowerBalance.postUpdate(pfromgrid-ptogrid)
end

I assume that you have already installed InfluxDB and Grafana. If not, please search the community (there few topics that explain how to do it very well).

Let’s go to InfluxDB. Here you have the persistence file (influxdb.persist in persistence folder):

Items {
    Energy_Generated            : strategy = everyChange
    Energy_PowerGenerated       : strategy = everyChange
    Energy_PowerFromGrid        : strategy = everyChange
    Energy_PowerToGrid          : strategy = everyChange
    Energy_PowerConsumption     : strategy = everyChange
}

The issue I had to face was to calculate Energy, which is avg power in a specific period of time, starting from power readings (a part of Energy_Generated which I was lucky enough that Fronius inverter sends that information to me already).
So I decided to leverage InfluxDB which is powerful with time series, as its query language has powerful tools to re-sample or calculate integrals over time series.
In InfluxDB you can write “continuous queries”, which are queries that are run periodically, given the interval between 2 runs.

cq_EnergyCons  CREATE CONTINUOUS QUERY cq_EnergyCons ON openhab_db RESAMPLE EVERY 1m BEGIN SELECT integral(value, 1h) / 1000 AS Consumption INTO openhab_db.autogen.Energy_KPI FROM openhab_db.autogen.Energy_PowerConsumption GROUP BY time(1d) fill(previous) TZ('Europe/Rome') END
cq_EnergyFromG CREATE CONTINUOUS QUERY cq_EnergyFromG ON openhab_db RESAMPLE EVERY 1m BEGIN SELECT integral(value, 1h) / 1000 AS FromGrid INTO openhab_db.autogen.Energy_KPI FROM openhab_db.autogen.Energy_PowerFromGrid GROUP BY time(1d) fill(previous) TZ('Europe/Rome') END
cq_EnergyGen   CREATE CONTINUOUS QUERY cq_EnergyGen ON openhab_db RESAMPLE EVERY 1m BEGIN SELECT max(value) AS Generated INTO openhab_db.autogen.Energy_KPI FROM openhab_db.autogen.Energy_Generated GROUP BY time(1d) TZ('Europe/Rome') END

So now I have 1 table with daily KPIs. Energy consumed and got from grid are integrals of power values, in the 1 hour time frame (i.e. kWh). Energy generated is just the latest value, as I can get this information already calculated by the Inverter.

But continuous queries don’t fit all needs. I could not run other continuous queries to build also energy "AutoCons"umed and energy sent “ToGrid” starting from the 3 measures just created (continuous queries have limitations). Therefore I decided to run 2 other independent queries leveraging rules, items and REST APIs provided by InfluxDB.

Rule:

rule "rule_energy_everymin"
when
  Time cron "0 * * ? * *"
then
  Energy_AutoCons_Update.sendCommand(ON)
  Energy_ToGrid_Update.sendCommand(ON)
end

which every minute sends an ON command to a couple of items. The items are defined as:

// Items for POSTing queries to influxdb
Switch Energy_AutoCons_Update { http=">[ON:POST:http://192.168.2.105:8086/query?db=openhab_db&q=select+(Consumption-FromGrid)+as+AutoCons+into+Energy_KPI+from+Energy_KPI+WHERE+time%%3Enow()-2d]" }
Switch Energy_ToGrid_Update { http=">[ON:POST:http://192.168.2.105:8086/query?db=openhab_db&q=select+(Generated-AutoCons)+as+ToGrid+into+Energy_KPI+from+Energy_KPI+WHERE+time%%3Enow()-2d]" }

which items send POST commands to InfluxDB. You can easily recognize the query passed via the “q” parameter, which for the first command is:

select (Consumption-FromGrid) as AutoCons into Energy_KPI from Energy_KPI WHERE time%%3Enow()-2d

I’m sorry if this sounds complex or unclear (it was hard for me to re-build the whole story).
Hope it helps and feel free to ask additional questions.

Amazing post! Thank you very much!

I try to rebuild myself, actually I have 2x3 torus on 2xf520, but is the same idea, I’m not very familiar with influxdb and grafana but now is time to jump on! I gave you feedback soon, again very cool and helpful for me thanks!

Number Energy_PowerGenerated    "Potenza generata [%.0f W]"     <energy>    { channel="fronius:powerinverter:myFroniusBridge:myInverter:inverterdatachannelpac" }
Number Energy_PowerFromGrid     "Potenza prelevata [%.0f W]"    <energy>    { channel="openwebnet:bus_energy_central_unit:OWNBridge:EnergyFromGrid:power" }
Number Energy_PowerConsumption  "Potenza consumata [%.0f W]"    <energy>    { channel="openwebnet:bus_energy_central_unit:OWNBridge:EnergyConsumption:power" }

Back to and thanks for your extra help :slight_smile:

Here is where i stuck , like you i have torus on wire for Production directly from the inverter
this the “Energy_PowerGenerated” i think.

next is the "Energy_PowerFromGrid " ? torus can’t tell if is “IN” or “OUT” right ? for me "Energy_PowerFromGrid " read all passing through wires “IN” And “OUT” the grid right ?

Finaly the “Energy_PowerConsumption” where you pick this one ? i see is from your Energy Torus but how you do that ?

At me home is like that : I have 6 torus

  • 3 for reading 3 wires comming from Inverter , this is production from Solar Inverter

  • 3 others for reading the 3 wires General in to the house , theses 3 wires read “IN” and “OUT” all times (or you have a trick to help me :slight_smile: )

this is why i do this in rules " General - Production solar = real consumption " (but in fact some times i have negative value and is not right i know)

thanks for your help :+1:

Here me actual And very basic Rules And not Correct bicause when i do GeneralGrid - Production i have negative value… .

rule "Consomation electrique seule temp Reel"
  when
    Item ConsGenElec changed ///general in out
    or 
    Item ProdSolaire changed
  then
    ConElectriqueSeule.postUpdate( ConsGenElec.state as Number - ProdSolaire.state as Number )
  end

  rule "W/h remis sur le reseau en temp Reel"
  when
    Item ConsGenElec changed 
    or 
    Item ProdSolaire changed
  then
    
    ElecPositifReseau.postUpdate( ProdSolaire.state as Number - ConElectriqueSeule.state as Number )
  end

yes! Instead of you I’m luky enough that I can read this from the inverter, without installing a torus.

in my case, the torus reads only one direction (depending on how you place the torus). Means that I read positive values when the current is IN-going, and zero when it is OUT-going.
I don’t know if there are any torus that can read both directions, not mine.

I have another torus for this.
In total, I have 2 torus: Power IN (from grid) and total power consumed (torus on the wire that goes to the house).

not sure I understand: is your house pwered at 220V ? Or is it three phase?

I also get negative numbers when I do some math, this is because:

  • your readings are not synchronized, and when values change quickly readings may be “late”; I had to fix this by forcing zero when negative values don’t make sense
  • depending on how your wiring is, it might be that you miss some consumption in the readings (in my case, I miss the inverter consumption so this will always be a bias of about 10W :frowning: )

hope this helps.
ciao

Thanks a lot! So I need to verify if torus Cant read positif and négatif, in this way it will be fine,
. I read 3 wire because I have 3 phases+Neutral wire, I use f520 and torus is from btcino f524 and this torus :

You use the same?

It looks the same.