ESP8266 label change

Hey openHAB Community!

I have a question regarding ESP’s, MQTT and labels. I currently have a automatic curtain closer, but I run into a problem with labels.

I have a switch item in my items file (see below). Whenever I hit the Open button, a mqtt message is sent and the motor spins. However, this takes a little while and during that time I should not send another command (else the curtains close/open twice). Therefore, I want the text in the button to change to Opening… or Closing… accordingly.

Switch  Robo500  "Robo 500"   <siren> {mqtt=">[mosquitto:esp/test:command:ON:Open]"}

And, I want to change the text in the button to Open or Close, accordingly. Lastly, I would like to open multiple curtains at the same time (thus one button that can ‘power’ multiple buttons). Is this possible, and if so how?

Thanks in advance!

Are you using a sitemap or HABpanel?

Sitemap!

And define:

Also, how does OH knows when the curtain is finally opened, closed?

I’m exploring options for raising a DIY roman shade. Can you say what you are using? It might be useful for me.

Anyway, to your questions. Easiest answers first:

You can put all your Items representing each curtain into a Group and put the Group on your sitemap/habpanel as a Switch and any command sent to the Group will get forwarded to all the members of the Group.

The other part is more challenging. First I’ll assume we are using a sitemap based UI and not HABPanel because I don’t think HABPanel supports something akin to the visibility tag.

You will need to create a new Item that represents the state of the curtains: OPEN, OPENING, CLOSING, CLOSED. Make it a String Item since there are four states and let’s call it Robo500_State.

Next you need to create a proxy Item that you put on your sitemap. Do not put the Robo500 on your sitemap. Let’s call the proxy Item Robo500_Proxy.

Now you need a Rule that takes the command to the proxy Item, updates the state Item and forward’s the right command to the Robo500 Rule.

rule "Robo500"
when
    Item Robo500_Proxy received command
then
    if(Robo500_State.toString == "OPENING" || Robo500_State.state.toString == "CLOSING") return; // ignore commands if the curtains are moving

    // Update the State Item
    val newState = if(Robo500_State.toString == "OPEN") "CLOSING" else "OPENING"
    Robo500_State.postUpdate(newState)

    // Send the command to the motor
    Robo500.sendCommand(ON)

    // Set a Timer to set the state back after the amount of time if takes for the curtains to fully open/close
    createTimer(now.plusSeconds(???), [ |
        Robo500_State.postUpdate(if(Robo500_State.state("OPENING")) "OPEN" else "CLOSED")
    ])
end

I just typed in the above. I’m sure there are errors and edge cases not handled (e.g. what if Robo500_State is NULL?).

Finally, you need to use the visibility tag on the sitemap to show a separate line based on the State Item.

Switch item=Robo500_Proxy mappings=[ON=Open] visibility=[Robo500_State == CLOSED]
Switch item=Robo500_Proxy mappings=[ON=Close] visibility=[Robo500_State == OPEN]
Text item=Robo500_Proxy label="Robo500 is opening" visibility=[Robo500_State == OPENING]
Text item=Robo500_Proxy label="Robo500 is closing" visibility=[Robo500_State == CLOSING]

Again, I just typed this in and there may be errors.

4 Likes

I was just still gathering the info to get to that!!

Ah thanks! I’ll try this tonight. Looking at the code, this does not require a state sent by the ESP that the curtains are open, correct? The esp does send a state now after the code is done, but I did not (yet) know how to implement this.

regarding my setup: i have those IKEA roller blinds, removed the spring inside and replaced it with a 3d printed adapter. This adapter is connected to a stepper motor, that is driven by the DRV8825 stepper driver. That driver is connected to the ESP.

Thanks a lot, bot of you.

Could you open a new Thread with details of your set-up please.
Roller shutter are a pain. Commercial solutions are very expensive and there are a lot of tinkerers and DIYers in the community who would be interested in your set-up.

Sure! Its currently still in an early stage, but I’ll make a thread for how far I am now. I want to create a single PCB in a plug and play box, maybe even selling kits.

That is correct. I made the assumption that there was no feedback since you didn’t mention it.

If it does send the state, you can link/bind the State Item to that topic and remove the timer.

Thanks!

Thanks all for your help, I’ll try to set the whole thing up tonight. I’ll post an update as soon as I’m done!

I run into a problem: no switch is visible on my basicui.

Items file:

String Robo500_state "OPEN"
Switch Robo500  "Robo500"   <siren> {mqtt=">[mosquitto:esp/test:command:ON:Open]"}

Switch Robo500_proxy "Robo500_proxy" <siren>

Sitemap file:

sitemap Robo500 label="Robo500" {
        Frame label="Robo500" {
                Switch item=Robo500_proxy mappings=[ON=Open] visibility=[Robo500_state == CLOSED] icon="light"
                Switch item=Robo500_proxy mappings=[OFF=Closed] visibility=[Robo500_state == OPEN] icon="light"
        }
}

I copied the rule file exactly, but I think there are some mistakes. However, I can’t find them:

rule "Robo500"

when
    Item Robo500_proxy received command
then
    if(Robo500_state.toString == "OPENING" || Robo500_state.toString == "CLOSING") return; // ignore commands if the curtains are moving

    // Update the State Item
    val newState = if(Robo500_state.toString == "OPEN") "CLOSING" else "OPENING"
    Robo500.postUpdate(newState)

    // Send the command to the motor
    Robo500.sendCommand(ON)

    // Set a Timer to set the state back after the amount of time if takes for the curtains to fully open/close
    createTimer(now.plusSeconds(10), [ |
        Robo500_state.postUpdate(if(Robo500.state.state("OPENING")) "OPEN" else "CLOSED")
    ])
end

Can anybody spot whats wrong? Thanks in advance.

EDIT: after trying with numbers for the Robo500_state, then the switch is visible. Is there a fault in the string compare?

If you can’t see them in the UI it means the visibility if off OR that the visibility syntax is wrong
Fix the sitemap first
According to the docs, there are no spaces in the vidsibility conditions
And the mappings for string must have ""
Also the parser doesn’t like things to be in the “wrong” order. It may work but it may not so put the icon parameter after the item.

sitemap Robo500 label="Robo500" {
        Frame label="Robo500" {
                Switch item=Robo500_proxy icon="light" mappings=[ON="Open"] visibility=[Robo500_state==CLOSED]
                Switch item=Robo500_proxy icon="light" mappings=[OFF="Closed"] visibility=[Robo500_state==OPEN]
        }
}

Hmm, after using your sitemap no change, I still can’t see the switches. What else could be wrong? Something in the rule file?

Maybe your visibility control Item doesn’t have any value yet i.e. NULL

Just put a plain simple version on your sitemap to try things out

        Frame label="Robo500" {
                Switch item=Robo500_proxy 
                Switch item=Robo500_proxy icon="light" mappings=[ON="Open"] visibility=[Robo500_state==CLOSED]
                Switch item=Robo500_proxy icon="light" mappings=[OFF="Closed"] visibility=[Robo500_state==OPEN]
           }
1 Like

You have several Typos in your rule:

Line 10:

Robo500.postUpdate(newState)

should be

Robo500_state.postUpdate(newState)
       ^^^^^^

Line 17:

Robo500_state.postUpdate(if(Robo500.state.state("OPENING")) "OPEN" else "CLOSED")

should be

Robo500_state.postUpdate(if(Robo500_state.state("OPENING")) "OPEN" else "CLOSED")
                                   ^

That is the problem. I removed the visibility from one item so I can change the value once and added it back again. The value then changes from NULL to open and it works fine after that. How can I account the NULL value the best?

@Udo_Hartmann I found those mistakes and fixed them. Haven’t tested it completely yet, but it seems to work okay!

What would you like to do about it? NULL isn’t just an inconvenience, it is telling you that OpenHAB has not determined a sensible value for that Item.

If there is some way for OH to find out what state it should be, there’s one avenue to persue.

Or perhaps it’s indeterminate until the first command is issued. You could rewite your rule and sitemap to deal with that case sensibly (question mark icon etc.?)

Sometimes remembering the last valid state long-term is good enough, and you could look into persistence with ‘restore on startup’

The log says it changes the value from NULL to Open, so its NULL at the start.

I can make the ESP-module send out a state (it does this after every closing/opening, to indicate it is open/closed), but since I only need the value for starting up the system (so, one time) a standard value may be easier. I have in the items file the following line:

String Robo500_state "OPEN" 

but the OPEN state is not the default value, it is NULL. How can I give it a default value that is not NULL?

I also have a followup question: I have a switch and a separate text item that says its opening/closing. Is there any way to have this in the button? So that the button changes from Open → opening → Close, but that I can’t press the opening button (or it does nothing)? Do I need to create separate switches (same as the open/close) and separate rules?

That’s not a state, it’s a label as visible on the sitemap. You cannot set the state of an Item in the xxx.items file.

You can set (postUpdate) the state of an Item from a rule. You can trigger a rule to run when ‘System started’.

You can use persistence to ‘remember’ the state of an Item while OpenHAB is off-air. And then use ‘restore on startup’ to recover that remembered state back to a current Item.

Out of interest, what happens if someone operates the curtains by hand, can OpenHAB know?