Timeline picker to setup heating, light and so on

@nakh_Home @HomeAutomation

Maybe a little example will help:
My rollershutter should closed between 11:00am and 1:00pm. The rest of the day it is controlled manually.

So you must set shutter on (equal down) from 11:00am to 1:00pm - blue.
The rest ist grey with red line.

Now you can drive the shutter as you like and the shutter stay in this position.
At 11:00am the shutter will be drive down and at 1:00pm he drived in the position befor 11:00am.

When you not used the manual mode the rest of the day is grey (without red underline).
At each switch point, every 15min, the shutter will be drive up. It’s not possible to close the shutter manual from 5:00pm to 6:00pm. Each 15min he will drive up.

The namespace:
event = connected state or states in the timeline, left and right limit manual (grey with red line)
restore state = the state befor the left limit will be stored and after finishing event he will be retored

It’s not nessesary to change the rule file, it’s works fine, as describt below.

@tose Thanks for your answer

i have well understood the current behaviour.

the restore might make sense for a rollershutter but think about AC.

If i want to be sure that the AC will be turned OFF at 11:00PM, i want a way to turn off at 11:00PM.

if i am still awake and wants to turn ON manually just after the scheduled turn off. i do not want to have an autorestore AND i do not want that it will be turned OFF each 15 minutes.

Instead of range, I prefer to program events at a specific time

That’s way that it makes sense to have an (additional) mode without autorestore

Hope that i am clear

@nakh_Home
I remember that we write about this.

But the switching interval is a limiting factor that limits the benefit. I agree with the opinion @opus, a “tasker” is perhaps the better solution.

Here is the rule changed to manual mode do nothing as decribed in my earlier task. Just if someone needs it

rule "timeLine picker 1"
    when
        //Member of gTimePicker changed or // this is only used if a item should emmediatly change to new state after timeline is changed, if not at next cron trigger
        Time cron "0 0/15 * 1/1 * ? *"
    then
        var Number currTimeInterval = (now.getMinuteOfDay() / 15).intValue
        var Number currDay = now.getDayOfWeek()

        gTimepicker.members.forEach[ currSwitchPlan |
        if((currSwitchPlan.state !== NULL) && (timePicker.keySet().contains(currSwitchPlan.name)))
        {
            var String switchPlan = (currSwitchPlan.state as StringType).toString
            var String currKey = currDay.toString

            // check the different week plans 15,17,67; e.g mo-fr, ...
            if (switchPlan.contains('"key":"17"')) currKey = "17"
            if (switchPlan.contains('"key":"15"') && (currDay > 0 && currDay < 6)) currKey = "15"
            if (switchPlan.contains('"key":"67"') && (currDay > 5 )) currKey = "67"

            // determine the scale number in transfer string
            var Number countScale = 1
            var Boolean stopLoop = false
            while((countScale < 9) && (!stopLoop))
            {
                if(switchPlan.contains(countScale.toString + '":'))
                {
                    if(transform("JSONPATH", "$." + countScale.toString + ".key", switchPlan) == currKey)
                    {
                        countScale = countScale -1
                        stopLoop = true
                    }
                    countScale = countScale + 1
                }
                else
                {
                    // error in transfer string
                    countScale = (-1)
                    stopLoop = true
                }
            }
  
            if(countScale != (-1))
            {
                // is it an event picker or not
                var String event = (transform("JSONPATH", "$.100.event", switchPlan.toString))
                var String[] switchStates = (transform("JSONPATH", "$.99", switchPlan.toString)).split(',')
                var ArrayList<String> itemToSwitch = new ArrayList(timePicker.get(currSwitchPlan.name))

                // extract switch states of dataset; jsonpath is realy unflexible so string operation are used
                var String dataSetOfDay = (transform("JSONPATH", "$." + countScale.toString, switchPlan))

                var Number[] switchPlanOfDay = (dataSetOfDay.substring(dataSetOfDay.indexOf('value') + 7, dataSetOfDay.length - 2)).split(',')
    
                if(!(itemToSwitch.size() == 1 && "".equals(itemToSwitch.get(0))))
                {
                    itemToSwitch.forEach [ iTS |
                    var GenericItem currItem = ScriptServiceUtil.getItemRegistry.getItem(iTS) as GenericItem

                    var String newStateString = switchPlanOfDay.get(currTimeInterval) as String
                    var String newState = ''

                    // steht der Zeitsteuerung auf manuell, dann Status nicht ändern
                    if(event == 'true')
                    {
                        if(newStateString != '-1')
                        {
                            newState = switchStates.get(Integer::parseInt(newStateString) as Number)

                            // send only commands when current state differenced from new state
                            if(currItem.state.toString != newState)
                              currItem.sendCommand(newState.toString)
                        }
                    }
                    else
                    {
                        newState = switchStates.get(Integer::parseInt(newStateString) as Number)
          
                        // send only commands when current state differenced from new state
                        if(currItem.state.toString != newState)
                            currItem.sendCommand(newState.toString)
                    }
                    ]
                }
            }
        }
        ]
end
1 Like

one other question,

is there a differance between

Time cron "0 0/15 * 1/1 * ? *"
and
Time cron "* 0/15 * * * ? *"

The last one will trigger each second on the minutes 0, 15, 30 and 45 of every hour, while the first one will trigger only once on these minutes.

New functions

I have added two new functions to the widget, version 0.7.x

  1. Especially for small devices exist now a zoom function. As standard the zoom is activ on mobiles and tablets. On desktops you must force the zoom witch an url- parameter. Where are no breaking changes in the data structur. All scheduling definition is retained. In order to recognize the correct orientation on the mobiles and tablets, it is necessary to choose a greater value for height in the sitemap. The url parameter is zoom. (&zoom=auto|no|force) please see the descripten in the first post or on GitLab.
  2. Portuguese and italien language as axis label is added.

Replace only the index.html, switchPointSet.js, switchPointSet.css files.
note: After replacing the files one must clear the browser cache!

Here are two screenshots with visible zoom in landscape and portrait mode:

You will find the current version here https://gitlab.com/RNTs_3/openhab-timeline-picker/tree/addZoomForTimeLine. When a few people have tested the new version i will merge this function’s in the master.

In case you wish to add Italian, here’s a translation

  • Language: Italian
  • Shortcut: it
  • Labels:
'Lun - Dom','Lun - Ven','Lunedi','Martedi','Mercoledi','Giovedi','Venerdi','Sabato','Domenica','Sab-Dom'

@Lionello_Marrelli Thanks for the translation.:+1: I have added italien as language for the label.

on my first test with version on PC with &zoom=force 7.0 all is working as expected. great work.

Hello @tose,

I started the testing and everything is working great as expected.

I noticed only one visual thing. There is a misalignmentin the first “boxes” from each day, but I do not know if this is from my screen or resolution:

image

Thanks again for your great work.

Hi @rjduraocosta,

it’s not your screen or the resolution. I have aligned first row to the right. But i agree with you, it’ s looks not so nice. I will correct this and point you, when it done.

Hi guys,

awesome thread, Thank you Torsten for providing this tool. However I have difficulties getting it to run. Could someone maybe help?

I’m currently running OH 2.5 Milestone and everything is in the directory as described. Setting up on and off times in the picker widget works and the times are getting saved as well. Having the gTimepicker group in my sitemap, I get the output:

{"1":{"key":"1","value":[0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,...

which seems about right. The thing which doesn’t work is getting an event fired. In my understanding, the rule should change the defined String Item (my case “sprincklerZone”) value to 0, 1 or whichever state, according to the set widget. Am I right?

I currently have the following setup:
Items:

Group   gTimepicker
Group   gTimepickerObserver
String  TransferItem                "[%s]"          (gTimepicker)
String  sprincklerZone

timeLinePicker.rule:

val HashMap<String,ArrayList<String>> timePicker = newHashMap(
    "TransferItem1" -> newArrayList('sprincklerZone')
)

Rule to fire it up (currently just having logWarns to see if something happens)

rule "manipulate sprinckler"
when
  Item sprincklerZone changed
then
  logWarn("Rule", "XX")
  switch (sprincklerZone.state) {
    case "1" : {
      // activate zone 1
      logWarn("Rule", "1")
    }
    case "0" : {
      // activate zone 2
      logWarn("Rule", "0")
    }
  }
end

The problem I’m facing is, that there is no log written hence the Item String “sprincklerZone” never gets an “0” or “1” written to. I also have the debug mode in the timeLinePickers.rule on, so that every 15 seconds the Item should be fired (if I changed the Timepicker widget during that time accordingly). But nothing happens. Any tips?

Regards
Chris

Hi Chris,

as first you must correct the item name in your items definition or timeLinePicker.rules.

You must type:

String TransferItem1                 "[%s]"             (gTimepicker)

So it is equal to your definition in timeLinePicker.rules.
For the item sprincklerZone i would choose Number and not String.

Thanks Torsten, missed this detail, it’s working now! Awesome, Thank you!

can i use the same timeline rules for multiple time lines,

just re defining the initial hashmap ie the bit in ----- part of config -----

for my 2nd time line definition and pass the values when i call in the sitemap

or do i duplicate everything with the different settings & names and go from there

Yes of course. You can use the one rule for as much as you like timelines. Each timeline is represented through a unique transferitem.

This is the example for two timelines.
Then customize your webview line in the sitemap and done.

1 Like

I just stumbled upon this Timeline picker thread. It looks awesome.
Don’t know why I missed it so far. Will give it a try. Thanks in advance!

excellent, works as expected,did you by change you ever look at/notice the thread that shows a time line for past events

What did you mean jeff?

I hope that the most of you will be satisfied with the presentation of timeline. My intention is to control/ switch things not to show past events. Please explain your thoughts.

1 Like