Create a 24h timer in an string item

  • Platform information:

    • Hardware: _CPUArchitecture: RPi /RAM: ?/storage: 16GB
    • OS: openHAB 3.4.1
    • Java Runtime Environment: I don’t know
    • openHAB version: 3.4.1
  • Issue of the topic: I have changed the state of the items, the Timer_state item remains on “NULL” and I do not see any change. Anyone have an idea what to do?

  • Please post configurations (if applicable):

    • Items configuration related to the issue:
      timer.items file in openhab-conf/items
Switch mySwitch "My Switch"
Switch mySwitch_reset "My Switch Reset"
String Timer_state "Timer State [%s]"
  • Rules code related to the issue:
    timer.py file in openhab-conf/automation/jsr223
import org.joda.time.DateTime
import org.joda.time.format.DateTimeFormat

var DateTime start = now()
var Timer timer = null

rule "start timer"
when
    Item mySwitch received command ON
then
    start = now()
    timer = createTimer(1000, [[
        elapsed = (24*60*60) - ((now().millis - start.millis)/1000)
        postUpdate(Timer_state, formatElapsed(elapsed))
    ]])
end

rule "reset timer"
when
    Item mySwitch_reset received command ON
then
    start = now()
    postUpdate(Timer_state, formatElapsed((24*60*60)))
    if(timer != null) {
        timer.cancel()
        timer = null
    }
end

def formatElapsed(elapsed) {
    def hours = elapsed / (60 * 60)
    elapsed -= hours * (60 * 60)
    def minutes = elapsed / 60
    elapsed -= minutes * 60
    def seconds = elapsed
    return String.format("%02d:%02d:%02d", hours, minutes, seconds)
}

  • If logs where generated please post these here using code fences: No error log and no logs about automation

Thanks in advance!

What language are you trying to use here? If Rules DSL, that’s not how to define a function (not that you need that function in the first place, you’re doing it the hard way to get the difference between two times). I’d expect you to be getting errors in openhab.log when this file is loaded because it is syntactically incorrect.

First of all, Rules DSL doesn’t really have functions, it has lambdas and you can put a lambda in a global variable but global variables have to go before the rule. See Reusable Functions: A simple lambda example with copious notes for details.

But you don’t need the function. You also don’t need the imports from joda since, Joda no longer exists in OH 3 (which should also generate errors in the logs when this file is loaded).

[[ is syntactically incorrect and you never declare elapsed as a variable, both of which should also generate syntax errors when this file is loaded.

Java ZonedDateTime, which replaced Joda also doesn’t have a millis.

Something like this would be a better approach (I’m just typing this in, it will likely have typos). There might be some logical errors here too because you set the timer for one second but are posting 24 hours worth of seconds minus the difference between now and when start was set which should be exactly 1 seconds since that’s what you scheduled the timer for. So you are not creating a 24 hour timer and you are not measuring a 24 hour timer.

var Timer timer = NULL
var start = now

rule "start timer"
when
    Item mySwitch received command ON
then
    start = now
    timer = createTimer(1000, [ |
        Timer_state.postUpdate(Duration.between(now, start).toHours+":"+toMinutesPart+":"+toSecondsPart))
    ]
end

That will post how much time has elapsed since the Timer was created which I guess kind of makes sense though it seems like you’d want to post that before the Timer goes off, not after.

By default Duration will print out in ISO8601 format which is pretty readable as well so you could use just

Timer_state.postUpdate(Duration.between(now, start).toString)

If for some reason you want to know how much is left of a 24 hour period based on the difference between now and start you’d use

Duration.ofHours(24).minus(Duration.between(now, start)). 

But you know how long the Timer is going to take to run ahead of time, so why wait until the timer exits to actually post that?

1 Like

Hello, thank you for your answer! I don’t know anything about automations that you put directly in the openhab-conf/automations directories and I think it’s pyton but I don’t know enough about it to say so! I asked ChatGPT to code me what I wanted :sweat_smile:. I already know a lot about the graphical configuration interface for everything that is rather home automation… But here, I “divert” the main use of openhab a little bit by making a “scoreboard” , for a private competition, which looks like this:

And I would like to be able to launch a 24h timer in any way it is and be able to reset it where it is put “NULL” which is for the moment the value of the item string “Timer_state”. But if there are other ways than going through items, I’m open to suggestions…

I tried your code but I still have nothing that appears in the logs and nothing that moves in the item… As file extension I put “.py”, is it the right one? And I placed the file, which I called “timer.py” with your code, in the “jsr223” directory in “automations”. Is this how it should be done? And does the script launch itself directly after modifying the file or do you have to restart openhab? I tried a lot of options but nothing worked yet :smiling_face_with_tear:

Do you have any idea how can I do what I want?

Thanks!

ChatGPT is fine to use as a shortcut if you have the expertise to review and fix what it gives you, but you make it pretty clear that that’s not the case. No one should expect ChatGPT to spit out something that just works perfectly (in any context), and it’s unreasonable to post ChatGPT code on the Internet asking someone else to fix it for you.

Based on all of the questions you’re asking, it seems like you’re just trying things because you saw someone else do it, without understanding what you’re actually doing (or why you’re doing it). That makes it very difficult to help you out.

I’m not saying this to chastise you or chase you away. We’re here to help you learn how openHAB works, but we’re not going to make your rules for you. If you want to expand your knowledge beyond UI-based rules, then you’ll need to do some reading and learning before asking questions.

OH supports a number of programming languages for rules. The code above in my reply is a Rules DSL rule so belongs in a .rules file in the rules folder.

If you don’t know programming I strongly recommend creating rules in the UI using Blockly. This is a graphical programming approach which is much easier for non-programmers to create, read and understand.

I’ve yet to see ChatGPT create an OH rule that would work out of the box. And fixing it requires a knowledge of OH such that you may as well write it yourself.

What does this Timer do? As a concept, a Timer is a way to schedule something to happen at a specific time (e.g. in 15 minutes turn off the light).

No, as I thought was clear in my reply that’s a Rules DSL rule. See Rules | openHAB for everything you need to know to understand that code. But to answer your question, it needs to be in the rules folder with a .rules extension. Your original code is Rules DSL too, just not syntactically correct.

I still don’t understand what it is you want. What needs to happen at the end of the 24 hours?

Hi @rpwong,

I completely agree with you and apologize for posting code from ChatGPT! I did notice that there were a lot of things that needed to be adapted in what he told me and in most cases, I knew what needed to be adapted, but in the codes he gave me, I didn’t know any more than that and should have researched better before posting directly.

I’ve never seen anyone do what I’m trying to do but I know it must be possible. And I understand most things because I know how to read code but I can’t easily find errors when there are some! From the moment the code works, I can easily adapt it according to my knowledge.

I fully understand your remark and I will try to be more careful in the future so as to seek more myself beforehand.

@rlkoshak, Thank you very much for all these precisions! I didn’t know it was simple “rules” and now that I know it, it will be easier for me to finish what I’m trying to do and that, correctly…

Yes, I know but I didn’t think it was possible to do that with “rules”, that’s why I didn’t even try with Blocky! Usually, when I’m doing pretty wacky scenes for home automation, I use Blocky first, then I copy-paste the code and adapt it because I understand it very well! But I think I’m going to have to start learning it more in depth.

This timer does nothing but display a 24h countdown in the layout (capture in my previous answer). It will only be visual in the scoreboard I talked about and I think passing the timer through a string item to display it in the layout is a good idea… So I’m “hijacking” the main use of openhab but I know it’s an effective way to do what I want!

Maybe I’ll make sure we can’t control items with scores anymore but otherwise, nothing special will happen except everyone will be there to watch the end (it’s for a private competition triathlon) and shout all in heart 10 - 9 - 8… And then party :blush:.

Thank you again for all your details :+1:! I hope I can finish all of this without problems :upside_down_face:.

I didn’t get that from your answer. See Design Pattern : Expire Binding based Countdown timer and Design Pattern: Looping Timers. If wanting to use JS Scripting for your timer also see Announcing the initial release of openhab_rules_tools which has a countdown timer implemented as a library call.

At a high level, you need a Timer that triggers every so often (every second? every minute?) and updates an Item with the amount of time remaining.