Help with basic script/rule to calculate COP heatpump

Hi,

I’m looking for some help, for most this would be easy/basic programming probably but to me this is quite complex.

I would like to calculate the COP of my heatpump or at least the energy generated.
This can be done by using the formula: Q=m x C x Delta T. Where:
m= kg/s, I have een items with the value in l/s. Therefore m= items_flow/60
C= constante water 4186 J/kg K
Delta T= Item_outlet-Item_inlet of the heatpump.

I have 3 items (flow, inlet, outlet) available where the data is updated every 30 second.
This formula calculate the amount of energy in watts, ideally I transform this into cumulative kWh number.

Anybody who can provide some help?

More information is required.

  • Item definitions
  • Desired programming language for the rules (Blockly would be a good choice)
  • UI or rules DSL
  • attempts you have tried yourself (we love to help but we don’t love just doing it for you)
  • specific details where you run into problems

In my experience, just coding it for you will be a miserable experience, result in dozens of waisted hours, and ultimately lead to your quitting OH entirely and my wanting to. So we need to meet half way.

Here’s my COP routine:

// Konstante für Wärmekapazität Wasser
var c = 4.183;

var Watt = items["Strom_Heizung"];
var kWh; // = items["Heizung_WMZ"];

// Liter/sekunde Wasserdurchfluss
// m3/h divided by 3600s per hour
var ls = 1750 / 3600;

// Spread between flow (VL) and return (RL) pipe
var Spread = (items["T_WP_VL"]) - (items["T_WP_RL"]);
var COP;
var kW;

// If pump is off, assume Spread=0
if (items["HKP"] == "OFF") Spread = 0;

// Only calculate if power consumption is over 100W
if (Watt > 100) {
  COP = c * ls * Spread * 1000;

  // Heizleistung
  kW = COP
  COP = COP / Watt;
  kWh = kW / 3600000;
  
  if (items["LGAWHP_Abtauen"] == "ON") {
    events.postUpdate("WMZ_Defrost", items["WMZ_Defrost"] + kWh);
  } else if (items["LGAWHP_Ventil"] == "ON") {
    events.postUpdate("WMZ_TWW", items["WMZ_TWW"] + kWh);
  } else {
    events.postUpdate("WMZ_Heizung", items["WMZ_Heizung"] + kWh);
  }
    
} else {
  COP = 0;
  kW = 0;
}

events.postUpdate("AWHP_kW", kW);
events.postUpdate("COP", COP);

Many thanks for the help both.

@rlkoshak I’m able to do some basic coding when in can find some similar code that can be use dot copy/paste/modify.

@Sascha_ Thanks! That was the kickstart I needed to get started.

So far this is wat I have made:

//Formule: Q=m x C x Delta T

var c = 4.183;
var flow = items["LGmodbusFlow_ValueasNumber"];

// Liter/seconds water debiet
// m3/h divided by 3600s per hour
var ls = flow / 60;

// Spread between flow (VL) and return (RL) pipe
var delta = (items["LGmodbuswateroutlet_ValueasNumber"]) - (items["LGmodbuswaterinlet_ValueasNumber"]);
var COP;

// Only calculate if delta T > 0
if (delta > 0) {
  var power = c * ls * delta ;
  
  events.postUpdate("LG_generated", power + ' kW')
  }

else {
  events.postUpdate("LG_generated", '0')
}

I don’t have the power consumption yet so I therefore will keep it to power generated only for now.

Some things I’m still struggling with:

  • The values now have many decimals (1.9325460000000023 kW), how can I parse this to maximum of 2 ( I tried a couple of ways but cannot get it to work)
  • I now use a rule that triggers as one of the items gets updated. Is this the best way or would it be possible to do this in the script automatically?
  • The formula is now calculating the watt’s produced every 30 second, can I convert this to a items with a cumulative value in kWh? I found time treats on the forum but have not fine a concrete solution so far.

Many thanks both of any help you can provide!

Do you need to? i.e. who cares about internal numbers, and also beware accumulating rounding errors (as you are also looking to aggregate your calculations over time).
If this is a presentation issue for tidy display, there are ways to do that instead. But who knows what you’ve tried already.

Fair enough. “Best” depends on what you want - and what you got (in terms of data input). Rule triggers are available for update and for change (updates include update-to-same). You might not want to recalculate unless there is a change. You might want to calculate based on a periodic update,

Sure.
As you say, there are a number of threads about this sort of thing.
Maybe you’d find out the elapsed time since the last calculation, then you’d have time x power and just need to scale to kWh, finally adding it to your rolling accumulator.

If you could provide a hint to only show maximum of 2 decibels at item level, that would be great. I’ve tried : "%.0f%“ as a state discription but that does not seem to work

I resolved it via implementing a rule that runs every 30 seconds:

configuration: {}
triggers:
  - id: "1"
    configuration:
      cronExpression: 0/30 * * * * ? *
    type: timer.GenericCronTrigger
conditions: []
actions:
  - inputs: {}
    id: "2"
    configuration:
      type: application/javascript
      script: "var watt = items[\"LG_generated\"];

        var kWh_old = items[\"LG_kWh_sum\"];



        var kWh = watt / 120

        var kWh_new = kWh_old + kWh


        events.postUpdate(\"LG_kWh_sum\", kWh_new + ' kWh')

        \ \ 

        \ "
    type: script.ScriptAction

Two things I would like to improve:

  • when the value of the items is NULL (only happened at the start) the rule does not work. Idea’s to solve this rear occasion?
  • Can I put this all into a script using If → cron time Then the script runs?

Set the State Description Item metadata to %.2f kWh. However, in the logs and in your calculations it will retain the extra decimal places.

This is a really bad approach. Over time, your calculation is going move farther an farther from the correct value due to rounding errors.

Test for NULL and only do stuff when it isn’t.

Please review the Getting Started Tutorial sections about Rules. This explains all the parts of a rule, what they are for, and what’s important here, answers your question (the answer is yes, of course).

Thanks! That worked!

Understood, that is exactly what I was afraid for. Any hints/direction on how to solve this in a better way? In different post I’ve read something on an accumulating sum but I could not find a good example to learn from.

Again, thanks. For someone with little programming skills any direction what works best is much appreciated! I really like to try and build the code myself, but it helps a lot when in can leverage from other work.

I misread what rule is doing. I though you were rounding the value every 30 seconds. That would be a bad idea. To accumulate a sum this rule should work OK, so long as you are not prematurely rounding the values.

One improvement would be to change the rule so it triggers when LG_Generated changes or updates instead of every 30 seconds.