Habpanel: Restore previous dashboard from item value

Possibly related to Habpanel: Switch dashboard with item value

So i’ve started using the “switch dashboard with item value” functionality of Habpanel and it’s very useful. Primarily I use it to override the panels on a specific event (eg, security camera motion) and select the camera view dashboard.

I have several tablets around the house running different panels, and for simplicity I trigger them all from the same item value, what would be most useful however is the ability to unset this item (NULL/UNDEF probably) and have habpanel revert to the previous dashboard

This would allow a user to clear a security alert on one panel, and have all the others revert to their original status untouched.

Thoughts?

I don’t think that’s supported in HABPanel yet. What you can do, however, is set the item to another dashboard after you clear a security alert.

For example:

rule "security cleared"
...
then
    sendCommand(YOUR_DB_ITEM, 'myMainDb')
end

So when you clear the security alert, it (they) will all go back to ‘myMainDb’ dashboard.

Unfortuantly, this doesn’t work so well with multiple panels as you can’t restore wherever each panel was previously

Particularly after @ysc’s thoughts on if he would be interested to implement this / how much effort it would be. I suspect it’s a relatively simple code change in https://github.com/openhab/org.openhab.ui.habpanel/blob/master/web/app/services/openhab.service.js#L188

Untested by hopefully helpful pseudo code:

if (item.state && $rootScope.settings.dashboard_control_item === item.name) {
    if (item.state == 'NULL') {
        console.log('Restoring Dashboard as control item state changed to null');
        if ($currentDashboardId == $rootScope.temporaryRequestDashboard) {
            $location.url('/view/' + $rootScope.temporaryDashboardStore);
        }
    } else {
        console.log('Dashboard control item state changed, attempting navigation to: ' + item.state);
        $rootScope.temporaryDashboardStore = $currentDashboardId;
        $rootScope.temporaryRequestDashboard = item.state;
        $location.url('/view/' + item.state);
    }
}

The autoswitch calls a $location.url. What I would do, instead of storing a dashboard id temporarily, is to simply go ‘back’

    if (item.state == 'NULL') {
        $window.history.back();
    } else {
    ...

you would need to inject $window. The beauty of this is that, it will just go back to where it was. So if that panel was currently on an edit page, and entering stuff on an input box, it will go back to that edit page, with all the previously entered stuff restored.


and just for fun, what if I have a dashboard with id = ‘NULL’ :slight_smile:

Using back/the history stack definitely seems like a better idea

I’m not sure if you can determine the difference between an actual NULL and a string “NULL” on the openhab REST API, I’d hope that you can.

{
    thing: null
    otherthing: "null"
}

are two different representations

Hmmm, doesn’t look good
image

@luckymallari I guess there’s two ways of handling this (as undef would have the same issue)

Either: Decide that having a dashboard called null/undef is silly and invalid (as you would generate persistence issues with this as well)
or
Have a secondary check which only returns down the history stack if the item.state doesn’t correlate to a valid dashboard (this would enable you to use “any” value to return, but could cause further issues if you changed a dashboard name / ended up with items/habpanel slightly out of sync)

or just $$NULL$$
…anything that doesn’t make sense :slight_smile:

I’d rather have HABPanel keep the item in sync with the current dashboard (i.e. updating the item’s state when the dashboard changes), which it does not do currently, this way you could implement any behavior you wish using associated items and rules on the server, something like this:

Group gCurrentDashboards
Group gPreviousDashboards

String Panel1_CurrentDashboard (gCurrentDashboards)
String Panel1_PreviousDashboard (gPreviousDashboards)

String Panel2_CurrentDashboard (gCurrentDashboards)
String Panel2_PreviousDashboard (gPreviousDashboards)

...
rule "store previous dashboard"
when
    Panel1_CurrentDashboard changed or
    Panel2_CurrentDashboard changed or
    Panel3_CurrentDashboard changed or
    (...)
then
    val previousDashboardItem = gPreviousDashboards.members.findFirst[i| i.name == triggeringItem.name.split("_").get(0) + "_PreviousDashboard"]
    previousDashbordItem.postUpdate(previousState)
end

rule "restore previous dashboards"
when
    gCurrentDashboards received update "Restore"
then
    gCurrentDashboards.members.forEach[item|
        val previousDashboardItem = gPreviousDashboards.members.findFirst[i| i.name == item.name.split("_").get(0) + "_PreviousDashboard"]
    item.sendCommand(previousDashboardItem.state.toString)
end

You could then send commands to the group to change all current dashboards at once or “Restore” to restore the previous ones.

if that’s the case, it would be better to have each Panel its own unique ID and saved onto localstorage, so that OH can send a command to each individual panel:

sendCommand(habPanelCommandItem, "{ to: 12345, command: ...}")

and Habpanel will handle command if to matches its id. Having no to is an implicit all

@ysc the principal of having it managed at the oh level is ok, however as soon as two panels are opened at once you would end up with massive item conflicts with each one trying to keep in sync, if you had two people at once this would cause bedlam. If not you would need to manage the panel config locally for each panel which makes adoption difficult

E.g.:
A panel config has multiple dashboards, one for each room in the house
A guest arrives in the house and installs the panel on their tablet. Without knowledge of the system this tablet either wouldn’t sync to the item commands or would try to copy the behaviour of other tablets. In the situation where you have multiple tablets (in different parts of the house) each tablet syncing becomes a pain as all tablets display where the last used tablet was, rather than where is useful for their area.

In my example above, the panel reporting back to the item would be unuseable, whereas the back functionality allows a basic restore function.
I guess you could support both in someway, but I certainly viewed this as more useful for broadcast items, not single tablet control