[SOLVED] Problem restoring Switch item from influxdb

I’m trying to restore a Switch item from my influxdb persistence.
I persist everything.
In Grafan, I can check that the item is in fact persisted: (HouseGuests)

item:

Switch HouseGuests (opStates)

rule:

rule "System start"
when
        System started
then 
    logInfo("System", "System started (or a rule changed)");    
    HouseGuests.lastUpdate("influxdb")
    logInfo("System", "HouseGuests.state=" + HouseGuests.state)
end

log:

2018-10-18 19:46:45.030 [INFO ] [clipse.smarthome.model.script.System] - System started (or a rule changed)
2018-10-18 19:46:45.102 [INFO ] [clipse.smarthome.model.script.System] - HouseGuests.state=NULL

The state is always NULL regardless of OFF (0) or ON (1) is persisted. (restarting OH2 when testing).

Any pointers to what I’m doing wrong?

I don’t think that does what you think it does. It doesn’t change the Item state, it fetches a historic timestamp from db.

If you do not want to auto-restore, I believe you could fetch item.previousState(), extract a state, and item.postUpdate with that.

Thank you.
I misunderstood the .previousState() as just that, the previous state and not the last persisted state.
Silly me.

This works:

HouseGuests.postUpdate(if (HouseGuests.previousState().state==ON) ON else OFF)

and for some reason this don’t

HouseGuests.postUpdate(HouseGuests.previousState().state)

Why don’t you use the restoreOnStartup facility in the persistence service?

    HouseGuests : strategies = everyChange, restoreOnStartup

Guess I could do that, but currently I only need a handful of items.
How will restoreOnStartup handle the case where OH starts before persistence?
I see that is the case for me now when restoring explicit items.

(from what I know)… Item state restoration is fired with a couple of (milli)seconds of delay after startup.

Following System started, all item states will be initialized as NULL and then will be updated either from persistence and/or from live collected data.

You may want to add a timer (not a delay) to your startup rule to make sure that state restoration is performed correctly.

I think @rlkoshak has posted a solution around this startup delay timer somewhere but I can’t find it now

I was planning on using an expire timer (from the expire binding)

I had my system up and running for over a year without persistence and quite recently added influxdb and Grafana. Mainly for generating graphs, but now when I’m introducing two new operating states HouseGuest and Alarm (any motion sends me a FB chat message) I wanted to persist and restore those 2.

Thanks for your input so far.

this one can’t help you within a rule
this is to change the state of an Item after a defined period
for the rule you need either a timer or a delay line

Are you sure?
I could just define a virtual Switch that expire sets when timing out, and trigger a rule that will do the restore?

It’s at the bottom of the persistence docs

You can actually somewhat infer when it occurs by watching the logs. The restoreOnStartup cannot start until some time (milliseconds) after you see “Loading model mapdb.persist” (replace mapdb.persist with the database you are using for restoreOnStartup) in openhab.log. Most of the time on my system this occurs after the .items are loaded.

I don’t recall writing something for this in particular but I’m constantly coming across posts I’ve written that I have no memory writing. It would just be a standard timer as you describe I think.

Indeed you can do a timer like that. See Design Pattern: Expire Binding Based Timers for a writeup.

:+1:

Just to give a detailed example of an implementation of Workaround 1 in the doc.
(remember to install the expire binding)
.items

Switch vPersistRestoreTimer { expire="15s,command=OFF" }

.rules

rule "System start"
when
        System started
then 
    logInfo("System", "System started (or a rule changed)");    
    vPersistRestoreTimer.sendCommand(ON) // start timer
end

rule "vPersistRestoreTimer expired"
when
     Item vPersistRestoreTimer received command OFF 
then
    logInfo("System", "vPersistRestoreTimer expired")
    HouseGuests.postUpdate(if (HouseGuests.previousState().state==ON) ON else OFF)
end

And finally I want to advertise for the Member of feature, that really makes the handling of grouped items a breeze. For instance, if you want to log and handle events from a group of Switches:

.items

Group:Switch groupSwitches
Switch All                        (groupSwitches) 
Switch AllLR                      (groupSwitches)
Switch AllDR                      (groupSwitches)
Switch AllK                       (groupSwitches)

.rules

rule 'groupSwitches changes'
when Member of groupSwitches received command OFF or
     Member of groupSwitches received command ON
then
    logInfo("groupSwitches", triggeringItem.name + " State=" + triggeringItem.state)

    switch(triggeringItem.name) {
        case "All": {
            sendCommand(lights, if (All.state==ON) ON else OFF);
        }
        case "AllLR": {
            sendCommand(livingRoom, if (AllLR.state==ON) ON else OFF);
            AllLR.state = if (AllLR.state==ON) ON else OFF;
        }
        case "AllDR": {
            sendCommand(diningRoom, if (AllDR.state==ON) ON else OFF);
            AllDR.state = if (AllDR.state==ON) ON else OFF;
        }
        case "AllK": {
            sendCommand(kitchen, if (AllK.state==ON) ON else OFF);
            AllK.state = if (AllK.state==ON) ON else OFF;
        }
    }
end

This can really cut down on the number of rules :slight_smile: