MQTT publish failed

I am using OH2.4 with MQTTv2

I have a script (discussed in a previous topic) that switches a siren on/off until manually stopped. I have been working on this for a while now and it all seems to be fine however every once and a while OH fails with MQTT publish to /topic failed!

I have to restart OH service and it’s all good. I initially put this down to me changing settings but I’ve been no-where near OH today, went to start the siren, it worked once then failed.

Any advice or am I going to have to think of a different way of controlling this outside of OH.

Error messages in openhab.log?

As mentioned in the first post it works fine then suddenly stops working (no additional messages in mosquitto log). Restart openhab2 service and it works fine. Hours/days can pass before it does it again but i need this to be reliable!

2019-05-14 13:52:20.792 [WARN ] [home.binding.mqtt.action.MQTTActions] - MQTT publish to gs/sirens/ghsirenmtr failed!
2019-05-14 13:52:20.793 [WARN ] [home.binding.mqtt.action.MQTTActions] - MQTT publish to gs/sirens/ghsirenmtr failed!
2019-05-14 13:53:09.694 [WARN ] [home.binding.mqtt.action.MQTTActions] - MQTT publish to gs/sirens/ghsirenmtr failed!
2019-05-14 13:53:15.696 [WARN ] [home.binding.mqtt.action.MQTTActions] - MQTT publish to gs/sirens/ghsirenmtr failed!
2019-05-14 13:53:21.698 [WARN ] [home.binding.mqtt.action.MQTTActions] - MQTT publish to gs/sirens/ghsirenmtr failed!
2019-05-14 13:53:27.254 [WARN ] [home.binding.mqtt.action.MQTTActions] - MQTT publish to gs/sirens/ghsirenmtr failed!
2019-05-14 13:53:27.255 [WARN ] [home.binding.mqtt.action.MQTTActions] - MQTT publish to gs/sirens/ghsirenmtr failed!
2019-05-14 13:53:29.938 [WARN ] [home.binding.mqtt.action.MQTTActions] - MQTT publish to gs/sirens/ghsirenmtr failed!
2019-05-14 13:53:34.942 [WARN ] [home.binding.mqtt.action.MQTTActions] - MQTT publish to gs/sirens/ghsirenmtr failed!
2019-05-14 13:53:34.942 [WARN ] [home.binding.mqtt.action.MQTTActions] - MQTT publish to gs/sirens/ghsirenmtr failed!

Then it may be a little harder to debug, especially when using any scripts you mentioned (I guess to build the mqtt action which was missing in 2.4 stable).
I would subscribe to the SYS topic and check the load to find out what is happening, for example with an mqtt client:

grafik

I think I may be running into this bug

But have no idea on how to workaround it

Good catch, sounds like your problem and unfortunately no solution yet … :joy:

That’s a pity, I’m going to have to move my logic outside of openhab

Do you happen to know of a way or another program that can listen to a topic then run a script automatically?

I think this is fixed in recent OH versions. The report was also for OH 2.4 only. Please remember that we added MQTT Thing actions about 5 days before the release, there are plenty of bugs in that old code.

Thanks David

I’m running 2.4 stable and 1.13 of the mqtt action. Is there a recommended version of OH or the action that I should upgrade to, to try and clear this up (I really don’t want to move my logic elsewhere as when this is working it’s working very well!)

However I have just noticed that for 1.13 it says i need mqtt binding 1.x installed. i am running 2.4. coudl this be an issue?

Why do you need to use the action? Why not have a switch Item defined in the conventional way, with an MQTT channel, and send it commands?

I am running the ON/OFF rule that you kindly helped me with last week but this is initially triggered (via a separate mqtt command) from a PHP page. What we want to do is not possible from a sitemap or switch item.

??

Instead of

val mqttActions=getActions("mqtt","mqtt:broker:MQTTBroker")
      mqttActions.publishMQTT("siren","0")

which gives you grief, you -
set up the MQTT binding to subscribe to your broker
make a thing for your siren topic
add a switch channel with commandTopic
specify on/off to 0/1

Then add an Item to use that channel

Switch mySirenItem "siren switch" { channel="mqtt:topic:mysirenthing:controlchannel"}

Then you just send it a command from your rule

mySirenItem.sendCommand(ON)`

Also useful

2 Likes

That works a treat. MQTT Action now uninstalled

Thank you!

1 Like

Hi! I’m having some trouble here … Maybe you can help me …

MQTT.things

  Thing topic Cortina_Test "Cortina en Cuenca" @ "Cortinas" {
   Channels:
     Type switch : power "Power" [ stateTopic="stat/Cortina/POWER1", commandTopic="cmnd/Cortina/POWER1" ]
  }

Sonoff.items

Rollershutter Cortina_Test     "Cortina"
Switch Cortina_Test_Up "Cortina Up" { channel="mqtt:topic:mqtt_broker:Cortina:power" }

Rules.rules

rule "G_sonoff"
when
    Item Cortina_Test received command
then
    Cortina_Test_Up.sendCommand(ON)
end

The log shows:
16:20:24.605 [INFO ] [smarthome.event.ItemCommandEvent ] - Item 'Cortina_Test_Up' received command ON

But nothing else happens … what am I missing?
I’m trying to control a Sonoff Dual thru a rollershutter item but since neither publishMQTT works nor the rollershutter on 2.4 I’m looking at other options.

Thanks for taking the time.

The rule is listening for commands to Cortina_Test, not Cortina_Test_Up
I do not expect the rule to do anything here.

The Cortina_Test_Up Item is bound to a channel mqtt:topic:mqtt_broker:Cortina:power
I cannot tell if you have a broker called mqtt_broker or not.
You do not seem to have a Thing called Cortina, although you do have a Thing called Cortina_Test
I do not expect the binding to do anything here.

Let me add some more info and my config files …

What I’m trying to achieve is to be able to control a rollershutter from the basic UI, with a sitemap with the rollershutter switch so I get the up, stop and down buttons.

So on my mind, I have a switch Cortina_Test, that triggers a rule with a select case depending on which button was pressed and acts accordingly, with a sendCommand(ON) to the POWER1 or POWER2 from my Sonoff Dual R2 flashed with Tasmota.

If you thinks there’s a better way to achieve the same result, I’m all ears.

So, back to my files …

ITEMS

Group:Switch:OR(ON, OFF) gCortinas "Todas las Cortinas"

//Blinds Controls
Switch Cortina_Test_Up "Cortina Up" { channel="mqtt:topic:mqtt_broker:Cortina_Test_Up:power" }
Switch Cortina_Test_Down "Cortina Down" { channel="mqtt:topic:mqtt_broker:Cortina_Test_Down:power" }
Rollershutter Cortina_Test     "Cortina"     (gCortinas) { channel="mqtt:topic:mqtt_broker:Cortina_Test:power" }

THINGS

Bridge mqtt:broker:mqtt_broker "MQTT Broker Alex" [ host="127.0.0.1", secure=false, clientID="MQTT_Cuenca"]
{
  Thing topic Cortina_Test_Up "Cortina en Cuenca" @ "Cortinas" {
   Channels:
     Type switch : power "Power" [ stateTopic="stat/Cortina/POWER1", commandTopic="cmnd/Cortina/POWER1" ]
  }
 
  Thing topic Cortina_Test_Down "Cortina en Cuenca" @ "Cortinas" {
   Channels:
     Type switch : power "Power" [ stateTopic="stat/Cortina/POWER2", commandTopic="cmnd/Cortina/POWER2" ]
  }

  Thing topic Cortina_Test "Cortina en Cuenca" @ "Cortinas" {
   Channels:
     Type switch : power "Power" [ stateTopic="stat/Cortina/POWER", commandTopic="cmnd/Cortina/POWER" ]
  }

}

SITEMAP

sitemap casa label="Casa Banana" {
    Frame label="Cortinas" icon="groundfloor" {
        Switch item=Cortina_Test label="Cortina Test []"
    }

	Frame label="Master Shutters Control" {
			Switch item=gCortinas icon="blinds" mappings=[ON="Subir Todo"]
			Switch item=gCortinas icon="blinds" mappings=[OFF="Bajar Todo"]      
    }

}

RULES

rule "Move Rollershutter"
when
    Item Cortina_Test received command
then
    switch (receivedCommand) {
        case UP: Cortina_Test_Up.sendCommand(ON)
        case DOWN:Cortina_Test_Down.sendCommand(ON)
        case STOP: {
            if(Cortina_Test_Up.state == ON) Cortina_Test_Up.sendCommand(OFF)
            if(Cortina_Test_Down.state == ON) Cortina_Test_Down.sendCommand(OFF)
        }
    }
end

That’s all I have … Any thoughts? Thanks again !!!

Apparently, it’s working! Weird …

Is there a better way to achieve the same result? Any tips?

Thanks for the help!

@David_Graeff i am running 2.5 M1 and I am seeing this bug. I am trying to link up homeassistant and openhab via mqtt using rule files and the thing action.

rules file

// MQTT naming convention i use:
//
//commandPublishTopic = /openHAB/out/${item}/command
//stateSubscribeTopic = /openHAB/in/${item}/state

// MASTER
var boolean commandSubscribeTopic = true
var boolean stateSubscribeTopic = false
var boolean statePublishTopic = true
var boolean commandPublishTopic = false
val actions = getActions("mqtt","mqtt:broker:a35fc928")

// SLAVE
// var boolean commandSubscribeTopic = true
// var boolean stateSubscribeTopic = false
// var boolean statePublishTopic = true
// var boolean commandPublishTopic = false

// We need a group with all items as a Member of trigger.
// Creating one dynamicly. (Group dg_AllItems)
// ScriptServiceUtil.getItemRegistry.getItems() can not be used as a Member of trigger (I've tried :-)



rule "Publish command to broker"
when
	Member of HomeAssistant_Switch received command
then
    if (commandPublishTopic){
	
	
		HomeAssistant.members.forEach[hassGroup|
	 	if (hassGroup instanceof GroupItem)
	 	{
	 		hassGroup.members.forEach[hassMember|
	 			if (hassMember.name == triggeringItem.name)
	 			{
	 				val mqttGroupLabel = hassGroup.label.toString().split(":")
					val mqttSubPath = mqttGroupLabel.get(0)
					val mqttPath = "homeassistant/"+mqttSubPath+"/"+triggeringItem.name+"/set"
					val mqttPayload = triggeringItem.state.toString

					logDebug("HomeAssistant.rules", "Sending to mqtt path: " + mqttPath+ " the following payload: "+ mqttPayload)
					HomeAssitant_MQTT.sendCommand(mqttPath + "%Payload%" + mqttPayload)
					//actions.publishMQTT(mqttPath,mqttPayload)
	 			}
			]
	 	}]
	}
end

rule "Publish state to broker"
when
     	Member of HomeAssistant_Sensor received update or
		Member of HomeAssistant_Switch received update or 
		Member of HomeAssistant_Door received update or 
		Member of HomeAssistant_Motion received update or
		Member of HomeAssistant_Presence received update 8
		
then
        
		
		HomeAssistant.members.forEach[hassGroup|
	 	if (hassGroup instanceof GroupItem)
	 	{
	 		hassGroup.members.forEach[hassMember|
	 			if (hassMember.name == triggeringItem.name)
	 			{
	 				val mqttGroupLabel = hassGroup.label.toString().split(":")
					val mqttSubPath = mqttGroupLabel.get(0)
					val mqttPath = "homeassistant/"+mqttSubPath+"/"+triggeringItem.name+"/state"
					val mqttPayload = triggeringItem.state.toString

					logDebug("HomeAssistant.rules", "Sending to mqtt path: " + mqttPath+ " the following payload: "+ mqttPayload)
					HomeAssitant_MQTT.sendCommand(mqttPath + "%Payload%" + mqttPayload)
					//actions.publishMQTT(mqttPath,mqttPayload)
	 			}
			]
	 	}]

end


rule "Subscribe to broker"
when
        //Channel 'mqtt:broker:a35fc928:publish' triggered
		
then
        logDebug("HomeAssistant.rules-mqtt-publish", "mqttevent payload received: " +receivedEvent.getEvent.toString())

		var evnt_payload = receivedEvent.getEvent.toString.split("#")
	
		

       // logDebug("HomeAssistant.rules", "mqttevent payload received: + " + event_payload.toString())
	    var mqtttopic = evnt_payload.get(0).toString.split("/")
        var mqttcommand = evnt_payload.get(1)
		//logDebug("HomeAssistant.rules-mqtt-publish", "the mqtttopic is : " +mqtttopic.toString() + "the mqttcommand is:" +mqttcommand.toString())
        var mqttitem = mqtttopic.get(mqtttopic.length-2)
		//logDebug("HomeAssistant.rules-mqtt-publish", "the mqttitem is : " +mqttitem.toString())
        var mqttcommandorstate = mqtttopic.get(mqtttopic.length-1)
		//logDebug("HomeAssistant.rules-mqtt-publish", "The members to search are: " + HomeAssistant.allMembers)
        var ItemExists = HomeAssistant.allMembers.filter[item | item.name.contains(mqttitem)].length
		//logDebug("HomeAssistant.rules-mqtt-publish", "the mqttitem is : " + ItemExists.toString())
        if (ItemExists > 0 || mqttitem.contains("HomeAssistant_Config")){

                if (commandSubscribeTopic &&   mqttcommandorstate == "set") {
                        sendCommand(mqttitem,mqttcommand)
                }
                else {
                        if (stateSubscribeTopic && mqttcommandorstate == "state") {
                                postUpdate(mqttitem,mqttcommand)
                        }
            
		    }
        }
end

rule "Send Autodiscovery Switches"
when 
System started or
Item HomeAssistant_Config changed
then


HomeAssistant.members.forEach[hassGroup|
	 	if (hassGroup instanceof GroupItem)
	 	{
			 logDebug("HomeAssistant.rules", "HASSgroup name = " + hassGroup.name)
	 		hassGroup.members.forEach[hassMember|
	 			
				var mqttPayload = ""
				
				var hassGroupname = hassGroup.name
				val mqttGroupLabel = hassGroup.label.toString().split(":")
				val mqttSubPath = mqttGroupLabel.get(0)
				val mqttBasePath = "homeassistant/"+ mqttSubPath +"/"+ hassMember.name 
				var mqttPath = mqttBasePath+ "/config"
				logDebug("HomeAssistant.rules-config", "The device class is: " + mqttSubPath.toString())
				var mqttdevicejson = ""
				if (mqttGroupLabel.get(1).contains("None")){}else{
					mqttdevicejson = '"device_class":"' + mqttGroupLabel.get(1) + '",'
				}
				switch (hassGroupname){
					case mqttSubPath.contains("switch"):

					mqttPayload = '{"name": "'+ hassMember.label +'","state_topic": "'+ mqttBasePath + '/state", "command_topic":"'+mqttBasePath+'/set"}'

					case mqttSubPath.contains("binary_sensor"):
					mqttPayload = '{"name": "'+ hassMember.label +'",' +mqttdevicejson+'"state_topic": "'+mqttBasePath+'/state"}'

				}
				 
				 logDebug("HomeAssistant.rules", "Sending to mqtt path: " + mqttPath+ " the following payload: "+ mqttPayload)
				 //actions.publishMQTT(mqttPath,mqttPayload)
				 HomeAssitant_MQTT.sendCommand(mqttPath + "%Payload%" + mqttPayload)
			]
	 	}]
end


rule "Send HomeAssistant Config"
when
Item HomeAssistant_Config received update
then


val mqttPath = "homeassistant/switch/"+triggeringItem.name+"/state"
val mqttPayload = triggeringItem.state.toString()

logDebug("HomeAssistant.rules", "Sending to mqtt path: " + mqttPath+ " the following payload: "+ mqttPayload)


HomeAssitant_MQTT.sendCommand(mqttPath + "%Payload%" + mqttPayload)
//actions.publishMQTT(mqttPath,mqttPayload)



end

jsr223 file

load(Java.type("java.lang.System").getenv("OPENHAB_CONF")+'/automation/jsr223/jslib/JSRule.js');

JSRule({
    name: "Send MQTT Payload",
    description: "Send an MQTT payload from the string",
    triggers: [
        CommandEventTrigger("HomeAssitant_MQTT")
    ],
    execute: function( module, input){
        //logInfo("About to Trigger MQTT Rule: ");
        var receivedCommand = getTriggeredData(input).receivedCommand;
        var splitCommand = receivedCommand.split("%Payload%");
        var mqttPayload = splitCommand[1]; 
        var mqttPath = splitCommand[0];
        
        logInfo("The MQTT rule was triggered with a path of : " + mqttPath + " and a payload of: " + mqttPayload);
        actions.get("mqtt", "mqtt:broker:a35fc928").publishMQTT(mqttPath, mqttPayload);
        
    }
});

.items file

Group HomeAssistant
Group HomeAssistant_Switch "switch:None" (HomeAssistant)
Group HomeAssistant_Sensor "binary_sensor:None" (HomeAssistant)
Group HomeAssistant_Door "binary_sensor:door" (HomeAssistant)
Group HomeAssistant_Motion "binary_sensor:motion" (HomeAssistant)
Group HomeAssistant_Presence "binary_sensor:presence" (HomeAssistant)
Switch HomeAssistant_Config
String HomeAssitant_MQTT "[%s]"
Switch	Light1	"Kitchen Light"			(Lights, Away_Lights,Bedroom_Lights,HomeAssistant_Switch)["Lighting"]	{channel="zwave:device:512:node9:switch_binary", channel="mqtt:topic:3851041d:Light1"} 
Switch Front_Door_Sensor 	"Front Door" <kfrontdoor> (HomeAssistant_Door)		{channel="konnected:module:1673491:Zone_6"}
Switch Konnected2_Zone_1	"Door Bell"     (HomeAssistant_Sensor)	{channel="konnected:module:1673491:Zone_1"}
Switch System_State "Home/Away" (Persist, HomeAssistant_Presence)
Switch  Front_Motion_Control "Front Motion Control"    (gPresent,HomeAssistant_Motion)     {expire="5m,command=OFF"}



I was original using the val actions and publishing directly from the DSL rules but i read somewhere that the jsr223 rules only run one per thread so i moved the publish to the jsr223 script to see if that would make it more stable.

Alas it has not. My setup can run for awhile but then the action starts failing. A restart is only temporary fix.

Wanted to add that restarting just this bundle makes things work again for awhile

239 │ Active │ 80 │ 0.11.0.oh250M1 │ Eclipse SmartHome MQTT Transport Bundle

This looks like a classic hidden timing race condition to me.
By the time you read the triggering Items .state, the command may or may not have updated it. You should not assume you’re going to get “before-command” or “after-command” state here.
As it seems the Item happens to be a switch where command is essentially same as expected state, and you can reliably get that with receivedCommand, that should do instead?

Or if you really do want to act after the state has been affected by the command, you need to look at rule trigger updated instead.

Probably has nothing at all to do with your publish issue of course :smiley: