Timeline picker to setup heating, light and so on

rules
Tags: #<Tag:0x00007f01486927b0>

(torsten) #104

I see a missing comma:

val HashMap<String,ArrayList> timePicker = newHashMap(
“TransferItem1” -> newArrayList(‘Thermostat1’,‘Thermostat2’), // <---- comma
“TransferItem2” -> newArrayList(‘LightSwitch45’)
)


(Jeff Haskel) #105

Thanks, it was missing on the origonal


(torsten) #106

I’ve seen it … and corrected it. :wink:


(Jeff Haskel) #107

excellent work mind, am I missing some thing else to switch the items ?


(torsten) #108

Download this project from https://gitlab.com/RNTs_3/openhab-timeline-picker and save:

location file
openhab-conf/html/time-line-picker/ index.html
openhab-conf/html/time-line-picker/js/ switchPointSet.js
openhab-conf/html/time-line-picker/css/ switchPointSet.css
openhab-conf/rules timeLinePicker.rules

The Rules-file is also in the gitlab repository. Please download the file.


(Jeff Haskel) #109

What logInfo can I add to see if anything is being triggered or lost

I am openhab-cli showlogs | grep Thermo, I have not noticed any errors for a while


(torsten) #110

Please post a copy of your Rules file (complete). Than we have a base to look.

One additional hint: the rule is trigger each 15min.
See the trigger section in the rule. You can change the trigger interval to 15 seconds.


(Jeff Haskel) #111

my rules file is identical to yours, with the 15 second trigger enabled


(torsten) #112

Hi Jeff, to help you post your rule file, your item definition and i will look.


(Jeff Haskel) #113
import org.eclipse.smarthome.model.script.ScriptServiceUtil
import java.util.HashMap

import java.util.ArrayList

// timeline/ timepicker control
// version 0.6
// ToSe
//
// init values & customize for you own enviroment
// -----------------------------------------------------------------------------------------------------------
//
//
// requirements: MapDB, JSONpath transformation
// -----------------------------------------------------------------------------------------------------------
// String TransferItem_XX “xxxxxx [%s]” (gTimepicker)
//
// Group gTimepicker
//
//
// data structure
// -----------------------------------------------------------------------------------------------------------
// val HashMap<String, ArrayList> timePicker = newHashMap(
// “TransferItem1” -> newArrayList(‘item1’,‘item2’,…), // enum all items to control
// “TransferItem2” -> newArrayList(‘item3’)
// … // enum all TransferItems
// // you control as many widgets as you need
// )
//
//

// -------------------- part of config -----------------------------------------------------------------------

val HashMap<String,ArrayList> timePicker = newHashMap(
“TransferItem1” -> newArrayList(‘Thermostat1’,‘Thermostat2’),
“TransferItem2” -> newArrayList(‘LightSwitch45’)
)

// -------------------- end of config ------------------------------------------------------------------------

// -------------------- don’t change anyone ---------------------------------------------------------------
val HashMap<String,String> oldStates = newHashMap()

rule “timeLine picker 1”
when
Member of gTimePicker changed or
// Time cron “0 0/15 * 1/1 * ? *”
Time cron “0/15 * * ? * * *” // for debug, trigger eatch 15 seconds
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
                logError("timepicker","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 = ''

                    if (event == 'true') {
                        var Boolean itemInGroupHit = false
                        gTimepickerObserver.getMembers().filter[ i | i == currItem].forEach[ i | 
                            itemInGroupHit = true
                        ]
                        if (newStateString != '-1') {
                            if (!itemInGroupHit) {
                                //save state from item befor event
                                oldStates.put(iTS,currItem.state.toString)
                                gTimepickerObserver.addMember(currItem)
                                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 {
                            if (itemInGroupHit) {
                                gTimepickerObserver.removeMember(currItem)
                                //restore old state for item
                                newState = oldStates.get(iTS) as String
                                oldStates.remove(iTS)
                                // 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


(Jeff Haskel) #114
Group gTimepicker

Group gTimepickerObserver

String TransferItem “[%s]” (gTimepicker)

Switch Thermostat1

Switch Thermostat2

Switch LightSwitch45


(torsten) #115

Okay.
What is your intention? It’s only the item definition from my example. But which item want you control?
Is the real item name from your thermostat realy ‘Thermostat1’ and is it realy a switch?


(Jeff Haskel) #116

I get the unaltered example working in most cases , then alter to my use.


(torsten) #117

Adapt the example for your usecase and it will work.
I will not add some logInfo for a try.


(Jeff Haskel) #118

Currently getting this, I have manually reset the TransferLine and tried just clearing, still no items being switched

just spotted this

2018-12-09 13:31:45.002 [ERROR] [se.smarthome.model.script.timepicker] - error in transfer string

(torsten) #119

Please open the devTools and look into the console. Is there a error message in the console.

Two quetsions:

  1. The space between “current selected” and the grey rectangle in the right upper corner is in your screenshot 0.
    Have you something modified in the css or js files?
  2. The Switch Reset Timeline. What is this switch doing?

(Jeff Haskel) #120

I dont know, maybe i need to reset the persistant database ?

the reset was a tempopary idea to clear the time line by clearing

TransferItem.postUpdate("")
TransferItem1.postUpdate("")
TransferItem2.postUpdate("")

I have not altered any css or js, can i check there checksum ?

in the logging ive seen,

2018-12-09 20:47:45.004 [INFO ] [eclipse.smarthome.model.script.check] - 1 |
2018-12-09 20:47:45.005 [ERROR] [se.smarthome.model.script.timepicker] - error in transfer string

after adding your debug code


(torsten) #121

It’s a little bit tricky, because you are shuffling the problems.:scream:
Let us solve this step by step.
The first thing is the presentation in the user interface. Without a correct presentation, with all timelines we are breaking on this point.

What says the console? (F12 on chrome) Error messages?


(Jeff Haskel) #122

10.0.0.89-1544389654280.log (17.0 KB)


(torsten) #123

perhaps you can take an screenshot