Rs232 help please

Hey all I’m at abit of a loss here.
I have an hdmi matrix im trying to control RELIABLY, I have it working, but sometimes a signal sent to the matrix (via rs232) doesn’t make it. I’d say this happens about 30% of the time (whenever a signal makes it a response is sent back). So I think I need a way to listen for the response, after a timeout period if the response isnt received, it can send the command again.
Unfortanetly I’m having trouble thinking of a way to accomplish this.
Does anyone have some Idea of how I can do something like this?

  • Platform information:
    • Hardware:raspberry pi 3
    • OS: openhabian openhab 2.3.0-1
    • Java Runtime Environment: which java platform is used and what version
    • openHAB version:230
  • Issue of the topic: need method to expect reaction response from rs232
  • Please post configurations (if applicable):
    • Items configuration related to the issue
    • Sitemap configuration related to the issue
    • Rules code related to the issue
    • Services configuration related to the issue
  • If logs where generated please post these here using code fences:

more info are needed…

how do you control the RS232 endpoint currently? (with the Serial binding?)
what are your relevant item configs and rules (if used)?
what is the format of the command and successful response (give an example)
have you tried changing the serial cable that connects the endpoint? (it could be a hardware problem)

how do you control the RS232 endpoint currently? (with the Serial binding?)
Yes I’m using the serial binding to control the matrix, I have a single string item that I send all commands to, and for each zone of the matrix I have a number item to switch modes with. it looks like this:

String GofancoMatrix "HDMI Matrix" { serial="/dev/ttyUSB0@9600" }
Number LivingSource "Living Room Source" (Persistant)
Number FamilySource "Family Room Source" (Persistant)
Number FPRSource "Fireplace Room Source" (Persistant)
Number GarageSource "Garage Source" (Persistant)

these are the rules I’m currently using to send commands to it:

///////////////// Gofanco HDMI Matrix ///////////
rule "switch Living Room Input"
	when
		Item LivingSource received command
	then
		if(LivingSource.state==0){
			//Flag1V1.sendCommand(ON)
			var String TransmitMSG = "1$."
			GofancoMatrix.sendCommand(TransmitMSG)
		}
		else if(LivingSource.state==1){
			//Flag1V1.sendCommand(ON)
			var String TransmitMSG = "1V1."
			GofancoMatrix.sendCommand(TransmitMSG)
		}
		else if(LivingSource.state==2){
			//Flag2V1.sendCommand(ON)
			var String TransmitMSG = "2V1."
			GofancoMatrix.sendCommand(TransmitMSG)
		}
		else if(LivingSource.state==3){
			//Flag3V1.sendCommand(ON)
			var String TransmitMSG = "3V1."
			GofancoMatrix.sendCommand(TransmitMSG)
		}
		else if(LivingSource.state==4){
			//Flag4V1.sendCommand(ON)
			var String TransmitMSG = "4V1."
			GofancoMatrix.sendCommand(TransmitMSG)
		}
end
rule "switch Family Room Input"
	when
		Item FamilySource received command
	then
		if(FamilySource.state==0){
			//Flag1V1.sendCommand(ON)
			var String TransmitMSG = "2$."
			GofancoMatrix.sendCommand(TransmitMSG)
		}
		else if(FamilySource.state==1){
			var String TransmitMSG = "1V2."
			GofancoMatrix.sendCommand(TransmitMSG)
		}
		else if(FamilySource.state==2){
			var String TransmitMSG = "2V2."
			GofancoMatrix.sendCommand(TransmitMSG)
		}
		else if(FamilySource.state==3){
			var String TransmitMSG = "3V2."
			GofancoMatrix.sendCommand(TransmitMSG)
		}
		else if(FamilySource.state==4){
			var String TransmitMSG = "4V2."
			GofancoMatrix.sendCommand(TransmitMSG)
		}
end
rule "switch Fireplace Room Input"
	when
		Item FPRSource received command
	then
		if(FPRSource.state==0){
			//Flag1V1.sendCommand(ON)
			var String TransmitMSG = "3$."
			GofancoMatrix.sendCommand(TransmitMSG)
		}
		else if(FPRSource.state==1){
			var String TransmitMSG = "1V3."
			GofancoMatrix.sendCommand(TransmitMSG)
		}
		else if(FPRSource.state==2){
			var String TransmitMSG = "2V3."
			GofancoMatrix.sendCommand(TransmitMSG)
		}
		else if(FPRSource.state==3){
			var String TransmitMSG = "3V3."
			GofancoMatrix.sendCommand(TransmitMSG)
		}
		else if(FPRSource.state==4){
			var String TransmitMSG = "4V3."
			GofancoMatrix.sendCommand(TransmitMSG)
		}
end
rule "switch Garage Input"
	when
		Item GarageSource received command
	then
		if(GarageSource.state==0){
			//Flag1V1.sendCommand(ON)
			var String TransmitMSG = "4$."
			GofancoMatrix.sendCommand(TransmitMSG)
		}
		else if(GarageSource.state==1){
			var String TransmitMSG = "1V4."
			GofancoMatrix.sendCommand(TransmitMSG)
		}
		else if(GarageSource.state==2){
			var String TransmitMSG = "2V4."
			GofancoMatrix.sendCommand(TransmitMSG)
		}
		else if(GarageSource.state==3){
			var String TransmitMSG = "3V4."
			GofancoMatrix.sendCommand(TransmitMSG)
		}
		else if(GarageSource.state==4){
			var String TransmitMSG = "4V4."
			GofancoMatrix.sendCommand(TransmitMSG)
		}
end

Whenever I send the command to switch input 1 to output 1 I send the command 1V1. (including the dot) and I expect to see the response AV:01->01
input 2 to output 1 I send command 2V1. and expect response: AV:02->01
to switch off output 1 I send command 1$. and receive response: 01 Closed.

I have tried replacing the serial cable with 2 different cables I have on hand and have verified that they work with other serial devices.

So… A little more digging apparently my rule’s have a few issues, I noticed that it isn’t the matrix at fault here. Sometimes when an input source item is sent a command (ie item LivingSource command 0,1,2,3,4) the rule doesn’t seem to execute and thus the signal never gets sent to the matrix via rs232. So I’ve changed my rules to use a case switch instead of multiple if statements and it seems to be working fine now (even a rapid fire of commands). The thing is, I don’t know why. anyhow here are my new rules:

///////////////// Gofanco HDMI Matrix ///////////
rule "switch Living Room Input"
	when
		Item LivingSource received update
	then
		var String TransmitMSG	
   		switch (LivingSource.state as Number) { 
        	case 0:TransmitMSG = "1$."
        	case 1:TransmitMSG = "1V1."
        	case 2:TransmitMSG = "2V1."
        	case 3:TransmitMSG = "3V1."
        	case 4:TransmitMSG = "4V1."
    	}
    	GofancoMatrix.sendCommand(TransmitMSG)	
end

rule "switch Family Room Input"
	when
		Item FamilySource received update
	then
		var String TransmitMSG	
    	switch (FamilySource.state as Number) { 
        	case 0:TransmitMSG = "2$."
        	case 1:TransmitMSG = "1V2."
        	case 2:TransmitMSG = "2V2."
        	case 3:TransmitMSG = "3V2."
        	case 4:TransmitMSG = "4V2."
    	}
    	GofancoMatrix.sendCommand(TransmitMSG)
end

rule "switch Fireplace Room Input"
	when
		Item FPRSource received update
	then
		var String TransmitMSG	
    	switch (FPRSource.state as Number) { 
        	case 0:TransmitMSG = "3$."
        	case 1:TransmitMSG = "1V3."
        	case 2:TransmitMSG = "2V3."
        	case 3:TransmitMSG = "3V3."
        	case 4:TransmitMSG = "4V3."
    	}
    	GofancoMatrix.sendCommand(TransmitMSG)
end

rule "switch Garage Input"
	when
		Item GarageSource received update
	then
		var String TransmitMSG	
    	switch (GarageSource.state as Number) { 
        	case 0:TransmitMSG = "4$."
        	case 1:TransmitMSG = "1V4."
        	case 2:TransmitMSG = "2V4."
        	case 3:TransmitMSG = "3V4."
        	case 4:TransmitMSG = "4V4."
    	}
    	GofancoMatrix.sendCommand(TransmitMSG)
end

edit: I’d still like to figure out a way to expect a response from commands sent though.

The most obvious difference is the use of as Number. Rules can be picky about number values. as Number is almost always a good idea.

First step would be to setup an Item listening on RS232 binding, and a simple rule to log received strings.

I’m not sure I follow you completely here, I have a string item (GofancoMatrix) that already listens in, it changes states to whatever data is sent or received. Are you saying I need two separate items? one for receiving data and one for sending?
This seems logical to me but I’m not sure how to create an item with the serial binding that only receives or sends, I’m looking through the documentation for the serial binding right now but I think that’s the direction I should be going.
As for the rule that does the logging bit, do you happen to have an example? I’m completely lost there

I don’t use the Serial binding but from what I see, you can’t define a “direction” (outbound and inbound) so I don’t think that it would work to use 2 Items here.

In theory, within your rule, immediately after the send command, you should evaluate the new state of the String item to see if you got a successful response and if not, resend it until you do (like a loop).
This is an advanced rule that requires alot of testing :slight_smile:

I think you can use the same Item for tx and rx. I would set autoupdate=“false” on that Item, so that it stops OH setting it to last command value regardless.
It probably depends on your hardware whether or not your Item will get updated to the sent command, i.e. shows an echo.

You could set a simple rule to listen for changes

rule "serial monitor"
when
   Item GofancoMatrix received update
then
   logInfo("monitor232", "value " + GofancoMatrix.state.totring)
end

You’l find the output in openhab.log

logInfo() is a really useful tool for rules development.

Once you get this to work, you can easily merge these four Rules into one. What I would do is:

  • append the number to the name of the Source Items, e.g. LivingSource_1
  • add all the sources to the same Group, e.g Sources
rule "Switch Input"
when
    Member of Sources received update
then
    val  num = triggeringItem.name.split("_").get(1)
    val transmitMsg = if(triggeringItem.state as Number == 0) num+"$." else triggeringItem.state.toString+"V"+num+"."

     GofancoMatrix.sendCommand(transmitMsg)
end

A few minor changes to the naming and in three lines of actual code you can replace all four of these Rules. And you can add more devices later if you need to without touching the Rule. You just have to add the Source Item to the Source’s Group.

1 Like

Thanks @rlkoshak, As always you have amazing suggestions. I intend to put this to good use. I still haven’t figured out a way to except the response, but after a few weeks with it working flawlessly I don’t think I really need it. (I’d rather focus on other things).

I’ll report back After I try your implementation. Thanks again.