Multi State Switches

Hi,

i want to implement a multi-state switch e.g. a switch which can be ON, OFF or AUTO. Auto behaviour should be driven by a rules file.

Is this possible in the current version? Read thru topics on the forum, however, could not find an exact match - hence this post to seek guidance.

  • Sundeep

I think most people would implement a number type item, then you can assign whatever meaning you want to different values.

Hi Sundeep,

If I understand you question right, I have done something similar with my garage doors. They can have three states. Open, Closed or Ajar. In my sitemap only the active state is shown using ‘mappings’ and ‘visibility’. My ‘ajar’ state is driven by a rule as this state is a combination of the two contacts indicating closed or open.

This is how I have done, hope it helps you or gives you an idea of how to make your own solution :slight_smile:

BR Søren

Items - the ‘ajar’ contact is a dummy/proxy contact (has no binding attached):

Contact Garage_Port_1_State_Open		"Status: Åben | Port 1"	   	        <garagedoor>	    	(Garage) 	{ihc="<0x19f15a"}
Contact Garage_Port_1_State_Ajar		"Status: På klem | Port 1"		<garagedoor>		(Garage)
Contact Garage_Port_1_State_Closed		"Status: Lukket | Port 1"		<garagedoor>		(Garage) 	{ihc="<0x19f35a"}

Sitemaps:

Switch item=Garage_Port_1_State_Open label="Status | Port 1" icon="garagedoor-open" mappings=[OPEN="Åben"] visibility=[Garage_Port_1_State_Open=="OPEN"]
Switch item=Garage_Port_1_State_Ajar label="Status | Port 1" icon="garagedoor-ajar" mappings=[OPEN="På klem"] visibility=[Garage_Port_1_State_Ajar=="OPEN"]
Switch item=Garage_Port_1_State_Closed label="Status | Port 1" icon="garagedoor-closed" mappings=[OPEN="Lukket"] visibility=[Garage_Port_1_State_Closed=="OPEN"]

Rule:

import org.openhab.core.library.types.*
import org.openhab.core.persistence.*
import org.openhab.model.script.actions.*

rule "Set GaragedoorAjar Flag - Port 1"
when
    Item Garage_Port_1_State_Closed changed or
    Item Garage_Port_1_State_Open changed
then
    if(Garage_Port_1_State_Closed.state == CLOSED && Garage_Port_1_State_Open.state == CLOSED) Garage_Port_1_State_Ajar.sendCommand(OPEN)
    else Garage_Port_1_State_Ajar.sendCommand(CLOSED)
end

Hi Soren, thanks for the revert.

My requirement is slightly different, let me elaborate. I need to implement a switch which can be set to one of three modes : ON, OFF, AUTO.

If ON: via an MQTT binding, an ON command is relayed to a device
If OFF : via MQTT binding, an OFF command is relayed to a device
if AUTO : a rule needs to execute periodically to say check for temperature and if above a threshold, send an ON command and if not, SEND an OFF command. I want this Rule to be executed if and only if the switch is set to AUTO and not is it is either ON / OFF.

I hope I have been able to make my query a bit clearer …

  • Sundeep

thanks, is that the only option or are their others ?

You could use a number Item with mapping in the UI:
.items

Number My3stateSwitch "State is [MAP(3states.map):%s]"

.sitemap

Switch item=My3stateSwitch mappings=[0="OFF",1="ON",2="AUTO"]

transformations/3states.map

0=OFF
1=ON
2=AUTO

.rules

rule "3state"
when
    Item My3stateSwitch changed
then
    switch (My3stateSwitch.state as DecimalType) {
        case 0 : MyItem.sendCommand(OFF)
        case 1 : MyItem.sendCommand(ON)
        case 2 : {
            //put auto code here or trigger another rule to execute auto code
        }
    }
end

Of course, since the UI draws three different buttons you don’t need the 3state.map and the dynamic label for the switch, it’s a matter of taste (is this correct? Maybe there is an idiom)

6 Likes

Hi Sundeep,

I’m sorry, that I’m not able to help with. I’m still very much in the learning process with openHAB.

BR Søren

Soeren, same here - trying to figure out the great application!!:slight_smile:

Udo, this is looking great and its exactly what i needed. Thank you !!

Udo, will persistence apply to .item Number My3stateSwitch or .sitemap Switch item=My3stateSwitch? i cant see to get it to persist, maybe doing something incorrect ?

persistence is always about Items, you have to define the persistence in *.persist, see here

For the Number Item you can use any persistence service you want.
For getting the right state at startup you can use mapdb, this will save the last state, and with restoreOnStartup strategy openHAB will restore the state at startup :wink: mapdb will never grow (per item).
If you want to have more information (e.g. you have a temperature item and want a chart of it’s state through the last 48 hours you should use rrd4j with everyMinute strategy, so this state will be saved every minute. The chart servlet then can build the chart from this data table. rrd is round robin, so the data table will never grow, too, but change the time accuracy for old data (save every minute, but also generate average values for old values, delete obsolete per-minute-values and so on) This isn’t too bad, because the resolution of a chart will decrease the more, the longer the time period is.
If you want accurate data forever, you will have to use a database for persistence, like mysql, db4o, InfluxDB and so on.

I tried mysql, and have got persistence to work. However, the restoreOnStartup strategy is not working. Tried the workaround from MySQL & restoreOnStartup : KO · Issue #1194 · openhab/openhab1-addons · GitHub, however, that is not working either.

One more issue : getting following WARN : 2016-06-02 20:13:30.513 [WARN ] [t.i.s.MapTransformationService] - Could not find a mapping for ‘-’ in the file ‘3states.map’. could you point me on how to debug this problem?

Ah, yes. simply add a line

- = -

to the file 3states.map, this is due to the fact, that the item is not initialized. openHAB tries to lookup the mapping and doesn’t find an appropriate line in the mapping file.

Do you see any database entry for your item in MySQL?
First there should be an entry in the table items with the name of the item and the name of the data table associated to the item.
Secondly there should be the table with entries for your item.
Maybe the MySQL connection isn’t up in time to restore the state. This is the downside of the strictly asynchronous design of openHAB.

adding -=- sorted that issue.

On the other one, yes all items are getting populated in mySQL, however, state is not getting restored even after using the touch script on mysql.persist

That’s strange, it’s working for me with mysql. What’s your mysql.persist like?

Strategies {
//default = everyChange
everyMinute : “0 * * * * ?”
default = everyMinute
}

Items {
* : strategy = default, restoreOnStartup
}

tried with both everyChange and everyMinute - however, restoreOnStartup does not work using mySQL. However, have got it to work using mapDB now.

I’m looking to do almost the exact same thing, except my states are -1, 0, 1.
My 3states.map looks like this:
-1=Off 0=Auto 1=On
but I get `[WARN ] [t.i.s.MapTransformationService] - Could not find a mapping for ‘-’ in the file ‘3state.map’'
in my run.log.

I think I found that the message above is generated when the value is unknown at startup. I added -:unknown to the map file and it’s now gone. I’d like to move the Switch definition from the Sitemap into an item file, but I’m at a loss on the right syntax. I can’t find documentation on the usage of mappings= to understand whether I can use it in that context.

In fact, you can’t get the mappings-setting to the items file, this is sitemap-only.

Is there a way to have it shown in a group? My sitemap looks like this, but the Switch shows up at the top level; I’d like it in the Outdoors group:
Frame { Group item=gGF label="Main Floor" icon="groundfloor" Group item=gUpstairs label="Upstairs" icon="firstfloor" Group item=gBasement label="Basement" icon="cellar" Group item=GF_Outdoor label="Outdoors" icon="garden" Switch item=PondMode label="Pond mode" mappings=["-1"="Off",0="Auto",1="On"] Group item=Holiday label="Holiday" Group item=Temperature label="Temperatures" Text item=alarmPanelDisplay icon="garden" Group item=gAlarm label="Alarm System" icon="garden" }