Item status values not correct when used in rules in OH3.1

  • Platform information:
    • Hardware: RPi3
    • openHAB version: migration from OH2.4 to OH3.1
  • Issue of the topic: Item status values not correct when used in rules in OH3.1

I’m migrating my OH2.4 setup to OH3.1 but I have an issue with some of my rules. When I use item states in my rules these values are not always correct in the output of the rule.

When one of my items received a command, the rule triggers and send a MQTT message which include the state of the item.
This works fine in OH2.4 but isn’t working well in OH3.1.
In OH3.1 the send MQTT messages includes most of the time the old/previous item state and not the new one. This is verry annoying :woozy_face:.

For example when I change my item Dimmer Allegretto_zone1_vol via the app or basic UI from value 20 to value 70 then in OH2.4 a MQTT message with value 70 is send. But in OH3.1 this MQTT message contains the value 20 (the old/previous value). When I then change the value from 70 to 50 the send value in OH3.1 is 70 and not 50!

See my items and rules below:

Items:

Dimmer Allegretto_zone1_vol "music zone 1 volume [%d %%]"
Switch Allegretto_zone1_mute "music zone 1 on/off"

Rules in OH2.4:

Rule to change the volume:

rule "volume zone 1"
	when
		Item Allegretto_zone1_vol received command
	then
		var VOL = (Allegretto_zone1_vol.state as Number).intValue
		if (VOL == 100){
			VOL = VOL - 1
		}	
		Allegretto_MQTT_command.sendCommand("*VOL,99,99,1,2," + String::format("%02d",VOL) + ";")
	end

Rule to mute:

rule "mute zone 1"
	when
		Item Allegretto_zone1_mute received command
	then
		if (Allegretto_zone1_mute.state == ON) Allegretto_MQTT_command.sendCommand("*MUT,99,99,1,0,00;")
		else if (Allegretto_zone1_mute.state == OFF) Allegretto_MQTT_command.sendCommand("*MUT,99,99,1,1,00;")
	end

Rules in OH3.1:

Rule to change the volume:

rule "volume zone 1"
	when
		Item Allegretto_zone1_vol received command
	then
		var VOL = (Allegretto_zone1_vol.state as Number).intValue
		if (VOL == 100){
			VOL = VOL - 1
		}	
		val mqttActions = getActions("mqtt","mqtt:broker:MQTTbroker")
		mqttActions.publishMQTT("Allegretto/Commando", "*VOL,99,99,1,2," + String::format("%02d",VOL) + ";")
	end

Rule to mute:

rule "mute zone 1"
	when
		Item Allegretto_zone1_mute received command
	then
		if (Allegretto_zone1_mute.state == ON){
			val mqttActions = getActions("mqtt","mqtt:broker:MQTTbroker")
			mqttActions.publishMQTT("Allegretto/Command", "*MUT,99,99,1,0,00;")
		}
		else if (Allegretto_zone1_mute.state == OFF){
			val mqttActions = getActions("mqtt","mqtt:broker:MQTTbroker")
			mqttActions.publishMQTT("Allegretto/Command", "*MUT,99,99,1,1,00;")
		}
	end

What is the issue here?

use „changed“ instead of „received command“

see

Your problem is that the bus isn’t updated yet when the rule fires. Parallel threads executing before each other. Don’t use Allegretto_zone1_vol.state. Use receivedCommand. There are times you may have to do some weird things like Integer::parseInt(receivedCommand.toString) to get what you want, but it works. receivedCommand gets the info you’re looking for before the bus has time to update and make a .state work.