[SOLVED] Rs485 to MQTT gateway?

I have a ventilation fan that puts out serial data using rs485… Things like speed, temp, humidity etc…

Does anyone know of a ready built solution to get this published as MQTT topics on my network? I did find one solution but 200 euros is a bit much to pay :laughing:

Hi,
i use a 2. Raspberry Pi with openhabbian and a rs485 Head to send the serial data from my PV Inverters to openHAB via MQTT.
It‘s cheap and takes little time build…

Could also hook up a rs485 to rs232. Converter to the serial port on a 8266.

Not running Modbus, is it? Many HVAC systems do.

Sounds like it is plain old serial over RS485… This is the response I got from the installer…

No it’s just running straight UART with baud rate 9600. Modbus is a specific communication protocol but we didn’t make it use that as that would become all sorts of complicated to implement, so the communication protocol is like I outlined in my previous email. The serial communication settings should be 9600 baud rate (asynchronous communication), 8-bit, no parity, 1 stop bit, no flow control (you will only be reading the data output by the fan anyway). If you use a simple program like RealTerm and a RS485 to USB converter, you should be able to see the fan output coming into your computer so you can get an idea of what kind of data you are receiving.

1 Like

Stuck with reading a serial stream then.
USB/RS485 hardware is cheap for a direct connection; RS485 cabling can go a loooong distance; openHAB serial binding is rather basic but a rule or two should be able to extract the data.

1 Like

Cool, so we thinking just a RS485 to USB dongle plugged into my OpenHAB raspberry Pi 3 should be the hardware I need?

They’re so cheap it’s worth a try.
You will need to know or observe the serial data stream or packet format in order to do anything useful.

I have used rs485 with openhab before and yes a USB to rs-485 converter that works in Linux is all you need. You have to parse the serial data yourself.

I’m planing on making a binding to interface to my rs485 devices so if you pm me a copy of your devices packets I can look to include an easier way to parse it in my binding.

Hey, I’ve got some stuff coming into OpenHAB and can see this in the logs…

2019-06-23 14:30:30.412 [vent.ItemStateChangedEvent] - Serial01 changed from S
PTaHIVM to S
PTHIVM

I suspect there are some special characters in there or something…
This is some context I got from the person who supllied me the fan…

If you want to see what kind of data you are receiving yourself, I would suggest selecting the “display as: Hex + ASCII” option if I remember correctly, but I would just try a few different options and see what it does. You should be getting data in the form of a string of 13 characters like “S15P2T185H63V3M0” (speed = 15%, phase = ADJUST, temp = 18.5, hum = 63%, vent rate = HIGH, summer mode = 0) but getting it to show it like that might be tricky.

So it looks like I have all the Alpha characters to indicate the bits of data but the actual values are encoded in such a way as that I can’t read them. I’ll read some more and see if I can figure anything further out…

When I tell the serial binding to encode it in BASE64 I get this…
UwxQAlQQAEhIVgFNAQ==

Yuck what a pain and it does not have any kind of device ID number in case you own multiple fans so it will mean a new serial port for every device so you know which device is sending the data. I would convert to using pure HEX and then simply learn what the hex for S is by using this

https://www.rapidtables.com/convert/number/ascii-to-hex.html

Here are some tips, set the serial binding to use ‘ISO-8859-1’ charset otherwise the conversion to HEX will not be correct and will confuse you. I believe the binding now allows you to set the charset as an option, have not used it since it was changed (?) so the following post may need to be adapted slightly. Note the post was made in 2015 so if you work it out be sure to post what works to help others.

1 Like

Yeah it is just something “custom” the guys added for me… They don’t normally add any “output” to their fans so they did me a favour at least :slight_smile:

I am completely out of my depth here a little… I’m thinking the next thing I need is a rule to convert the ASCII to HEX?

Yes that was nice of them and the static characters will actually help you identify when you have a good packet since there is no Id. My last post had some example for you to get it working with hex if the binding has not changed too much. You don’t need rules to receive the hex but you will for the parsing of the incoming data. This is why I am going to write a binding that allows more flexible and easier setup for this kind of thing. It will probably be a few months before I get the time to do it.

Okay, thanks to @rossko57 I have this converted to decimal bytes now…

Serial01 changed from S	PTH<VM to SPTH=VM
decimal bytes 83, 8, 80, 1, 84, 15, 0, 72, 61, 86, 1, 77, 1,

Great news that you now have it sorted. Can you post what info you needed to know in order to get it working and mark the post as the solution to help others that search the forum?

That the part of the stream represents temp = 15.0 I guess??
What a nasty encoding! But you can use it.
I guess the simplest way would be something like
myTempItem.postUpdate( byte(nn).toString + "." + byte(nn+1).toString )

What does the “nn” represent in that code? i can’t quite figure it out…

Well it’s just an example, you’d use the 6th and 7th bytes in the stream.
The object was to convert X and Y numeric values to a single decimal X.Y , which isn’t quite as easy at it looks.
The cheat way is to make a string out of it.

Yeah I’m pretty clueless when it comes to coding so don’t assume I know anything "-)

Below is the rule I have so far using the sample you provided to log the full DECIMAL. I’ve added an extra line to try to add some more logging and display the fan speed which is supposed to be the 2nd value.

rule "display serial packet"
when
   Item Serial01 changed
then
   var bytesarray = Serial01.state.toString.getBytes()
   val StringBuilder decdisplay = new StringBuilder
   bytesarray.forEach[b |
      var int x = b.intValue.bitwiseAnd(255) // this converts -128 to 127 to 0 to 255
      decdisplay.append(Integer::toString(x) + " ")
      ]
   logInfo("Serial test", "decimal bytes " + decdisplay)
   logInfo("Serial test", "Fan Speed " + bytesarray(2).toString)
end

FAIL
Rule ‘display serial packet’: The name ‘bytesarray’ cannot be resolved to an item or type

Okay I think I can make sense of where the data I need is… Now to figure out how to get at it and store it in different items…