Total energy consumed in kWh day/week/mont/year

Yeh, sorry about that, but I have a work in progress calculating cost.
Here in Norway we have hourly spot prices throughout the day forecasted by NordPool a day in advance.
I have made a scraper for that data, but haven’t finished it all yet, so I snipped out the part you got, but might have forgot to remove a line or two.

The other items you didn’t get was indeed those cost items. :slight_smile:

Since I haven’t figured out how to make arrays of items, I ended up doing this:

Number nextDay23_24 (nextDayHourlyPrices)
Number nextDay24_01 (nextDayHourlyPrices)
Number nextDay01_02 (nextDayHourlyPrices)
Number nextDay02_03 (nextDayHourlyPrices)
Number nextDay03_04 (nextDayHourlyPrices)
Number nextDay04_05 (nextDayHourlyPrices)
Number nextDay05_06 (nextDayHourlyPrices)
Number nextDay06_07 (nextDayHourlyPrices)
Number nextDay07_08 (nextDayHourlyPrices)
Number nextDay08_09 (nextDayHourlyPrices)
Number nextDay09_10 (nextDayHourlyPrices)
Number nextDay10_11 (nextDayHourlyPrices)
Number nextDay11_12 (nextDayHourlyPrices)
Number nextDay12_13 (nextDayHourlyPrices)
Number nextDay13_14 (nextDayHourlyPrices)
Number nextDay14_15 (nextDayHourlyPrices)
Number nextDay15_16 (nextDayHourlyPrices)
Number nextDay16_17 (nextDayHourlyPrices)
Number nextDay17_18 (nextDayHourlyPrices)
Number nextDay18_19 (nextDayHourlyPrices)
Number nextDay19_20 (nextDayHourlyPrices)
Number nextDay20_21 (nextDayHourlyPrices)
Number nextDay21_22 (nextDayHourlyPrices)
Number nextDay22_23 (nextDayHourlyPrices)

Number toDay23_24 (toDayHourlyPrices)
Number toDay24_01 (toDayHourlyPrices)
Number toDay01_02 (toDayHourlyPrices)
Number toDay02_03 (toDayHourlyPrices)
Number toDay03_04 (toDayHourlyPrices)
Number toDay04_05 (toDayHourlyPrices)
Number toDay05_06 (toDayHourlyPrices)
Number toDay06_07 (toDayHourlyPrices)
Number toDay07_08 (toDayHourlyPrices)
Number toDay08_09 (toDayHourlyPrices)
Number toDay09_10 (toDayHourlyPrices)
Number toDay10_11 (toDayHourlyPrices)
Number toDay11_12 (toDayHourlyPrices)
Number toDay12_13 (toDayHourlyPrices)
Number toDay13_14 (toDayHourlyPrices)
Number toDay14_15 (toDayHourlyPrices)
Number toDay15_16 (toDayHourlyPrices)
Number toDay16_17 (toDayHourlyPrices)
Number toDay17_18 (toDayHourlyPrices)
Number toDay18_19 (toDayHourlyPrices)
Number toDay19_20 (toDayHourlyPrices)
Number toDay20_21 (toDayHourlyPrices)
Number toDay21_22 (toDayHourlyPrices)
Number toDay22_23 (toDayHourlyPrices)

and in the JSS rule:

    function calcHourlyConsumptionCost(hourlyConsumption) {  
      // fetch NordPool hourly price for this hour interval
      switch (today.getHours()) {
        case 0:
          hourlyPrice = parseFloat(items.getItem("toDay24_01").state)
          break
        case 1:
          hourlyPrice = parseFloat(items.getItem("toDay01_02").state)
          break
        case 2:
          hourlyPrice = parseFloat(items.getItem("toDay02_03").state)
          break
        case 3:
          hourlyPrice = parseFloat(items.getItem("toDay03_04").state)
          break
        case 4:
          hourlyPrice = parseFloat(items.getItem("toDay04_05").state)
          break
        case 5:
          hourlyPrice = parseFloat(items.getItem("toDay05_06").state)
          break
        case 6:
          hourlyPrice = parseFloat(items.getItem("toDay06_07").state)
          break
        case 7:
          hourlyPrice = parseFloat(items.getItem("toDay07_08").state)
          break
        case 8:
          hourlyPrice = parseFloat(items.getItem("toDay08_09").state)
          break
        case 9:
          hourlyPrice = parseFloat(items.getItem("toDay09_10").state)
          break
        case 10:
          hourlyPrice = parseFloat(items.getItem("toDay10_11").state)
          break
        case 11:
          hourlyPrice = parseFloat(items.getItem("toDay11_12").state)
          break
        case 12:
          hourlyPrice = parseFloat(items.getItem("toDay12_13").state)
          break
        case 13:
          hourlyPrice = parseFloat(items.getItem("toDay13_14").state)
          break
        case 14:
          hourlyPrice = parseFloat(items.getItem("toDay14_15").state)
          break
        case 15:
          hourlyPrice = parseFloat(items.getItem("toDay15_16").state)
          break
        case 16:
          hourlyPrice = parseFloat(items.getItem("toDay16_17").state)
          break
        case 17:
          hourlyPrice = parseFloat(items.getItem("toDay17_18").state)
          break
        case 18:
          hourlyPrice = parseFloat(items.getItem("toDay18_19").state)
          break
        case 19:
          hourlyPrice = parseFloat(items.getItem("toDay19_20").state)
          break
        case 20:
          hourlyPrice = parseFloat(items.getItem("toDay20_21").state)
          break
        case 21:
          hourlyPrice = parseFloat(items.getItem("toDay21_22").state)
          break
        case 22:
          hourlyPrice = parseFloat(items.getItem("toDay22_23").state)
          break
        case 23:
          hourlyPrice = parseFloat(items.getItem("toDay23_24").state)
          break
        default:
          hourlyPrice = 0.0
          break      
      }
      console.log("hourlyPrice=(NOK) " + (hourlyPrice*hourlyConsumption)/1000)
    }

WTF! i will never be skilled as you in scripting :frowning:

one last question, my energy meter gives me info in kw and not in kWH. i would like to add just a “/ 100” to keep units in kWH but with right values. i think i just need to add “/ 100” to minute consumption (and all other values will be automatically okay), but i cannot find the line where to add it.
can you point me to the right direction?
and if possibile, to have all values with max 3 decimal numbers like 0.323 kWH.

thanks!

If it’s the same power meter you posted a few posts up, the instantaneous power consumption is in W.
If you want to do calculations in kW instead, you need to divide by 1000. (k=kilo=1000)
Power and energy is not the same beast. In order to get the energy consumed, you must look at the power consumed over time, and that time is usually an hour.

That is why my script samples the power every 1s and calculates the energy used per minute.
Power meters rarely supplies samples more often that that.

So

var instPower = parseInt(items.getItem("TpLinkFrigorifero_Power").state, 10)/1000

gives you the power consumption in kW, and keeping the script as is kWmin. (add up 60 of those for an hour)
You might consider changing the item names, since when you now do historical data lookup, you will get a mix of Wmin and kWmin.

When you say you want 3 digit float precision I assume you mean in the sitemap? Use %.3f as below.

Text item=kWHhourlyConsumption label="Last hour [%.3f kWh]"
1 Like

i’ve followed what you suggested, to remove items and adding them with new names.
also of course i’ve adapted the rule with new names.

the rule seems to work:

i also added the state description in metadata as “%.3f kWh” so all items are shown with 3 digit and measurement unit both in sitemap and also in items list.

but i see these errors in the log, and i can’t understand them:

2022-01-11 09:56:53.200 [WARN ] [ache.cxf.phase.PhaseInterceptorChain] - Interceptor for {http://internal.id.core.openhab.org/}UUIDResource has thrown exception, unwinding now
org.apache.cxf.interceptor.Fault: Could not send Message.
	at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:67) ~[bundleFile:3.4.5]
	at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) ~[bundleFile:3.4.5]
	at org.apache.cxf.interceptor.OutgoingChainInterceptor.handleMessage(OutgoingChainInterceptor.java:90) ~[bundleFile:3.4.5]
	at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) ~[bundleFile:3.4.5]
	at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121) ~[bundleFile:3.4.5]
	at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:265) ~[bundleFile:3.4.5]
	at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234) ~[bundleFile:3.4.5]
	at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208) ~[bundleFile:3.4.5]
	at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160) ~[bundleFile:3.4.5]
	at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:225) ~[bundleFile:3.4.5]
	at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:298) ~[bundleFile:3.4.5]
	at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doGet(AbstractHTTPServlet.java:222) ~[bundleFile:3.4.5]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:687) ~[bundleFile:3.1.0]
	at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:273) ~[bundleFile:3.4.5]
	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:799) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:550) ~[bundleFile:9.4.43.v20210629]
	at org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.doHandle(HttpServiceServletHandler.java:71) ~[bundleFile:?]
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:602) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1434) ~[bundleFile:9.4.43.v20210629]
	at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.doHandle(HttpServiceContext.java:294) ~[bundleFile:?]
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:501) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1349) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) ~[bundleFile:9.4.43.v20210629]
	at org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:82) ~[bundleFile:?]
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.Server.handle(Server.java:516) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:388) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:633) [bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:380) [bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277) [bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311) [bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105) [bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104) [bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:338) [bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:315) [bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:173) [bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131) [bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:386) [bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883) [bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034) [bundleFile:9.4.43.v20210629]
	at java.lang.Thread.run(Thread.java:829) [?:?]
Caused by: org.eclipse.jetty.io.EofException
	at org.eclipse.jetty.io.ChannelEndPoint.flush(ChannelEndPoint.java:279) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.io.WriteFlusher.flush(WriteFlusher.java:422) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.io.WriteFlusher.write(WriteFlusher.java:277) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.io.AbstractEndPoint.write(AbstractEndPoint.java:381) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.HttpConnection$SendCallback.process(HttpConnection.java:829) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.util.IteratingCallback.processing(IteratingCallback.java:241) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.util.IteratingCallback.iterate(IteratingCallback.java:223) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.HttpConnection.send(HttpConnection.java:550) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.HttpChannel.sendResponse(HttpChannel.java:915) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.HttpChannel.write(HttpChannel.java:987) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.HttpOutput.channelWrite(HttpOutput.java:285) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.HttpOutput.close(HttpOutput.java:638) ~[bundleFile:9.4.43.v20210629]
	at org.apache.cxf.transport.http.AbstractHTTPDestination$WrappedOutputStream.close(AbstractHTTPDestination.java:791) ~[bundleFile:3.4.5]
	at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56) ~[bundleFile:3.4.5]
	at org.apache.cxf.transport.http.AbstractHTTPDestination$BackChannelConduit.close(AbstractHTTPDestination.java:722) ~[bundleFile:3.4.5]
	at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:63) ~[bundleFile:3.4.5]
	... 48 more
Caused by: java.io.IOException: Broken pipe
	at sun.nio.ch.FileDispatcherImpl.writev0(Native Method) ~[?:?]
	at sun.nio.ch.SocketDispatcher.writev(SocketDispatcher.java:51) ~[?:?]
	at sun.nio.ch.IOUtil.write(IOUtil.java:182) ~[?:?]
	at sun.nio.ch.IOUtil.write(IOUtil.java:130) ~[?:?]
	at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:493) ~[?:?]
	at java.nio.channels.SocketChannel.write(SocketChannel.java:507) ~[?:?]
	at org.eclipse.jetty.io.ChannelEndPoint.flush(ChannelEndPoint.java:273) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.io.WriteFlusher.flush(WriteFlusher.java:422) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.io.WriteFlusher.write(WriteFlusher.java:277) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.io.AbstractEndPoint.write(AbstractEndPoint.java:381) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.HttpConnection$SendCallback.process(HttpConnection.java:829) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.util.IteratingCallback.processing(IteratingCallback.java:241) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.util.IteratingCallback.iterate(IteratingCallback.java:223) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.HttpConnection.send(HttpConnection.java:550) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.HttpChannel.sendResponse(HttpChannel.java:915) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.HttpChannel.write(HttpChannel.java:987) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.HttpOutput.channelWrite(HttpOutput.java:285) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.HttpOutput.close(HttpOutput.java:638) ~[bundleFile:9.4.43.v20210629]
	at org.apache.cxf.transport.http.AbstractHTTPDestination$WrappedOutputStream.close(AbstractHTTPDestination.java:791) ~[bundleFile:3.4.5]
	at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56) ~[bundleFile:3.4.5]
	at org.apache.cxf.transport.http.AbstractHTTPDestination$BackChannelConduit.close(AbstractHTTPDestination.java:722) ~[bundleFile:3.4.5]
	at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:63) ~[bundleFile:3.4.5]
	... 48 more
2022-01-11 09:56:53.214 [ERROR] [internal.JSONResponseExceptionMapper] - Unexpected exception occurred while processing REST request.
org.eclipse.jetty.io.EofException: null
	at org.eclipse.jetty.io.ChannelEndPoint.flush(ChannelEndPoint.java:279) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.io.WriteFlusher.flush(WriteFlusher.java:422) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.io.WriteFlusher.write(WriteFlusher.java:277) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.io.AbstractEndPoint.write(AbstractEndPoint.java:381) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.HttpConnection$SendCallback.process(HttpConnection.java:829) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.util.IteratingCallback.processing(IteratingCallback.java:241) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.util.IteratingCallback.iterate(IteratingCallback.java:223) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.HttpConnection.send(HttpConnection.java:550) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.HttpChannel.sendResponse(HttpChannel.java:915) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.HttpChannel.write(HttpChannel.java:987) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.HttpOutput.channelWrite(HttpOutput.java:285) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.HttpOutput.close(HttpOutput.java:638) ~[bundleFile:9.4.43.v20210629]
	at org.apache.cxf.transport.http.AbstractHTTPDestination$WrappedOutputStream.close(AbstractHTTPDestination.java:791) ~[bundleFile:3.4.5]
	at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56) ~[bundleFile:3.4.5]
	at org.apache.cxf.transport.http.AbstractHTTPDestination$BackChannelConduit.close(AbstractHTTPDestination.java:722) ~[bundleFile:3.4.5]
	at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:63) ~[bundleFile:3.4.5]
	at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) ~[bundleFile:3.4.5]
	at org.apache.cxf.interceptor.OutgoingChainInterceptor.handleMessage(OutgoingChainInterceptor.java:90) ~[bundleFile:3.4.5]
	at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) ~[bundleFile:3.4.5]
	at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121) ~[bundleFile:3.4.5]
	at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:265) ~[bundleFile:3.4.5]
	at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234) ~[bundleFile:3.4.5]
	at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208) ~[bundleFile:3.4.5]
	at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160) ~[bundleFile:3.4.5]
	at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:225) ~[bundleFile:3.4.5]
	at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:298) ~[bundleFile:3.4.5]
	at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doGet(AbstractHTTPServlet.java:222) ~[bundleFile:3.4.5]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:687) ~[bundleFile:3.1.0]
	at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:273) ~[bundleFile:3.4.5]
	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:799) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:550) ~[bundleFile:9.4.43.v20210629]
	at org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.doHandle(HttpServiceServletHandler.java:71) ~[bundleFile:?]
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:602) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1434) ~[bundleFile:9.4.43.v20210629]
	at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.doHandle(HttpServiceContext.java:294) ~[bundleFile:?]
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:501) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1349) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) ~[bundleFile:9.4.43.v20210629]
	at org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:82) ~[bundleFile:?]
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.Server.handle(Server.java:516) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:388) ~[bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:633) [bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:380) [bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277) [bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311) [bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105) [bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104) [bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:338) [bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:315) [bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:173) [bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131) [bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:386) [bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883) [bundleFile:9.4.43.v20210629]
	at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034) [bundleFile:9.4.43.v20210629]
	at java.lang.Thread.run(Thread.java:829) [?:?]
Caused by: java.io.IOException: Broken pipe
	at sun.nio.ch.FileDispatcherImpl.writev0(Native Method) ~[?:?]
	at sun.nio.ch.SocketDispatcher.writev(SocketDispatcher.java:51) ~[?:?]
	at sun.nio.ch.IOUtil.write(IOUtil.java:182) ~[?:?]
	at sun.nio.ch.IOUtil.write(IOUtil.java:130) ~[?:?]
	at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:493) ~[?:?]
	at java.nio.channels.SocketChannel.write(SocketChannel.java:507) ~[?:?]
	at org.eclipse.jetty.io.ChannelEndPoint.flush(ChannelEndPoint.java:273) ~[bundleFile:9.4.43.v20210629]
	... 63 more

here there is the rule adapted:

var today = new Date
var instPower = parseInt(items.getItem("TpLinkFrigorifero_Power").state, 10) /1000
var kwMinute
var hasTickedMinutes

if (isNaN(kwMinute)) {
  console.log("Rule starting");
  kwMinute = 0;
  kWhour = 0;
  hasTickedMinutes = false
  }

  function isMinuteTick () {
    return (today.getSeconds() == 0)
  }

 function isHourTick () {
   return ((today.getMinutes() == 0) && (today.getSeconds() == 4)) // delay a bit so that the last persisted value becomes part of the sum
  }
    if (isMinuteTick()) {
      if (!hasTickedMinutes) { // sample a full interval
        hasTickedMinutes = true
      } else {
        kwMinute /= 60    
        //console.log("kWmin= " + kwMinute);
        items.getItem("Frigorifero_kWhMinuto").postUpdate(kwMinute)
      }
        kwMinute = 0
    } else {
        kwMinute += instPower
    }


    if (isHourTick()) {  
        var kwPeriod = items.getItem("Frigorifero_kWhMinuto").history.sumSince(new Date(new Date().setHours(new Date().getHours()-1))) / 60
            
        console.log("kWh = " + kwPeriod);
        items.getItem("Frigorifero_kWhOra").postUpdate(kwPeriod)
        
        var now = new Date();
        var tday = new Date(now.getFullYear(), now.getMonth(), now.getDate());
        var lastMonday = new Date(tday.setDate(tday.getDate()-(today.getDay() + 6) % 7));

        var dayStimato = items.getItem("Frigorifero_kWhMinuto").history.sumSince(new Date(new Date().setHours(0, 0, 0))) / 60    // from midnight
        var weekStimato = items.getItem("Frigorifero_kWhMinuto").history.sumSince(lastMonday) / 60                               // from midnight monday
        var monthStimato = items.getItem("Frigorifero_kWhMinuto").history.sumSince(new Date(new Date().setDate(1))) / 60         // from the 1. of the month
        var yearStimato = items.getItem("Frigorifero_kWhMinuto").history.sumSince(new Date(new Date().setMonth(0, 1))) / 60      // from 1. january

        items.getItem("Frigorifero_kWhGiornoStimato").postUpdate(dayStimato)
        items.getItem("Frigorifero_kWhSettimanaStimato").postUpdate(weekStimato)
        items.getItem("Frigorifero_kWhMeseStimato").postUpdate(monthStimato)
        items.getItem("Frigorifero_kWhAnnoStimato").postUpdate(yearStimato)
    }

anyway, thanks a lot for your script, is really useful and i think i will use it soooo much!

You are welcome.
If you have saved the script with errors, you might have been hit with this:

Check your top/free.
A reboot fixed this for me.

1 Like

Fine tuning: missed a sample, removed check for full interval added support for missed samples.

var today = new Date
var instPower = parseInt(items.getItem("GTV7PowerConsumption").state, 10)
var kwMinute
var samples

if (isNaN(kwMinute)) {
  console.log("Rule starting");
  kwMinute = 0;
  samples = 0;
}

function addSample() {
    kwMinute += instPower
    samples += 1  
}

function resetSamples() {
    kwMinute = 0
    samples = 0
}

if (isMinuteTick()) {
    addSample()
    kwMinute /= samples    
    console.log("kWmin= " + kwMinute + " (" + samples + " samples)");
    items.getItem("kWHminuteConsumption").postUpdate(kwMinute)
    var kwPeriod = items.getItem("kWHminuteConsumption").history.sumSince(new Date(new Date().setHours(new Date().getHours()-1)))/samples/1000
    items.getItem("kWHhourlyConsumption").postUpdate(kwPeriod)
    resetSamples()
} else {
    addSample()
}

Looks like you have done the exact thing I have set out to do, so very grateful for all the things you have shared here.

I’m hoping to bother you on a sligthly off topic issue. Since you’re in Norway you are probably connecting to the HAN port of your meter(?). Can I ask what HW your using? I optimistically went with the EVA meter reader, but can’t really connect it to my conbee.

Welcome to the forum!
I was an early adopter and have had this up and running since it became available and hence had to do the job myself. (but just recently have I started trying to use the instantaneous power consumption to something useful :slight_smile:

I’m using this: METERBUS : PW001G Mbus Slave Level Converter which I doctored to give me TTL level standard serial signal which I connected to an Arduino with a Eth shield. Decoded that data myself, and have a process on my machine listening for new values. Only changes are sent, and re-posted to OH3 via the REST API.

Are you trying to get the EVA meter into deconz?

can you post the full code? seems there are errors about isMinuteTick and isHourTick…

OK, but remember, work in progress cost wise … but runs without errors:

var today = new Date
var instPower = parseInt(items.getItem("GTV7PowerConsumption").state, 10)
var kwMinute
var hourlyPrice 
var samples


if (isNaN(kwMinute)) {
  //today = new Date
  console.log("Rule starting");
  kwMinute = 0;
  samples = 0;
  hourlyPrice = 0.0
}

function isMinuteTick () {
  return (today.getSeconds() == 0)
}

function isHourTick () {
  return ((today.getMinutes() == 0) && (today.getSeconds() == 4)) // delay a bit so that the last persisted value becomes part of the sum
}

function isDayTick () {
  return ((today.getHours() == 0) && (today.getMinutes() == 0) && (today.getSeconds() == 4)) // delay a bit so that the last persisted value becomes part of the sum
}

function isWeekTick () {
  return ((today.getDay() == 1) /* monday */ && isDayTick())
}

function isMonthTick () {
  return ((today.getDate() == 1) && isDayTick())
}

function isYearTick () {
  return ((today.getMonth() == 0) && isMonthTick()) // month 0 is January
}

function calcHourlyConsumptionCost(hourlyConsumption) {  
  // fetch NordPool hourly price for this hour interval
  switch (today.getHours()) {
    case 0:
      hourlyPrice = parseFloat(items.getItem("toDay24_01").state)
      break
    case 1:
      hourlyPrice = parseFloat(items.getItem("toDay01_02").state)
      break
    case 2:
      hourlyPrice = parseFloat(items.getItem("toDay02_03").state)
      break
    case 3:
      hourlyPrice = parseFloat(items.getItem("toDay03_04").state)
      break
    case 4:
      hourlyPrice = parseFloat(items.getItem("toDay04_05").state)
      break
    case 5:
      hourlyPrice = parseFloat(items.getItem("toDay05_06").state)
      break
    case 6:
      hourlyPrice = parseFloat(items.getItem("toDay06_07").state)
      break
    case 7:
      hourlyPrice = parseFloat(items.getItem("toDay07_08").state)
      break
    case 8:
      hourlyPrice = parseFloat(items.getItem("toDay08_09").state)
      break
    case 9:
      hourlyPrice = parseFloat(items.getItem("toDay09_10").state)
      break
    case 10:
      hourlyPrice = parseFloat(items.getItem("toDay10_11").state)
      break
    case 11:
      hourlyPrice = parseFloat(items.getItem("toDay11_12").state)
      break
    case 12:
      hourlyPrice = parseFloat(items.getItem("toDay12_13").state)
      break
    case 13:
      hourlyPrice = parseFloat(items.getItem("toDay13_14").state)
      break
    case 14:
      hourlyPrice = parseFloat(items.getItem("toDay14_15").state)
      break
    case 15:
      hourlyPrice = parseFloat(items.getItem("toDay15_16").state)
      break
    case 16:
      hourlyPrice = parseFloat(items.getItem("toDay16_17").state)
      break
    case 17:
      hourlyPrice = parseFloat(items.getItem("toDay17_18").state)
      break
    case 18:
      hourlyPrice = parseFloat(items.getItem("toDay18_19").state)
      break
    case 19:
      hourlyPrice = parseFloat(items.getItem("toDay19_20").state)
      break
    case 20:
      hourlyPrice = parseFloat(items.getItem("toDay20_21").state)
      break
    case 21:
      hourlyPrice = parseFloat(items.getItem("toDay21_22").state)
      break
    case 22:
      hourlyPrice = parseFloat(items.getItem("toDay22_23").state)
      break
    case 23:
      hourlyPrice = parseFloat(items.getItem("toDay23_24").state)
      break
    default:
      hourlyPrice = 0.0
      break      
  }
  console.log("hourlyPrice=(NOK) " + (hourlyPrice*hourlyConsumption)/1000)
}

function addSample() {
    kwMinute += instPower
    samples += 1  
}

function resetSamples() {
    kwMinute = 0
    samples = 0
}

if (isMinuteTick()) {
    addSample()
    kwMinute /= samples    
    console.log("kWmin= " + kwMinute + " (" + samples + " samples)");
    items.getItem("kWHminuteConsumption").postUpdate(kwMinute)
    var kwPeriod = items.getItem("kWHminuteConsumption").history.sumSince(new Date(new Date().setHours(new Date().getHours()-1)))/samples/1000
    items.getItem("kWHhourlyConsumption").postUpdate(kwPeriod)
    resetSamples()
} else {
    addSample()
}

if (isHourTick()) {  
        
    console.log("kWh= " + kwPeriod);
    calcHourlyConsumptionCost(kwPeriod)
    
    var now = new Date();
    var tday = new Date(now.getFullYear(), now.getMonth(), now.getDate());
    var lastMonday = new Date(tday.setDate(tday.getDate()-(today.getDay() + 6) % 7));

    var daySoFar = items.getItem("kWHminuteConsumption").history.sumSince(new Date(new Date().setHours(0, 0, 0)))/60/1000     // from midnight
    var weekSoFar = items.getItem("kWHminuteConsumption").history.sumSince(lastMonday)/60/1000                                // from midnight monday
    var monthSoFar = items.getItem("kWHminuteConsumption").history.sumSince(new Date(new Date().setDate(1)))/60/1000    // from the 1. of the month
    var yearSoFar = items.getItem("kWHminuteConsumption").history.sumSince(new Date(new Date().setMonth(0, 1)))/60/1000 // from 1. january

    items.getItem("kWHdaylyConsumptionSoFar").postUpdate(daySoFar)
    items.getItem("kWHweeklyConsumptionSoFar").postUpdate(weekSoFar)
    items.getItem("kWHmonthlyConsumptionSoFar").postUpdate(monthSoFar)
    items.getItem("kWHyearlyConsumptionSoFar").postUpdate(yearSoFar)

//if (isDayTick()) {
    var kwPeriod = items.getItem("kWHminuteConsumption").history.sumSince(new Date(new Date().setDate(new Date().getDate()-1)))/60/1000    
    //var kwPeriod = items.getItem("kWHdaylyConsumptionSoFar").state
    console.log("kwhday=" + kwPeriod)
    items.getItem("kWHdaylyConsumption").postUpdate(kwPeriod)
//}

//if (isWeekTick()) {
    var kwPeriod = items.getItem("kWHminuteConsumption").history.sumSince(new Date(new Date().setDate(new Date().getDate()-7)))/60/1000
    console.log("kwhweek=" + kwPeriod)
    items.getItem("kWHweeklyConsumption").postUpdate(kwPeriod)
//}

//if (isMonthTick()) {
    var kwPeriod = items.getItem("kWHminuteConsumption").history.sumSince(new Date(new Date().setMonth(new Date().getMonth()-1)))/60/1000
    console.log("kwhmonth=" + kwPeriod)
    items.getItem("kWHmonthlyConsumption").postUpdate(kwPeriod)
//}

//if (isYearTick()) {
    var kwPeriod = items.getItem("kWHminuteConsumption").history.sumSince(new Date(new Date().setMonth(new Date().getMonth()-12)))/60/1000
    console.log("kwhyear=" + kwPeriod)
    items.getItem("kWHyearlyConsumption").postUpdate(kwPeriod)
//}
}

Ok, so your solution is probably quite a bit to advanced for me.

But yes - I’m trying to connect the EVA meter reader to deconz. It shows up in decons as an unknown device, but is of course not available in OH.

So the pessimist in me is asking for tips for a combination of meter reader (in the Norwegian market) and a zigbee gw that will work.

The optimist is currently looking at the documentation for device description files in deconz to see if it can be possible to get this to work.

Try asking for help on the deconz github issue forum. They are very helpful.

Honk if you need a Nordpool price scraper. :relaxed: