Looking for Software utilities. like chrono, timer,

Hello,
Happy user of openhab2 here!

Using openhab for over a year and controlling my heating, curtains, lights and some sockets with it.

What I also like todo is creating ‘Fun’ functions like a chronometer, a timer and 8 ball for everyday use.
But currently running out of ideas. Anyone got some more ideas?

1 Like

Hi @Jo_C
Look cool!!
Could you share the setup, please?
Items, rules and sitemaps.

Thanks

1 Like

@Jo_C
can you please provide us your code example. I’m interested in the part how you have implemented the remaining time item.

1 Like

Hello hello,
I share my code, but please be advised it really bad written. It was like a draft Rule I created for both the chrono and the timer. I need to rewrite it, but didn’t come to it yet
It has the following problems

  1. the chronometer runs to slow, It would probably be better if a like “Time elapsed since start Chronometer” calculation is used here. In my test with current code on my machine ticks about: 3 min/hour too slow
  2. it’s also possible that the timer is not very accurate but not really tested this yet.
    If you use the chronometer and timer for things that shoudln’t be very accurate to the second, you’re probably good to go.

SITEMAP:

    			Frame label="Timer" {
				Switch label="Timer" item=Timer1 mappings=[3="3 MIN",5="5 MIN",10="10 MIN"] icon=hourglass
				Text label="Timer Resterende tijd" item=Timer1Countdown visibility=[Timer1Countdown!= "0:00"] valuecolor=["blue"] icon=hourglass
				Switch label="Timer" item=Timer1 mappings=[30="30 MIN",60="60 MIN",reset="RESET"] icon=hourglass
			} 
			Frame label="Chronometer" {
				Switch label="Chronometer" item=Chrono1State mappings=["START"="START","STOP"="STOP","RESET"="RESET"] icon=chrono
				Text label="Tijd actief" item=Chrono1String visibility=[Chrono1 != "0"] valuecolor=["blue"] icon=chrono
			}

ITEMS:

    String Timer1 "0:00"
    String Timer1Countdown "[%s]"

    Number Chrono1 
    String Chrono1String "[%s]"
    String Chrono1State

RULES

    import java.util.*;
    import java.util.List
**Rule Timer**

    rule Timer1
	when Item Timer1 changed
	
	then
	
		var int timersecs
		var cmd = Timer1.state.toString
		if (cmd == "reset") {
			timersecs = 0
			Timer1Countdown.postUpdate("0:00")
                        //DO SOMETHING HERE
		
		} else {
		 	timersecs = (Integer::parseInt(cmd))*60
		 	logInfo("TimerM",timersecs.toString)
		 	var int timerM = 0
		 	var int timerS = timersecs
		 	
		 	while ((timersecs > 0) && (Timer1.state.toString == cmd)) {
		 		timerM = 0
		 		timerS = timersecs
		 		 while (timerS > 59) {
		 		 	timerM = timerM  + 1 
		 		 	timerS = timerS - 60
		 		 }
		 		 
		 		 var String strMin
		 		 var String strSec
		 		 if (timerM < 10) {
		 		 	strMin = "0" + timerM.toString
		 		 } else {
		 		 	strMin = timerM.toString
		 		 }
		 		 
		 		 if (timerS < 10) {
		 		 	strSec = "0" + timerS.toString 
		 		 	} else {
		 		 		strSec = timerS.toString
		 		 }
		 		 
		 		 var String timeString = strMin + ":" + strSec
				 //logInfo("TEST",timeString)
				 timersecs=timersecs-1
		 		 Timer1Countdown.postUpdate(timeString)
		 		 Thread::sleep(1000)
	 		}
	 		Timer1.postUpdate(NULL) //hides the remaning time item from the sitemap
	 	} 
	end

Rule Chronometer

 rule "Chrono1"
    when Item Chrono1State changed
	
    then

	if (Chrono1.state == NULL) {
		Chrono1.postUpdate(0)
	}

	if (Chrono1State.state == "START") {
		while(Chrono1State.state == "START") {
			var int elapsed = Integer::parseInt(Chrono1.state.toString())
			Chrono1.postUpdate(elapsed+1)
			var int h
			var int m
			var int s
			while (elapsed > 0) {
				if (elapsed >= 3600 ) {
					h=h+1
					elapsed=elapsed-3600
				} else if (elapsed >= 60) {
					m=m+1
					elapsed=elapsed-60
				} else {
					s = elapsed
					elapsed=0
				}
			}
			var String timeString = String.format("%1$02d:%2$02d:%3$02d",h,m,s)
			Chrono1String.postUpdate(timeString)
			Thread::sleep(1000)
		}
	} else if (Chrono1State.state == "RESET") {
		Chrono1.postUpdate(0)
		Chrono1State.postUpdate("STOP")
	}

Hopes that shines some light on the functionality.

Have a great day !

For the ‘8 Ball’ Code that just random answersly “yes” or “no” (but it’s in dutch, because that’s my native language)

Sitemap

    			Frame label="8 Ball" {
				Switch item=Random label="Willekeurig" mappings=["again"="Doediszot"] visibility=[RandomResult==""] icon=magic
				Text item=RandomResult label="Het antwoord op je vraag is " visibility=[RandomResult!=""] valuecolor=["JA!"="green","Neen"="red"] icon=magic
			}

ITEMS

    String Random
    String RandomResult "[%s]"

RULES

    rule _random
	when 
		Item Random received command
	then
	var int RandomNR = (new java.util.Random).nextInt(1001)
	if (RandomNR%2 == 0) { //if even number
		RandomResult.postUpdate("JA!") //yes
	} else {
		RandomResult.postUpdate("Neen") //no
	}

    //hide the ResultRandom Text item on sitemap after 5 seconds of display.
	createTimer(now.plusSeconds(5), [| 
		RandomResult.postUpdate("")
	])
    end

have a good one !

1 Like

I also added a Lotto Generator that help me pick Lottery game numbers
If created for the Belgian Lotto but it can easily be adapted

Sitemap

			Frame label="Lotto Generator" {
			Switch item=LottoState label="Lotto Nummers" mappings=[ON="Pick!"] icon=magic
			Text item=Lotto valuecolor=["blue"] visibility=[Lotto!=""] icon=lotto
			}

ITEMS

String Lotto "Winnende nummers [%s]" //winning numbers
Switch LottoState

RULES

import java.util.*;
import java.util.List
rule _lotto
when 
	Item LottoState received command 
then
	//There are 45 lotto numbers
	// each game is 6 numbers
	
	//lotto nrs based on https://www.nationale-loterij.be/onze-spelen/lotto/statistieken from best to worse
	//last upadted 3/11/2018
	val int[] theLottoNumbers = newArrayList(7,12,16,24,38,22,5,25,28,14,17,33,9,3,13,36,27,2,4,18,19,21,10,29,20,31,1,40,23,6,26,32,35,11,34,37,39,8,41,42,30,15,43,45,44)
	
	//create result arraylist
	val List<Integer> result = newArrayList()
	//last number in theLottoNumbers to use
	var int lastgoodnr = 16
	
	//Pick random nrs and add to result array
	while (result.size() < 6) {
		var int i = (new java.util.Random).nextInt(lastgoodnr+1)
		var int currentNR = theLottoNumbers.get(i)
		
		if (result.size > 0 ) {
			if (result.contains(currentNR)) {
				//logInfo("Lotto Generator","Duplicate number: " + currentNR.toString())
			} else {
				result.add(currentNR) 
			}
		} else {
			result.add(currentNR) 
		}
	}

	//sort the result array
	Collections.sort(result)

	//add array to string and format string to show always 2 decimals
	var String strResult = String.format("%1$02d %2$02d %3$02d %4$02d %5$02d %6$02d",result.get(0),result.get(1),result.get(2),result.get(3),result.get(4),result.get(5))
	logInfo("Lotto Generator","Generated Lotto Numbers: " + strResult)

	//Show the generated numbers in sitemap
	Lotto.postUpdate(strResult)
      
        //hide result after 2 minutes, possible not ideal, because it creates a timer everytime.
	createTimer(now.plusMinutes(2), [|
		Lotto.postUpdate("")
	])
2 Likes

Thanks for sharing,
It’s always interesting to see different code for unusual problems
Just today I was dealing with a rule generating random number and you have a more efficient syntax

It doesn’t matter there is some good stuff in there

Thanks again

For me (on OH 2.4) it is only working if I change it to:

            while(Chrono1State.state.toString == "START")
            {
                var int elapsed = Integer::parseInt(Chrono1.state.toString())

This is not needed:

    import java.util.*;
    import java.util.List