MQTT Switch on/off with custom state value

Using MQTT to change speed on a ceiling fan.
I’m using Switch to be able to use buttons in the GUI.

However I can’t get the buttons to recognize what speed is selected. Guessing it has something of how I’m mapping the MQTT in parameter. For each button if it’s 1,2,3,4,5,6.

So in the GUI when pressing speed 2, I want to button to be ‘selected’.


Switch FanSpeed1 "Speed 1" {mqtt="

    // First i send to my broadlink to play a command

    // Send to keep track what speed is active

    // Listen if value is 1, then button is on


// next button for another speed
Switch FanSpeed2 "Speed 2" {mqtt="


Switch item=FanSpeed1 label="Speed" mappings=[ON="1"]
Switch item=FanSpeed2 label="Speed" mappings=[ON="2"]
Switch item=FanSpeed3 label="Speed" mappings=[ON="3"]
Switch item=FanSpeed4 label="Speed" mappings=[ON="4"]
Switch item=FanSpeed5 label="Speed" mappings=[ON="5"]
Switch item=FanSpeed6 label="Speed" mappings=[ON="6"]

I’ve made it work for my house state HOME, AWAY, BEDTIME, NIGHT. I did this with MAP(). However I needed to create a new map for each of the states and that seems like a PIK (pain in keyboard).

Switch HouseModeHome "HOME" {mqtt="

This is overly complicated.
Use a Number item for the speed
You will need to install the MQTT action

Number FanSpeed "Fan Speed [%d]"

In the sitemap, you can use a selection

Selection item=FanSpeed mappings=[1="1", 2="2", 3="3", 4="4", 5="5", 6="6"]

Or a setpoint

Setpoint item=FanSpeed minValue=1 maxValue=6 step=1

Then a rule:

rule "FanSpeed"
    Item FanSpeed changed
    if (FanSpeed.state == "NULL") return; // If NULL do nothing
    val String FSString = Integer::parseInt(FanSpeed.state as DecimalType)
    val topic = "broadlink/fans/livingroom/speed-" + FSString
    publish("mqtt", topic, "ON")
1 Like

Had some thought of only using openhab as a ‘connector’ for device and then use MQTT and node-red with all the rules. But You are right @vzorglub. This is a clean solution for the problem.

I’, running OH 2.2 and needed to change this:

val String FSString = Integer::parseInt(FanSpeed.state as DecimalType)
val topic = "broadlink/fans/livingroom/speed-" + FSString


val topic = "broadlink/fans/livingroom/speed-" + FanSpeed.state

Didn’t like the Integer::parseInt(FanSpeed.state as DecimalType)

Yes, there is a thread called node-red as an alternative rule engine.
On my phone right now so I don’t have the direct link.

I didn’t use the second option in case the toString returned the decimal point value of the number so I forced an integer.