Arraylist

For debug purposes and a bit of fun it would be nice to know:

  1. How many times a rule has been triggered,
  2. When a rule was last triggered
  3. How many hours a light has been on
  4. When a sensor got its last update

So if you look on the list above and you have 30+ rules, 60+ lights and 25+ sensors

this means we could create 150+ items, or what i rather would prefer is to use dictionaries(arrayList).
So from a rule I would simply add:

RuleTriigeredArray(me.name)=RuleTriigeredArray(me.name)+1
RuleLastRunArray(me.name)=now()

and for my lambda for lights I would simply add:

this to the on rule
LightOnArray(item.name) = now()

and this to the off rule
LightUsedArray(item.name) = LIghtUsedArray(item.name) +(now()- LightOnArray(item.name) )

So the question is if this possible or at least that this is some feature that the developers could consider for the next relase, so that we can get a new item type called ArrayLis or so (so it can be persited on startup…)

Stuff like that can easily be done with the experimental scripting engine in JavaScript or Python etc. You may want to switch to that depending on your scripting skill level. here some examples: https://github.com/illnesse/openhab2_pub_001/tree/master/automation/jsr223/00_scripts

Absolutely possible. And so long as you don’t need the information shown in your sitemap or to persist across restarts of OH Lists and Maps are the perfect solution for something like this.

However, if you want it persisted across restarts what you will have to do is encode your data in a String Item then decode it back out after the restart.

It can be done in Rules DSL too. The big problem is there is no List Item type and that wouldn’t be any different for the JSR223 languages.

So here is how I would approach it. Unless someone has gone out of their way, you should be able to store up to a 2^31 characters though the DBs likely can store less. Given the the novel Moby Dick is around 2.5 MB you should be fine, though if this data continues to grow you will want to switch to using files or a DB for storage at which point you have to weigh the tedium of writing a bunch more Items against the complexity of adding DB access.

Anyway, here is one way to approach it.

Create your “database” Item as a String. Then you need to have some code that will read the data from that String into an ArrayList or HashMap (note we need to use these specific implementations so we get access to serialization). Also note that a HashMap is a dictionary, not an ArrayList which is more just an array instead of key/value mappings.

Then every time you update the “database” HashMap or ArrayList you need to reserialize the contents of your “database” to your “database” Item.

So you would need something like:

import java.util.HashMap
import java.io.StringBufferInputStream
import java.io.ObjectInputStream

var HashMap<String, String> database = null

rule "Populate database"
when
    val delay = if(DictionaryItem.state == NULL) 10 else 0
    createTimer(now.plusSeconds(delay), [ |
        if(DictionaryItem.state == NULL) {
            logError("Database", "Database is still NULL after 10 seconds!")
        }
        val ois = new ObjectInputStream(new StringBufferInputStream(DictionaryItem.state.toString))
        database = (ois.readObject() as HashMap)
    ])
end

There needs to be some error checking added but this gets arcoss the idea. Basically what we do is when OH starts we wait for a bit if restoreOnStartup hasn’t restored the state to the Database Item yet. After the wait we use the built in ability Java has to serialize Objects to String.

I’m not 100% certain that this will work as written. If you want to go down this path let me know and we can prove it out.

It also occurs to me that if you are truly wanting a dictionary type “database” we should probably just go ahead and use a Properties class instead. And then with a Properties class you could read and write the data to file in a standardized format that other tools would be able to use. I’ve written this up somewhere and can search for it if you want.

I’m pretty ambivalent about the concept of an ArrayList type Item. There are a whole lot of important questions about how such an Item would work.

  • what would it look like on the Sitemap?
  • how would it get saved in persistence?
  • how would I use it in Rules?
  • what different data types would it support?
  • how big can it get?
  • what commands/updates can it receive?
  • what happens when you send it a command?

I’m just not sure that an Item like this is supportable without a fundamental reworking of what an Item is and changes to each and every part of OH that touches Items. It’s a pretty big deal.

I will agree with @illnesse, coding the above might be easier to do in the JSR223 languages but you will still have to deal with the lack of an ListItem type.

Great Idea Rich to use a string item to persist the data !

Why dont make it really simple since we only have like 50 rules, rule name is in average 20 characters, then a long item of 5 digit or so, and finally a , to seperate values, this gives a string of around 1300 characters i.e no problem to handle for OH.

So we just make a global lambda:

ruleLogger(functionName as String){
    dictionaryDate=split(ruleLoggerDateString, ",")
    dictionaryDate(functioname)=new DateItem()
    ruleLoggerDateString.postUpdate(join(dictionaryDate,","))
}

or maybe its even faster if we can do some smart coding and make sure that when we restart the ruleengine, we sort the string item and then we can just take out the needed substring in ms and update it.

you probly will want to use Design Pattern: Separation of Behaviors since you can’t make a lambda global across rules files.

this is why I recommended using the HashMap or properties class to store the data and then serialize that to the string item. You will have better access to the data inside your rule to update, modify, and do calculations then you would have with just a regular string.

This is also one of the few places where I worry about performance. If your rules are constantly triggering you could be performing a pretty exspensive operation every time which might have a noticeable impact.

Though dealing with just the string might be more straight forward to code initially.