Need help Number conversion/casting

Hello again…
I face the next problem…
In a rule there should be a calculation:

Number Licht_Carport_Heute                "Licht Osten diese Nacht Millisekunden"

global Variable:

var long Licht_Carport_start
    if (Licht_Out_Eingang.state == ON) {                // Licht Carport ist an
        val long nowMsec = now.millis
        if(Licht_Carport_start==null) Licht_Carport_start=now.millis
        logInfo("On-Time", "Carport 1 " + Licht_Carport_start)
        sendCommand(Licht_Carport_Heute,( (Licht_Carport_Heute.state as Number).longValue + (nowMsec - Licht_Carport_start)).longValue)
        logInfo("On-Time", "Carport 2")

Log:
[INFO ] [lipse.smarthome.model.script.On-Time] - Carport 1 1481646887672
[INFO ] [lipse.smarthome.model.script.On-Time] - Carport 1a 1481646887672
[ERROR] [ntime.internal.engine.ExecuteRuleJob] - Error during the execution of rule Licht Carport OnTime Display update: java.lang.Number

So it’s working till the calculation. Designer shows no error. It must be something with the Number conversion. Can anybody tell me, how to do it right?

What are you trying to accomplish with your items and rules?

In an other rule I store in Licht_Carport_start the now.millis, and in the above I calculate the time between it. It’s for the runtime of lights, pumps and so on.
The Licht_Carport_Heute contains the millis since last switch on of the corresponding item.
The logInfos are only for debugging to see how far the rule runs.

The rule was done with Licht_Carport_Heute as a global variable, but Rich told me to change it and use it as a Number -Item instead. This sound very nice as it can be persisted, but I now have the problem with the casting/conversion.

Please check your parenthesis:
(nowMsec - Licht_Carport_start)).longValue

That isn’t quite what I said but it is a good approach.

What I said was to just store the Joda DateTime instead of the millis as a primitive long so you would initialize your global var with null to avoid the apparent problem with now not being available when global vars and vals are first initialized.

There is a difference between java.lang.Number, which is what the Rule’s DSL uses for all numerical values and the results of calculations unless explicitly told otherwise) and NumberItem which is the type of object that a Number defined in .items is.

What I actually suggested is something along the lines of:

var lightOnStart = null

rule "light turned on"
when
    Item MyLight changed to ON
then
    lightOnStart = now
end

rule "light turned off"
when
    Item MyLight changed to OFF
then
    LightRuntime.postUpdate(0)
end

rule "Periodically update LightRuntime"
when
    Time cron "0 * * * * ?"
then
    if(MyLight.state == ON) {
        LightRuntime.postUpdate(now.millis - lightOnStart.millis)
    }
end

No casting. No conversion. There should be no errors. I’m assuming your code fragment is in a rule that runs periodically so you can see your Licht_Carport_Heute update on the sitemap while the light is ON.

Well, thanks! I think that’s what I want to have. Will try and try to understand.
And also thanks to Ulrich, I checked the ) but I think they are O.K.

I think, I understand what you try to do: Store the DateTime in the global Variable, and the millis (interger) in the Number-Item, right?
But here:

the Designer says: The method or field millis is undefined for the type Object
The rule crashes here. (I did it with my Designators, but I’m pretty sure it’s like yours)

Also, in LightRuntime would only be the time (in millis) for one On-Period, but I need them for a whole day. So there must be a calculation with the Number-Item LightRuntime. eg:
LightRuntime = LightRuntime + (now.millis - lightOnStart.millis)
And then, there is the problem with the conversion again.
Do you see any solution here?

It probably needs a hint as to what the var’s type is.

var DateTime lightOnStart = null

Forget the milliseconds. We are storing the DateTime object and using the milliseconds only for the calculation.

LightRuntime is an Item, not a variable. You must either postUpdate or sendCommand like my code does.

There was nothing in your original posts or code to indicate that you are trying to calculate the amount of time it has been on for the whole day.

Your easiest solution is to store the Switch Item in persistence once a minute and simply call

LightRuntime.postUpdate(MyLight.sumSince(now.withTimeAtStartOfDay))

That will get the number of minutes the light has been on since midnight. you could use now.minusDays(1) if you really want the past 24 hours.

If you need higher fidelity (i.e. seconds or milliseconds) or for some reason you can’t use persistence for this it gets really really complicated.

I recommend reviewing the following postings:

I have it working now. I will let it run over night and post the code.
Thanks for your help!

yes, and it needs the import:

import org.joda.time.DateTime

Because I moved the code I was working on to an extra rules file, it was missing :frowning:

Yes, I know, this was meant as a “description” what has to be calulatet.

You’re right. I thought it’s clear because of the code. It’s the difference between what you think and what you write :wink:

One more question:
Your suggestion[quote=“rlkoshak, post:8, topic:18165”]
LightRuntime.postUpdate(MyLight.sumSince(now.withTimeAtStartOfDay))
[/quote]
does not work here.
I put it in a rule which triggers every minute:

Balkon_Zeit.postUpdate(Licht_Balkon_Decke.sumSince(now.withTimeAtStartOfDay))

Where Licht_Balkon_Decke is the Switch and Balkon_Zeit is the Number-Item.
Designer says:
The method sumSince(DateTime) is undefined for the type SwitchItem
The rule doesn’t crash, but the state of Balkon_Zeit stays on 0.
The Switch-Item Licht_Balkon_Decke contains only ON and OFF, so is there anything to add over time?
I think this might work on a Number-Item or any Item containing Numbers, but on a switch-Item?

Switch items are usually stored in the database as 1 for ON and 0 for OFF. So if you store the state every minute and add up all the 1’s you will get the number of minutes ON

I might have the syntax wrong on sumSince. That’s the danger when replying from memory and typing on a phone.

I found a post from 02/2016:
https://knx-user-forum.de/forum/supportforen/openhab/909876-sumsince-führt-immer-zu-einer-fehlermeldung

They state, that sumSince is not working, but others like averageSince do work. I checked, it’s working.
So, I leave by now and go on with the working stuff…
Thanks Rich!

O.K., I think it’s working now. I made a Dummy-rule for measuring on-times (runtimes) of switches over a day. It can be used by using function “replace all” of the Designer.

/*
these rules count the time an Item is switch on over a period of one day.
use: Replace all "Dummy" by own, meaningful keywords
Item-file must contain:
Number Dummy_today_hours
Number Dummy_yesterday_hours
Number Dummy_millis

rrd4j.persist must contain:
Dummy_today_hours        : strategy = everyUpdate, everyMinute, everyChange, restoreOnStartup
Dummy_yesterday_hours    : strategy = everyUpdate, everyMinute, everyChange, restoreOnStartup
Dummy_millis            : strategy = everyUpdate, everyMinute, everyChange, restoreOnStartup
*/
import org.joda.time.DateTime
/****************   global Variables   ********************/
var DateTime Dummy_start = null

/********** Day/midday Change **********/
rule "Dummy Day change"
// The Value of "today" is stored in a Number to have it availeble as "yesterday"
// can be done at midnight (Valves, pumps, etc) or midday (lights, etc)
when
    Time cron "0 0 0 1/1 * ? *"            // midnight
//    Time cron "0 0 12 1/1 * ? *"            // midday
    then
    if (YourSwitchItem.state == ON) {
        if(Dummy_start==null) Dummy_start = now
        Dummy_millis.postUpdate (now.millis - Dummy_start.millis + (Dummy_millis.state as Number).longValue)
        Dummy_today_hours.postUpdate ( (Dummy_millis.state as Number / 3600000.0).doubleValue)
        Dummy_start = now
    }
    Dummy_yesterday_hours.postUpdate (Dummy_today_hours.state)
    Dummy_today_hours.postUpdate (0)
    Dummy_millis.postUpdate (0)
end

rule "Dummy start-stop"
when
    Item YourSwitchItem changed
then
    if (YourSwitchItem.state == ON) {
        Dummy_start = now
    }
    else {
        if(Dummy_start == null) Dummy_start = now
        Dummy_millis.postUpdate (now.millis - Dummy_start.millis + (Dummy_millis.state as Number).longValue)
        Dummy_today_hours.postUpdate ( (Dummy_millis.state as Number / 3600000.0).doubleValue)
    }
end

rule "Dummy OnTime Display update"
when
    Time cron "0 0/1 * 1/1 * ? *"
then
    if (YourSwitchItem.state == ON) {
        if(Dummy_start==null) Dummy_start = now
        Dummy_millis.postUpdate (now.millis - Dummy_start.millis + (Dummy_millis.state as Number).longValue)
        Dummy_today_hours.postUpdate ( (Dummy_millis.state as Number / 3600000.0).doubleValue)
        Dummy_start = now
    }
end
rule "Dummy Check if files exist"
when
        System started
then
    createTimer(now.plusMinutes(3)) [|
        if (Dummy_millis.state == NULL) Dummy_millis.postUpdate (0)
    ]
end


Thanks again for helping me.