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:
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.
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
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.
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.