Creating Wh from an item with only instant W

I’ve finally fixed my code…

var {alerting} = require('personal');
var logger = log('Watt to Wh');

var now = time.ZonedDateTime.now(); 
var time_update = time.LocalDateTime.now();

//java.lang.Thread.sleep(500);

var item = items.getItem(event.itemName);
//var item = items.getItem('InverterPV_PVPower');
var item_lu = items.getItem(event.itemName + '_LastUpdate');
//var item_lu = items.getItem('InverterPV_PVPower_LastUpdate');
var item_wh = items.getItem(event.itemName + '_H');
//var item_wh = items.getItem('InverterPV_PVPower_H');
if (item_lu.state == 'NULL') {
     item_lu.postUpdate(time.LocalDateTime.now().toString());
     java.lang.Thread.sleep(500);
}

var pastupdate = item_lu.rawState.getZonedDateTime();

var lastvalue = item.state;
var previousvalue = item.history.historicState(pastupdate);  //var previousvalue = item.history.previousState(true);

var delta = '';
var delta = time.Duration.between(time.ZonedDateTime.parse(pastupdate.toString()), now).toMillis()/1000;
//var delta = time.Duration.between(time.ZonedDateTime.parse(pastupdate.toString()), now).seconds();
var updates_h = 1 / (3600/delta);
var Wh = (previousvalue * (1 / (3600/delta))).toFixed(4);
var kWh = (Wh/1000);
item_wh.postUpdate(Wh);

logger.info(now);
logger.info('Handling update for: ' + item.name + ' = ' + item.state);
logger.info(item.name + '  Past Update string: ' + item_lu.state.toString() + '          Now is: ' + now.toString() ); //logger.debug
logger.info(item.name + '  Past Update formatted ' + pastupdate );
logger.info(item.name + '  Last value is: -> ' + lastvalue + '         Past value is: -> ' + previousvalue );
logger.info(item.name + '  Delta: -> ' + delta.toString() + '           Updates/h: ' + updates_h.toString());
logger.info(item.name + '  Actual Wh: ' + Wh.toString() + '   Actual kWh: ' + kWh.toString());

item_lu.postUpdate(time_update.toString());  //update LastUpdate item with new time

Now my log looks like:

2022-06-11 00:34:59.443 [INFO ] [openhab.automation.script.watt to wh] - 2022-06-11T00:34:59.387+02:00[SYSTEM]

2022-06-11 00:34:59.446 [INFO ] [openhab.automation.script.watt to wh] - Handling update for: InverterPV_ACOutputW = 148

2022-06-11 00:34:59.449 [INFO ] [openhab.automation.script.watt to wh] - InverterPV_ACOutputW  Past Update string: 2022-06-11T00:34:54.446+0200          Now is: 2022-06-11T00:34:59.387+02:00[SYSTEM]

2022-06-11 00:34:59.451 [INFO ] [openhab.automation.script.watt to wh] - InverterPV_ACOutputW  Past Update formatted 1654900494446

2022-06-11 00:34:59.453 [INFO ] [openhab.automation.script.watt to wh] - InverterPV_ACOutputW  Last value is: -> 148         Past value is: -> 150

2022-06-11 00:34:59.455 [INFO ] [openhab.automation.script.watt to wh] - InverterPV_ACOutputW  Delta: -> 4.941           Updates/h: 0.0013725

2022-06-11 00:34:59.457 [INFO ] [openhab.automation.script.watt to wh] - InverterPV_ACOutputW  Actual Wh: 0.2059   Actual kWh: 0.0002059

But now I have my item having power consuption for the delta (usually 5sec).
Do I have to add another rule to calculate daily power consuption? Like

var {alerting} = require('personal');
var logger = log('Daily Wh calculator');

var today = time.ZonedDateTime.now().withHour(0).withMinute(0);

var item = items.getItem('InverterPV_ACOutputW_H');
var item_daily = items.getItem('[itemdaily]');

var totalpower = item.history.sumSince(today)/1000;

logger.info('Total daily power: ' + totalpower.toString() + "kWh");

And item may show Wh or kWh automatically? Or if I set Wh it will be always Wh?
My Item is:

  • Name: InverterPV_ACOutputW_H
  • Label: Used Power Wh
  • Type: Number:Energy
  • Category energy
  • Semantic Class: Measurement
  • Semantic Property: Energy

Yes.

You can choose which units you want to see regardless of the units the Item holds. For example, if you skip the divide by 1000 and update the Item using totalpower + "Wh" and set the Item’s State Description pattern to %.0f kWh it will show kWh on your UI even though the value stored by the Item is Wh.

Ok so better to work with kWh

But it’s possible that my rule, called from 2 items updated together, may interfere each other and I have wrong values?

2022-06-13 16:57:40.503 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'InverterPV_ACOutputW' changed from 434 to 427
2022-06-13 16:57:40.543 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'InverterPV_PVPowerW' changed from 500 W to 501 W
2022-06-13 16:57:40.547 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'InverterPV_ACOutputWh' changed from 0.2803 to 0.6027
2022-06-13 16:57:40.552 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'InverterPV_ACOutputW_LastUpdate' changed from 2022-06-13T16:57:35.504+0200 to 2022-06-13T16:57:40.506+0200
2022-06-13 16:57:40.590 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'InverterPV_PVPowerWh' changed from 0.4574 to 0.6942
2022-06-13 16:57:40.595 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'InverterPV_PVPowerW_LastUpdate' changed from 2022-06-13T16:57:35.558+0200 to 2022-06-13T16:57:40.557+0200
2022-06-13 16:57:49.932 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'InverterPV_ACOutputWh' changed from 0.6027 to 1.1088
2022-06-13 16:57:49.942 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'InverterPV_ACOutputW_LastUpdate' changed from 2022-06-13T16:57:40.506+0200 to 2022-06-13T16:57:49.857+0200
2022-06-13 16:57:50.025 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'InverterPV_PVPowerWh' changed from 0.6942 to 1.3072
2022-06-13 16:57:50.033 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'InverterPV_PVPowerW_LastUpdate' changed from 2022-06-13T16:57:40.557+0200 to 2022-06-13T16:57:49.952+0200
2022-06-13 16:57:54.865 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'InverterPV_ACOutputW' changed from 427 to 422

I call the rule for both InverterPV_ACOutputW and InverterPV_PowerW

Only one instance of a given rule can run at a time. If the rule is already running when triggered again, the second trigger will wait for the rule to exit before running the rule again.

So it’s impossible that first item value are “modified” from second item when firing the same rule? So it’s only my suggestion… Good to know. Thanks

I’m sorry if I’m opening this thread again but… The rule after update of Openhab to version 4 is not working anymore. As I understood, it is because I cannot read an item as Number:Power (instant power), calculate and then send to an item as Number: Energy.
And I I have to admit that I didn’t understand the quantity and modification of the target measurements.

Hope someone can help

It has been two years. Post your latest version of the rule.

Yes you’re right.
this is my code without any modifications:

var logger = log('Watt to Wh');

var now = time.ZonedDateTime.now(); 
var time_update = time.LocalDateTime.now();

var item = items.getItem(event.itemName);
//var item = items.getItem('InverterPV_PVPowerW');  //Testing purpose
var item_lu_meta = item.getMetadataValue('last_update') || time.LocalDateTime.now().toString();
var item_lu = items.getItem(event.itemName + '_LastUpdate');
//var item_lu = items.getItem('InverterPV_PVPowerW_LastUpdate');  //Testing purpose
var item_wh = items.getItem(event.itemName + 'h');
//var item_wh = items.getItem('InverterPV_PVPowerWh');  //Testing purpose
if (item_lu.state == 'NULL') {
     item_lu.postUpdate(time.LocalDateTime.now().toString());
     java.lang.Thread.sleep(500);
}

var pastupdate = item_lu.rawState.getZonedDateTime(); //Using last-update item
var pastupdate_meta = time.ZonedDateTime.parse(item_lu_meta);  //Using callign item metadata

var lastvalue = item.state;

var previousvalue = item.history.historicState(pastupdate_meta);

if (lastvalue !== previousvalue) {
    var delta = time.Duration.between(time.ZonedDateTime.parse(pastupdate.toString()), now).toMillis()/1000;
 
    if (delta < 30) {  //Check if last update was less than half minute, otherwise discard
      //var updates_h = 1 / (3600/delta);
      var Wh = (previousvalue * (1 / (3600/delta))).toFixed(4);
      item_wh.postUpdate(Wh);
    }
    else {
      logger.info('Update too old... Last update was: ' + delta.toString());
    }
    item_lu.postUpdate(time_update.toString());  //update LastUpdate item with new time
    item.updateMetadataValue('last_update',now.toString());
}