[SOLVED] Thermostat Rule Help (gpio, dht22, exec binding, things, items, rules)

Duh… why didn’t I think of that? I already have the expire binding installed to control a relay. Thanks your help and patience sir!

How does my solution to the notification rule look? Do you see any issues with it?

Looks ok

K… thanks

Go to bed

LOL! :smiley:

The evenings and early morning is when I get the chance to do my stuff. Not much time for fun stuff due to wife and 2 kids and another on the way! I’m going to watch a little bit of the British Open, then it’s off to bed! Thanks again

Guess who’s still awake? I laid down to go to sleep and ding… phone received an email! Looking at the logs… It looked like the timer wasn’t getting nulled because the if statement evaluated to false. So I added some stuff to check and change the timer time to 5 mins.

See the log says the… AC_Relay changed to ON @ 3:20am
Then 2 mins later it say the… 20 min timer expired

018-07-20 03:20:51.932 [INFO ] [pse.smarthome.model.script.TempCheck] - AC_Relay changed to ON and Vals set and threshold are set
2018-07-20 03:22:30.923 [INFO ] [el.core.internal.ModelRepositoryImpl] - Refreshing model 'hvac.rules'
2018-07-20 03:22:51.895 [INFO ] [pse.smarthome.model.script.TempCheck] - 20 min timer expired

The rule is failing right after the logInfo(“TempCheck”, “5 min timer expired”) Seem to me that the val supply is having trouble??

I’ve been searching the error, changing stuff, then banging my head on the desk for the past 3 plus hours. I even added a rule to null the timer when the AC_Relay changed from ON to OFF. I’m out of ideas and exhausted. But, I just can not let this go… :frowning: :frowning:

Here is my updated rule…

rule "Send Email/Notification after AC is ON for 5 mins IF AC_Relay is ON and split is less than 15 degrees"
    when
        Item AC_Relay changed from OFF to ON
    then
                val set=Setpoint_Temp.state as Number
                val threshold=15
                logInfo("TempCheck", "AC_Relay changed to ON and Vals set and threshold are set")
                tempTimer=createTimer(now.plusMinutes(5), [|
                logInfo("TempCheck", "5 min timer expired")
                        val supply=SupplyAir_Temp.state as Number
                        logInfo("TempCheck", "Val supply set")
                        if (AC_Relay.state==ON && (threshold>=(set-supply))){
                                logInfo("TempCheck", "Relay is still ON and threshold is less than (set-supply)")
                                sendMail("xxxx", "xxxxx", "xxxxx")
                                tempTimer=null
                        }else{
                                tempTimer.cancel()
                                tempTimer=null
                                logInfo("TempTimer", "tempTimer canceled and nulled")
                                        }
                                ])
    end

Most recent…
openhab.log

2018-07-20 05:01:57.008 [INFO ] [pse.smarthome.model.script.TempCheck] - AC_Relay changed to ON and Vals set and threshold are set
2018-07-20 05:03:04.250 [INFO ] [el.core.internal.ModelRepositoryImpl] - Refreshing model 'hvac.rules'
2018-07-20 05:06:32.079 [INFO ] [lipse.smarthome.model.script.Lockout] - AC lockout ON
2018-07-20 05:06:57.013 [INFO ] [pse.smarthome.model.script.TempCheck] - 5 min timer expired
2018-07-20 05:06:57.016 [ERROR] [org.quartz.core.JobRunShell         ] - Job DEFAULT.2018-07-20T05:06:57.011-05:00: Proxy for org.eclipse.xtext.xbase.lib.Procedures$Procedure0: [ | {
  logInfo(<XStringLiteralImpl>,<XStringLiteralImpl>)
  val supply
  logInfo(<XStringLiteralImpl>,<XStringLiteralImpl>)
  org.eclipse.xtext.xbase.impl.XIfExpressionImpl@19ca962
} ] threw an unhandled Exception: 
java.lang.NullPointerException: null

You need to define the variables used in the timer lambda either in the lambda or global.

rule "Send Email/Notification after AC is ON for 5 mins IF AC_Relay is ON and split is less than 15 degrees"
when
    Item AC_Relay changed from OFF to ON
then
    val set=Setpoint_Temp.state as Number
    val threshold=15
    logInfo("TempCheck", "AC_Relay changed to ON and Vals set and threshold are set")
    tempTimer=createTimer(now.plusMinutes(5), [ |
        logInfo("TempCheck", "5 min timer expired")
        val supply = SupplyAir_Temp.state as Number
        val set = Setpoint_Temp.state as Number
        val threshold = 15
        logInfo("TempCheck", "Val supply set")
        if (AC_Relay.state == ON && (threshold >= (set - supply))) {
            logInfo("TempCheck", "Relay is still ON and threshold is less than (set-supply)")
            sendMail("xxxx", "xxxxx", "xxxxx")
            tempTimer = null
        } else {
            tempTimer.cancel()
            tempTimer = null
            logInfo("TempTimer", "tempTimer canceled and nulled")
        }
    ])
end

Understood. I’ll give it a shot when I get home. Thanks

Alright… I got this to work, but was still getting undesired results. This whole experience has been tough being that I previously knew very little about programming. More of the hands on kind of guy.

That said, I’d like to thank the OH Community for the help I’ve received… without the community this adventure would have come to a halt quickly. Again, thanks for being patient, pointing me in the right direction, and forcing me to think!

My solution was to remove the temptimer and replaced with the expire binding. Thanks @vzorglub for suggesting I use the expire binding for the lockout… it’s what led me to use it for other purposes. Works great!

Now… I would like to keep track of the hours that the AC is on for the day, week, and month. I found this thread…Generator hours counter, but noticed it’s pretty old. I get that I would need to have some variables to keep track of when the ac turned on and when it turned off. What I’m not sure of is whether or not I’d have to use any of the imports??

The only import you may still need is: import java.lang.Math
The rest has now been implicit with OH 2.x

Use the code in post 2441th

Got it. What’s up with the lock.lock stuff and do I need it?

Probably not
It’s used to prevent the same rule running at the same time when there is a rule that take a while to execute and a trigger may happen when the rule is still running.
In your case your shouldn’t need it. In the other post he was using a rule to start a generator or something that took a while to get up to speed and so had to prevent the rule being run twice.

Understood. Thanks for the explanation. I’ll see what I can do… appreciate it.

Thanks Vincent for pointing me in the right direction!

Update… I got the “switch item on/off tracking” to work.

At first I adjusted this Generator hours counter to fit my needs. After thinking about it for a few days I concluded that it was overly complex for my situation and I didn’t like the cron jobs constantly checking the states.

So I took this Calculated daily run time of a switch and modified to accomplish my needs. Note… this part >> var Number execDuration = Seconds::secondsBetween(new DateTime(prevOnState.calendar.timeInMillis), now ).getSeconds() doesn’t work in the newest version of OH. Needs to change the bolded part to this >> toInstant.toEpochMilli

Also, no imports are needed for it to work.

@vzorglub Do you know if the expire binding will work for a duration of a year?

@bobby_wayne
I don’t think so. Anyway your system will probably restart more than one in that period so it wouldn’t matter annyway
What are you trying to do?

Get a notification / email a year after a reed switch changes from closed to open.

I think the best way would be to put the time the switch changed to open in an item.
For example:

rule "Entry Doors Update"
when
    reedSwitch changed from CLOSED to OPEN
then
    Thread::sleep(100) // give persistence time to catch up
    if (previousState == NULL) return;
    reedSwitch_LastOpen.postUpdate(now.toString)
end

Your new item will be:

DateTime reedSwitch_LastOpen

And it needs to be persisted and set to restoreOnStartUp to survive a reboot

And then a rule that fires everyday to check if the time now is more than one year after the saved time and fire out an email. I don’t have that code yet. Maybe you have a go and we’ll find out together

@vzorglub

Here is what I’d like to do… I have a contact attached to a filter base. When the filter base is opened, a date time item gets set. I also have a number item used for a selection… 2=2 months, 3=3 months, 6=6 months, 12=12 months. I’d like to have OH check if now is after date time months plus number item (selection on sitemap). If not, check the following Friday. If yes, then send me an email saying that the filter needs to be changed.

Here’s what I have thus far…

.items

Contact Filter_Contact  // Reed switch
DateTime Changed_DateTime  // Gets DateTime that Filter_Contact changed from Closed to Open
Number Change_Period  // Displayed on sitemap using selection.  Gives ability to adjust the duration.. for instance 2=2 months 3=3months 6=6 months 12=12 months (using transformation map)

.rules
// This is just for testing. Am I right to assume that this will also work for now.minusDays and now.minusYears??

rule "Show Filter_Changed switch"
when
        Time cron "0 0/1 * 1/1 * ? *"
then
        val DateTime filterChanged=Changed_DateTime.state
        logInfo("Filter", "Val filterChanged has " + filterChanged + " state")
        val Number filterPeriod=Change_Period.state as Number
        logInfo("Filter", "Val filterMinutes has " + filterPeriod + " state")
        if(now.minusMinutes(filterPeriod).isAfter(filterChanged))
                {
                logInfo("Filter", "It works...you can sendMail now!!!")
                }
end

log

Error during the execution of rule 'Filter Change' An error occurred during the script execution: Could not invoke method: org.joda.time.DateTime.minusMinutes(int) on instance: 2018-08-27T22:10:00.036-05:00

I’ve searched the forum and google for a solution, but I’m not sure if I’m even searching the right topic?!?