Dimmer rule between scene light [SOLVED]

Hi everybody,
I’m stuck with a rule.
I use openhabian 2.5.3.1
with ikea tradfri binding.

to control my lights i use multiple rules scenes schemas: diner scene, evening scene and so on, such as:

rule "Ambiance soir"
when
    Item Ambiance_du_Soir received command ON
then
        Niche_Droite.sendCommand(30)
        Niche_Gauche.sendCommand(30)
        Niche_Milieu.sendCommand(60)
        Lumieres_TV.sendCommand(60)
        Plafond_Entree_2.sendCommand(0)
        Plafond_Entree_3.sendCommand(40)
        Plafond_Entree_4.sendCommand(0)
        Plafond_Entree_1.sendCommand(40)
        Plafond_Salle_A_Manger_1.sendCommand(30)
        Plafond_Salle_A_Manger_2.sendCommand(40)
        Plafond_Salle_A_Manger_3.sendCommand(30)
        ArcheDroite.sendCommand(20)
        ArcheGauche.sendCommand(20)
        ArcheMilieu.sendCommand(0)
        Lumieres_Cuisine.sendCommand(80)
        Lampe_Ambiance_Entree.sendCommand(50)
        Lampe_Ambiance_Entree_ColorTemperature.sendCommand(40)
        Lustre_1.sendCommand(15)
        LustreColorTemperature.sendCommand(0)
        LustreColor.sendCommand("39,85,84")
        
        Lumieres.postUpdate(ON)
        Ambiance_Apero.postUpdate(OFF)
        Ambiance_Diner.postUpdate(OFF)
        Ambiance_Matin.postUpdate(OFF)
        Ambiance_Film_Tele.postUpdate(OFF)
        Ambiance_Tele.postUpdate(OFF)
        Ambiance_Pleine_lumiere.postUpdate(OFF)
        Ambiance_du_Soir.postUpdate(ON)
        Ambiance_cosy.postUpdate(OFF)
        Ambiance_VP.postUpdate(OFF)
        Ambiance_feutree.postUpdate(OFF)
        Ambiance_pluie.postUpdate(OFF)
        //Bureau.postUpdate(OFF)
logInfo("Ambiance", "Ambiance soir")

end
rule "Ambiance_Diner"
when
    Item Ambiance_Diner received command ON
then
        Niche_Droite.sendCommand(50)
        Niche_Gauche.sendCommand(50)
        Niche_Milieu.sendCommand(50)
        Lumieres_TV.sendCommand(40)
        Plafond_Entree_2.sendCommand(60)
        Plafond_Entree_3.sendCommand(60)
        Plafond_Entree_4.sendCommand(0)
        Plafond_Entree_1.sendCommand(0)
        Plafond_Salle_A_Manger_1.sendCommand(100)
        Plafond_Salle_A_Manger_2.sendCommand(100)
        Plafond_Salle_A_Manger_3.sendCommand(100)
        ArcheDroite.sendCommand(80)
        ArcheGauche.sendCommand(80)
        ArcheMilieu.sendCommand(50)
        Lumieres_Cuisine.sendCommand(100)
        Lampe_Ambiance_Entree.sendCommand(80)
        Lampe_Ambiance_Entree_ColorTemperature.sendCommand(20)
        Lustre_1.sendCommand(80)
        LustreColorTemperature.sendCommand(90)
        
        Lumieres.postUpdate(ON)
        Ambiance_Apero.postUpdate(OFF)
        Ambiance_Diner.postUpdate(ON)
        Ambiance_Matin.postUpdate(OFF)
        Ambiance_Film_Tele.postUpdate(OFF)
        Ambiance_Tele.postUpdate(OFF)
        Ambiance_Pleine_lumiere.postUpdate(OFF)
        Ambiance_du_Soir.postUpdate(OFF)
        Ambiance_cosy.postUpdate(OFF)
        Ambiance_VP.postUpdate(OFF)
        Ambiance_feutree.postUpdate(OFF)
        Ambiance_pluie.postUpdate(OFF)
        //Bureau.postUpdate(OFF)
logInfo("Ambiance", "Ambiance diner")

end

any of them are triggered trought prescence detection or time cron or timer, i know that i can simplify my rules (using design patern) but this method is the one that i can understand.

i want to integrate a slow dimmer between each scene for example slowly dimme light from evening scene to diner scene, to be more precise, dimme light from 30% to 60% during 45 min for example.

i’m testing this kind of rule:

var Timer Timer0 = null

rule "morning alarm"
    when
        Time cron "0 32 10 1/1 * ? *"
    then
        logInfo("morningAlarm", "Wakeup Started")
        if(G_Presence.state == ON && Timer0 === null) { 
            Timer0 = createTimer(now.plusSeconds(1)) [ |                               
                if ((Niche_Milieu.state as Number) < 100) {                             
                    Niche_Milieu.sendCommand((Niche_Milieu.state as Number) + 10)       10
                    Timer0.reschedule(now.plusMinutes(1))                                                         
                }
                else
                    Timer0 = null                                                      
            ]
        }
        else if(Niche_Milieu.state==ON) {
            Niche_Milieu.sendCommand(OFF)                                             
            Timer0.cancel                                                              
            Timer0 = null                                                               
            logInfo("morningAlarm", "Wakeup Ended")
        }
end

i found a rule example that can correspond to my schema, but i’m stuck with departure value to a specific one.
Can you please put me on the right direction

Not sure what you mean by this?

i mean by using this method :

rule "morning alarm"
    when
        Time cron "0 32 10 1/1 * ? *"
    then
        logInfo("morningAlarm", "Wakeup Started")
        if(G_Presence.state == ON && Timer0 === null) { 
            Timer0 = createTimer(now.plusSeconds(1)) [ |                               
                if ((Niche_Milieu.state as Number) < 100) {                             
                    Niche_Milieu.sendCommand((Niche_Milieu.state as Number) + 10)       10
                    Timer0.reschedule(now.plusMinutes(1))                                                         
                }
                else
                    Timer0 = null                                                      
            ]
        }
        else if(Niche_Milieu.state==ON) {
            Niche_Milieu.sendCommand(OFF)                                             
            Timer0.cancel                                                              
            Timer0 = null                                                               
            logInfo("morningAlarm", "Wakeup Ended")
        }
end

i start from the 0% level of the light (tunr off) to 100% level, i want to start from 60% to 90%

Just add a command to send the value of 60 at the start of the rule and change the number values in the rule as needed.

ok for the departure value but how to stop it to a specific %level not 100%

Change this to 90

So, following your suggestions, i’ ve made my rule, looking like this

var Timer Timer0 = null

rule "evening dimmer"
    when
        Time cron "0 51 22 1/1 * ? *"
    then
        logInfo("Dimmer.rules", "Evening dimmer")
        if(G_Presence.state == ON && Timer0 === null) { 
            Timer0 = createTimer(now.plusSeconds(1)) [ |                                // Create a Timer
                if (((Niche_Gauche.state as Number) < 50) &&
                    ((Niche_Milieu.state as Number) > 50) &&
                    ((Niche_Droite.state as Number) < 50) &&
                    ((Lumieres_TV.state as Number) > 40) && 
                    ((Plafond_Entree_2.state as Number) < 60) &&
                    ((Plafond_Entree_3.state as Number) < 60) &&
                    ((Plafond_Entree_1.state as Number) > 0) &&
                    ((Plafond_Salle_A_Manger_1.state as Number) < 100) &&
                    ((Plafond_Salle_A_Manger_2.state as Number) < 100) &&
                    ((Plafond_Salle_A_Manger_3.state as Number) < 100) &&
                    ((ArcheDroite.state as Number) < 80) &&
                    ((ArcheGauche.state as Number) < 80) &&
                    ((ArcheMilieu.state as Number) < 50) &&
                    ((Lumieres_Cuisine.state as Number) < 100) &&
                    ((Lampe_Ambiance_Entree.state as Number) < 80) &&
                    ((Lampe_Ambiance_Entree_ColorTemperature.state as Number) > 20) &&
                    ((Lustre_1.state as Number) < 80) &&
                    ((LustreColorTemperature.state as Number) < 90) &&
                    Ambiance_du_Soir.state == ON ) {                             // already reached highest Level?

                    Niche_Gauche.sendCommand((Niche_Gauche.state as Number) + 5)       // Increase Level by 10
                    Niche_Milieu.sendCommand((Niche_Milieu.state as Number) + 5)
                    Niche_Droite.sendCommand((Niche_Droite.state as Number) + 5)
                    Lumieres_TV.sendCommand((Lumieres_TV.state as Number) - 5)
                    Plafond_Entree_2.sendCommand((Plafond_Entree_2.state as Number) + 5)
                    Plafond_Entree_3.sendCommand((Plafond_Entree_3.state as Number) + 1)
                    Plafond_Entree_1.sendCommand((Plafond_Entree_1.state as Number) - 5)
                    Plafond_Salle_A_Manger_1.sendCommand((Plafond_Salle_A_Manger_1.state as Number) + 5)
                    Plafond_Salle_A_Manger_2.sendCommand((Plafond_Salle_A_Manger_2.state as Number) + 2)
                    Plafond_Salle_A_Manger_3.sendCommand((Plafond_Salle_A_Manger_3.state as Number) + 5)
                    ArcheDroite.sendCommand((ArcheDroite.state as Number) + 5)
                    ArcheGauche.sendCommand((ArcheGauche.state as Number) + 5)
                    ArcheMilieu.sendCommand((ArcheMilieu.state as Number) + 1)
                    Lumieres_Cuisine.sendCommand((Lumieres_Cuisine.state as Number) + 1)
                    Lampe_Ambiance_Entree.sendCommand((Lampe_Ambiance_Entree.state as Number) + 1)
                    Lampe_Ambiance_Entree_ColorTemperature.sendCommand((Lampe_Ambiance_Entree_ColorTemperature.state as Number) + 5)
                    Lustre_1.sendCommand((Lustre_1.state as Number) + 5)
                    LustreColorTemperature.sendCommand((LustreColorTemperature.state as Number) + 5)

                    Timer0.reschedule(now.plusMinutes(1))                               // Reschedule Timer                             
                }
                else
                    Timer0 = null                                                       // reinitialize Timer
            ]
        }
        /*else if(Niche_Milieu.state==ON) {
            Niche_Milieu.sendCommand(OFF)                                               // Switch off
            Timer0.cancel                                                               // Cancel Timer if running
            Timer0 = null                                                               // reinitialize Timer 
            logInfo("morningAlarm", "Wakeup Ended")
        }
*/


end

The switch between the two scenes works but stop as soon as one of the light value is reached
in that case the first reached value is the lumieres TV (from 60% to 40% ) prevent other to continue their way to reached their own value

So if I got it right you want to fade between two complex scenes. You will need do fade per item individually, but of course you can do it in one timer. you will need to save some information for correct calculation, and this is per item. So maybe it would be wise to do a persistence for all of these items (everyChange strategy) and only save the timestamp when fading starts. Now it’s possible to get the start value via persistence (Item.historicState(timestamp).state). The timer could be started once per Second, and if the fade should last a minute, all you have to do is to calculate the new level by startlevel + (endlevel-startlevel)/60 * fade step, where fade step is the number of Seconds past start of fade. e.g.

var DateTime dtFadeStart = null
var Timer tFade = null
var Number nCount = 0

rule "fade to scene 1"
when
    // some trigger
then
    if(dtFadeStart === null && tFade === null) {
        nCount = 0
        dtFadeStart = now
        tFade = createTimer(now.plusMillis(10), [ |
            nCount = nCount + 1
            if(nCount < 60) {
            // new Level for Light shall be 55
                Light.sendCommand((Light.historicState(dtFadeStart).state as Number) + (55 - (Light.historicState(dtFadeStart).state as Number)) / 60 * nCount)
            // new Level for Light2 shall be 25
                Light2.sendCommand((Light2.historicState(dtFadeStart).state as Number) + (25 - (Light2.historicState(dtFadeStart).state as Number)) / 60 * nCount)
                tFade.reschedule(now.plusSeconds(1))
            } else {
                dtFadeStart = null
                tFade = null
            }
        ])
    }
end

I did not test this, so the code may have issues :slight_smile: but I’m sure you get the idea.

@Udo_Hartmann

thanks you, for all these explainations.
So , as you advise, i put all my items in the rrd4j persistence with the everychange strategie.
i tried to manipulate your rule with my own item

var Number nCount = 0

rule "fade to scene 1"
when
    Item Boutton received command ON
then
    if(dtFadeStart === null && tFade === null) {
        nCount = 0
        dtFadeStart = now
        tFade = createTimer(now.plusMillis(10), [ |
            nCount = nCount + 1
            if(nCount < 60) {
            // new Level for Light shall be 55
                Niche_Milieu.sendCommand((Niche_Milieu.historicState(dtFadeStart).state as Number) + (100 - (Niche_Milieu.historicState(dtFadeStart).state as Number)) / 60 * nCount)
            // new Level for Light2 shall be 25
                Niche_Gauche.sendCommand((Niche_Gauche.historicState(dtFadeStart).state as Number) + (25 - (Niche_Gauche.historicState(dtFadeStart).state as Number)) / 60 * nCount)
                tFade.reschedule(now.plusSeconds(1))
            } else {
                dtFadeStart = null
                tFade = null
            }
        ])
        logInfo("Transitions.rules", "fade to scene 1")
    }
end 

, but nothing happens, and this error appears

Rule 'fade to scene 1': The name 'dtFadeStart' cannot be resolved to an item or type; line 7, column 8, length 11

, i’m not confortable with var value yet, and i think i missed something in your formula.

var DateTime dtFadeStart = null
var Timer tFade = null
var Number nCount = 0

[quote="yippicai, post:9, topic:96878"]
i’m not confortable with var value yet, and i think i missed something in your formula.
[/quote]

Just make sure you have all the var’s listed at the top of your rule as Udo_Hartmann posted and the rule should work.

My bad i forgot var value, thx for your pointing.
i’ve resolved that and still error

2020-04-19 16:46:51.170 [INFO ] [thome.model.script.Transitions.rules] - fade to scene 1

2020-04-19 16:46:51.359 [INFO ] [el.core.internal.ModelRepositoryImpl] - Refreshing model 'transition.rules'
2020-04-19 16:47:01.147 [ERROR] [org.quartz.core.JobRunShell         ] - Job DEFAULT.Timer 4 2020-04-19T16:47:01.145+02:00: Proxy for org.eclipse.xtext.xbase.lib.Procedures$Procedure0: [ | {
  <null>.nCount = <XBinaryOperationImplCustom>
  org.eclipse.xtext.xbase.impl.XIfExpressionImpl@10c21d5 (conditionalExpression: false)
} ] threw an unhandled Exception: 
java.lang.NullPointerException: null
	at org.eclipse.smarthome.model.script.engine.ScriptError.<init>(ScriptError.java:65) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.invokeFeature(ScriptInterpreter.java:140) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:991) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:954) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:235) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:215) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluateArgumentExpressions(XbaseInterpreter.java:1205) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._invokeFeature(XbaseInterpreter.java:1135) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.invokeFeature(XbaseInterpreter.java:1081) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.invokeFeature(ScriptInterpreter.java:151) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:991) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:237) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:215) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:1301) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:227) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:215) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:458) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:239) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:215) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluate(XbaseInterpreter.java:201) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.ClosureInvocationHandler.doInvoke(ClosureInvocationHandler.java:46) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.AbstractClosureInvocationHandler.invoke(AbstractClosureInvocationHandler.java:29) ~[?:?]
	at com.sun.proxy.$Proxy333.apply(Unknown Source) ~[?:?]
	at org.eclipse.smarthome.model.script.internal.actions.TimerExecutionJob.execute(TimerExecutionJob.java:48) ~[?:?]
	at org.quartz.core.JobRunShell.run(JobRunShell.java:202) [bundleFile:?]
	at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) [bundleFile:?]
2020-04-19 16:47:01.178 [ERROR] [org.quartz.core.ErrorLogger         ] - Job (DEFAULT.Timer 4 2020-04-19T16:47:01.145+02:00: Proxy for org.eclipse.xtext.xbase.lib.Procedures$Procedure0: [ | {
  <null>.nCount = <XBinaryOperationImplCustom>
  org.eclipse.xtext.xbase.impl.XIfExpressionImpl@10c21d5 (conditionalExpression: false)
} ] threw an exception.
org.quartz.SchedulerException: Job threw an unhandled exception.
	at org.quartz.core.JobRunShell.run(JobRunShell.java:213) [bundleFile:?]
	at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) [bundleFile:?]
Caused by: java.lang.NullPointerException
	at org.eclipse.smarthome.model.script.engine.ScriptError.<init>(ScriptError.java:65) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.invokeFeature(ScriptInterpreter.java:140) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:991) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:954) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:235) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:215) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluateArgumentExpressions(XbaseInterpreter.java:1205) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._invokeFeature(XbaseInterpreter.java:1135) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.invokeFeature(XbaseInterpreter.java:1081) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.invokeFeature(ScriptInterpreter.java:151) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:991) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:237) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:215) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:1301) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:227) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:215) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:458) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:239) ~[?:?]
at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:215) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluate(XbaseInterpreter.java:201) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.ClosureInvocationHandler.doInvoke(ClosureInvocationHandler.java:46) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.AbstractClosureInvocationHandler.invoke(AbstractClosureInvocationHandler.java:29) ~[?:?]

	at com.sun.proxy.$Proxy333.apply(Unknown Source) ~[?:?]

	at org.eclipse.smarthome.model.script.internal.actions.TimerExecutionJob.execute(TimerExecutionJob.java:48) ~[?:?]

	at org.quartz.core.JobRunShell.run(JobRunShell.java:202) ~[?:?]

	... 1 more


Try changing this

 nCount = nCount + 1

to

nCount +=1

still error

var DateTime dtFadeStart = null
var Timer tFade = null
var Number nCount = 0


rule "fade to scene 1"
when
    Item Boutton received command ON
then
    if(dtFadeStart === null && tFade === null) {
        nCount = 0
        dtFadeStart = now
        tFade = createTimer(now.plusMillis(10), [ |
            nCount +=1
            if(nCount < 60) {
            // new Level for Light shall be 55
                Niche_Milieu.sendCommand((Niche_Milieu.historicState(dtFadeStart).state as Number) + (55 - (Niche_Milieu.historicState(dtFadeStart).state as Number)) / 60 * nCount)
            // new Level for Light2 shall be 25
                Niche_Gauche.sendCommand((Niche_Gauche.historicState(dtFadeStart).state as Number) + (25 - (Niche_Gauche.historicState(dtFadeStart).state as Number)) / 60 * nCount)
                tFade.reschedule(now.plusSeconds(1))
            } else {
                dtFadeStart = null
                tFade = null
            }
        ])
        logInfo("Transitions.rules", "fade to scene 1")
    }
end 

Hmm. Is rrd4j default persistence? If not, you have to change historicState slightly:

                Niche_Milieu.sendCommand((Niche_Milieu.historicState(dtFadeStart,"rrd4j").state as Number) + (55 - (Niche_Milieu.historicState(dtFadeStart,"rrd4j").state as Number)) / 60 * nCount)

Of course this applies for all historicState calls.

Maybe it’s better to use a var, although it’s more lines of code…

var oldVal = 0
var newVal = 0

oldVal = Niche_Milieu.historicState(dtFadeStart,"rrd4j").state 
newVal = 55
if(oldVal !== null) Niche_Milieu.sendCommand((oldVal as Number) + (newVal - (oldVal as Number))/60*nCount)
oldVal = (Niche_Gauche.historicState(dtFadeStart,"rrd4j").state 
newVal = 25
if(oldVal !== null) Niche_Gauche.sendCommand((oldVal as Number) + (newVal - (oldVal as Number))/60*nCount)

I’m not sure though, if this will work as intended :slight_smile:

no it doesn’t work at all :expressionless:

hi guys thanks for your time both of you…
as i told you i’m not confiortable with var, but anyway i love to learn, and i want the machine do what i want.
So i break down the rule step by step and it seems that the historic state calls won’t work with RRD4j persistence,

https://community.openhab.org/t/historicstate-not-working-with-rrd4j/40254/11

and it’s confirm by the rule i made to test it by my own

var DateTime test_time
var DateTime test_time
rule "Test"
when
	Item Boutton changed to ON
then
	time_play_started = now
	logInfo("test"," HistoricalState 1: " + Niche_Milieu.historicState(now.minusDays(1)))
	logInfo("test"," HistoricalState 2: " + Niche_Gauche.historicState(now.minusDays(1)))
	logInfo("test"," HistoricalState 3: " + Niche_Droite.historicState(now.minusDays(1)))

end


with either .state or not
wich return this error

2020-04-22 01:34:12.840 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Test': cannot invoke method public abstract org.eclipse.smarthome.core.types.State org.eclipse.smarthome.core.persistence.HistoricItem.getState() on null

so i checked my persistence service with the rest api

{
  "name": "Niche_Milieu",
  "datapoints": "44",
  "data": [
    {
      "time": 1587430740000,
      "state": "0"
    },
    {
      "time": 1587452220000,
      "state": "5"
    },
    {
      "time": 1587477600000,
      "state": "0"
    },
    {
      "time": 1587489780000,
      "state": "60"
    },
    {
      "time": 1587489840000,
      "state": "60"

it’s seems to store some data

here is my persistence config files, for eye only

Strategies {
    // for rrd charts, we need a cron strategy
    everyMinute : "0 * * * * ?"
    everyhour : "0 0 * * * ?"
    everyDay :"0 0 0 * * ?"
    default = everyChange

}

Items {
    // persist items on every change and every minute
    StationMeteoTemperature : strategy = everyMinute
    StationMeteohumidity : strategy = everyMinute
    LocalWeatherAndForecastCurrentHumidity : strategy = everyMinute
    LocalWeatherAndForecastCurrentTemperature : strategy = everyMinute
    win10_start : strategy = everyChange
    win10_shutdown : strategy = everyChange
    PC_ON_OFF : strategy = everyChange
    Bureau : strategy = everyChange
    CurrentActivity : strategy = everyChange
    Lumieres_niche : strategy = everyChange                                            
    Lumieres_TV : strategy = everyChange                         
    Lumieres_Arche : strategy = everyChange                     
    Lumieres_Plafond_entree : strategy = everyChange            
    Lumieres_PLafond_Salle_a_manger : strategy = everyChange    
    Lumieres_Ambiance : strategy = everyChange                   
    Lustre_1 : strategy = everyChange                                                                                                        
    LustreColorTemperature : strategy = everyChange                                                                               
    LustreColor : strategy = everyChange                                                                                              
    ArcheDroite : strategy = everyChange                                                                              
    ArcheGauche : strategy = everyChange                                                                              
    ArcheMilieu : strategy = everyChange                                                                             
    Plafond_Salle_A_Manger_1 : strategy = everyChange                                           
    Plafond_Salle_A_Manger_2 : strategy = everyChange                                           
    Plafond_Salle_A_Manger_3 : strategy = everyChange
    Lampe_Ambiance_Entree : strategy = everyChange                                                
    Lampe_Ambiance_Entree_ColorTemperature : strategy = everyChange                               
    Plafond_Entree_1 : strategy = everyChange                                          
    Plafond_Entree_2 : strategy = everyChange                                          
    Plafond_Entree_3 : strategy = everyChange                                          
    Plafond_Entree_4 : strategy = everyChange                                                                        
    Niche_Milieu : strategy = everyChange                                              
    Niche_Droite : strategy = everyChange                                                       
    Niche_Gauche : strategy = everyChange                                
    Meuble_Tv_Droite : strategy = everyChange                               
    Meuble_Tv_Gauche : strategy = everyChange
    Cuisine1 : strategy = everyChange                                              
    Cuisine2 : strategy = everyChange                                              
    Cuisine3 : strategy = everyChange                                              
    Cuisine4 : strategy = everyChange                                                                   
}

still stuck with this ******rules

In the rule use the persistence as per the doc’s and not just as logInfo.

But maybe your calls are not going to rrd4j at all.

Niche_Milieu.historicState(now.minusDays(1))

accesses your default persistence service. Have you set one? What is it?
Try

Niche_Milieu.historicState(now.minusDays(1), "rrd4j")

Note that will return a HistoricState object, which is not an Item or a state. The objects most interesting properties are the .state and .timestamp

This is a handy trick for looking at an object in a logInfo(), using curly braces -

logInfo("test"," HistoricalState 1: {}",  Niche_Milieu.historicState(now.minusDays(1), "rrd4j"))

@Udo_Hartmann.

here is the solution thanks to the rules you edited :

var DateTime dtFadeStart = null
var Timer tFade = null
var Number nCount = 12

rule "fade to scene 1"
when
    Item Boutton changed to ON
then
    if(dtFadeStart === null && tFade === null) {
        nCount = 0
        tFade = createTimer(now.plusMillis(10000), [ |
            nCount = nCount + 1
            if(nCount <= 12) {
                dtFadeStart = now.minusMinutes(1)
            // new Level for Niche_Milieu shall be 100
                Niche_Milieu.sendCommand(Niche_Milieu.historicState(dtFadeStart,"rrd4j").state as Number  + (40 - (Niche_Milieu.historicState(dtFadeStart,"rrd4j").state as Number)) / 12 * nCount)
            // new Level for Niche_Gauche shall be 30
                Niche_Gauche.sendCommand(Niche_Gauche.historicState(dtFadeStart,"rrd4j").state as Number  + (40 - (Niche_Gauche.historicState(dtFadeStart,"rrd4j").state as Number)) / 12 * nCount)
                tFade.reschedule(now.plusSeconds(60))
            } 
            else {
                dtFadeStart = null
                tFade = null
            }
        ])
    }
    
end

i adjusted it ,
i reinstalled rrd4j persistence, wich caused some problem and everything works like a charm now

2 Likes

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.