[SOLVED] Get state from MQTT (item) on Tasmotized Sonoff Mini device and use it in a rule with time as well

  • Platform information:
    • Hardware: Raspberry Pi 3
    • OS: Raspbian 9 (stretch)
    • Java Runtime Environment: openjdk version “1.8.0_232”
      OpenJDK Runtime Environment (build 1.8.0_232-8u232-b09-1~deb9u1-b09)
      OpenJDK Client VM (build 25.232-b09, mixed mode)
    • openHAB version: 2.5.0~S1742-1

I am trying to do something very basic. Using a PIR I am activating a light using Sonoff Mini and deactivating after 10 seconds. So that’s working without any problems.

Now, what I want to do is to ONLY turn “ON and OFF” the light if the state is OFF or NULL.

So for that I have this rule:

val actions = getActions("mqtt","mqtt:systemBroker:embedded-mqtt-broker")

rule "Sensor Luz Entrada"
when
   Item Sensor433mhz changed
then
   switch Sensor433mhz.state {
      case "79E006": {
         actions.publishMQTT("cmnd/LuzEntradaFrente/POWER", "ON")
         Thread::sleep(10000)
         actions.publishMQTT("cmnd/LuzEntradaFrente/POWER", "OFF")
      }
   }

   if(Sensor433mhz.state.toString !="") {
      Thread::sleep(500)
      Sensor433mhz.postUpdate("")
   }
end

And to make it work as I wanted, I added this condition right after getting inside case:

if (LuzEntradaFrente.state == OFF || LuzEntradaFrente.state == NULL) { ...

Problem is, it did not worked. :frowning:

On my .items file I have this:

Switch Luz_Entrada_Frente "Luz Entrada Frente" <light> (iluminacao) ["Lighting"] { mqtt=">[embedded-mqtt-broker:cmnd/LuzEntradaFrente/POWER:command:ON:1],
>[embedded-mqtt-broker:cmnd/LuzEntradaFrente/POWER:command:OFF:0],
<[embedded-mqtt-broker:stat/LuzEntradaFrente/POWER:state:default]"}

I don’t know if somehow this is related with my problem or not, but I cannot have state updated on the APP nor online in Paper UI whenever I press the button manually on my Sonoff Mini.

Can someone help me out here?

Thanks!

EDIT

I am now able to update in realtime my manual switches. So if I click a Sonoff (or a switch connected to it) I immediately see OH updated with it. These are my configurations in Paper UI to achieve that:

Then I already tried in my rule to use this:

var LEF = LuzEntradaFrente.state.toString

Also tried directly here:

if (LuzEntradaFrente.state.toString == "OFF" || LuzEntradaFrente.state.toString == "NULL" || LuzEntradaFrente.state.toString == NULL) { ...

Still nothing…

Your item definition is using the mqtt version 1 syntax, however you have setup everything else for the version 2 syntax!
You can either delete the complete { } part of the item definition and link the item via PaperUI OR
copy the required channel definition from PaperUI and put it in like { channel=…}.

Some other hints:
Why does your rule trigger on each change Sensor433mhz, IMHO triggering on the change to ON will make your life easier.
Why not use the expire binding in order to switch off the ligth instead of using an ugly thread.sleep?

I thank you for your help, but regarding the item, since I’ve successfully put it working using Paper UI, I have deleted all { } part. Now I see instantly update on the APP whenever I click manually on the switch, which is perfect.

Triggering on change to ON, what do you mean with that? I want to detect whenever “something” is detected on the Sensor (which is a Sonoff Bridge) and then I have multiple cases to check for the code and do something, therefore that’s why I have it like that.

Regarding the Expire functionality, as far as I could see that’s applied in .items not in .rules, am I right?

Because if that’s the case, then this does not do what I want because I want to be able to activate the device manually and leave it on for as long as I want AND I want it to turn ON whenever the status is OFF.

Afterwards I will also check if the current time is “night” or “day” to be able to turn it ON only at night.

Please don’t use Thread:sleep() for long time (i.e. more than 500 Milliseconds). That’s what timers are for.

So, regarding the timer, I’ve set it like so but it does not work:

val actions = getActions("mqtt","mqtt:systemBroker:embedded-mqtt-broker")
var Timer offTimer = null

rule "Sensor 433mhz - Sonoff Bridge"
when
   Item Sensor433mhz changed
then
   switch Sensor433mhz.state {
      case "79E006": {
         actions.publishMQTT("cmnd/LuzEntradaFrente/POWER", "ON")
         offTimer = createTimer(now.plusSeconds(10), [|
            actions.publishMQTT("cmnd/LuzEntradaFrente/POWER", "OFF")
            Alexa_Sala.postUpdate("Olá, bem vindo a casa!")
            if(offTimer != null){
               offTimer = null
            }
         ])
      }

   }

   if(Sensor433mhz.state.toString != "") {
      offTimer = createTimer(now.plusSeconds(10), [|
         Sensor433mhz.postUpdate("")
      ])
   }
end

But regarding the main question, how can I get a state of an item/thing inside a rule?

Thanks! :slight_smile:

More please.

I’m sorry, I didn’t get what you mean.

Do you mean more code? In my rules I don’t have more code, this is the only rule for the moment.

Regarding the item I have shown above the code I had, now it’s only this part:

Switch Luz_Entrada_Frente "Luz Entrada Frente" <light> (iluminacao) ["Lighting"]

Since I was able to make it work only via Paper UI, I simply removed the code for MQTT since that was really complex due to the lack of examples on the documentation of OH.

Can I, please, have some more help on the main question of this topic?

Or was your “More please” related to a need for me to beg for help? :smiley: (just joking)

More for “more detail”. “Doesn’t work” is a bit non-specific.

Things don’t have states.
To get the state of an Item in a rule,
myItemName.state
but you’re already using that.

Perhaps the diagnostic tool you need is to get visibility of the state at the time of running the rule?
logInfo("test", "the state is " + myItemName.state.toString)
Sprinkle strategically through your rule and look for results in openhab.log

1 Like

THANK YOU SO MUCH FOR YOUR PATIENCE! :smiley:

Thanks to your help I did it. I’m so happy. This was totally my mistake (obviously) because I was using the Thing ID instead of the Item ID. My oh my. :upside_down_face:

So instead of “LuzEntradaFrente”, which is the Thing ID, I should have used “Luz_Entrada_Frente” which is the proper Item ID.

For future reference for others, here’s my working code with proper time working as well.

val actions = getActions("mqtt","mqtt:systemBroker:embedded-mqtt-broker")
var Timer offTimer = null
val Number hours = now.getHourOfDay

rule "Sensor 433mhz Sonoff Bridge"
when
   Item Sensor433mhz changed
then
   switch Sensor433mhz.state {
      case "79E006": { 
         if ((hours > 19 || hours < 2)
             && Luz_Entrada_Frente.state.toString !== "ON") {
            actions.publishMQTT("cmnd/LuzEntradaFrente/POWER", "ON")
            offTimer = createTimer(now.plusSeconds(10), [|
               actions.publishMQTT("cmnd/LuzEntradaFrente/POWER", "OFF")
            ])
         }
      }
   }

   if(Sensor433mhz.state.toString !== "") {
      offTimer = createTimer(now.plusSeconds(2), [|
         Sensor433mhz.postUpdate("")
      ])
   }
end

I love clean coding! :smiley:

JFYI - you don’t need the if(offTimer !== null) inside the timer. actually you don’t need it in any place in question of setting the var to null :wink: this test is only necessary for canceling or rescheduling timers.

1 Like

Thanks for the advice, code cleaned. :smiley: