Newbie Basic RS232 Plugin

Hi Everyone,

I’ve been reading over the Somfy plugin to try to understand how to write a plugin. It’s definitely over my head. I’m just wanting to write a plugin to pass status of a Kwikset door lock and to receive commands to lock and unlock my kwikset lock from an Elan controller over RS232. I’ve got a Global Cache unit that I can use for a serial port.

I can send or receive any ascii or hex commands from my Elan controller. Is there a simple way to do a plugin like this? Or, is there another simple plugin similar to this that I can go off of?

Thanks in advance for any help.
-Shane

Hi lshanepowers,

I attached a simple plugin that allows you to send something on the serial port, and displays the text it received from the serial port.

This is where the incoming data is handled:

<incoming>
    <lua>
        luup.log("Received: '"..(lul_data or "nil").."'")
        luup.variable_set("urn:micasaverde-com:serviceId:SimpleSerial1", "Received", (lul_data or "nil"), lul_device)
    </lua>
</incoming>

To send the message I used luup.io.write.

These pages should be helpful:

[ul][li]http://wiki.micasaverde.com/index.php/Luup_Plugins_ByHand[/li]
[li]http://wiki.micasaverde.com/index.php/Luup_Lua_extensions#Module:_io[/li][/ul]

If you prefer to monitor the incoming data on the GUI:

  1. Install WAI ([tt]http://forum.micasaverde.com/index.php/topic,6441.msg39556.html#msg39556[/tt]).

  2. Replace

<incoming>
    <lua>
        luup.log("Received: '"..(lul_data or "nil").."'")
        luup.variable_set("urn:micasaverde-com:serviceId:SimpleSerial1", "Received", (lul_data or "nil"), lul_device)
    </lua>
</incoming>

with

<incoming>
    <lua>
        luup.log("Received: '"..(lul_data or "nil").."'")
        luup.variable_set("urn:micasaverde-com:serviceId:SimpleSerial1", "Received", (lul_data or "nil"), lul_device)
        luup.variable_set( 'urn:upnp-ap15e-com:serviceId:WAI1', 'Location', tostring( lul_data ), dev_ID )
    </lua>
</incoming>
  1. Don’t forget to replace dev_ID with the WAI device ID.

Thanks guys for the help. I’ve got some reading to do and playing with it to see what I can figure out. I’m sure I’ll have lots more questions but thanks for getting me started.

Does SimpleSerial work with UI5? I am unable to send anything using the test luup code and luup.io.write(‘XXX’) in UI5, are there any changes there?

Thanks

Yes, it should work with UI5 too. This plugin uses the CR-LF protocol, maybe you should change it to the one your device uses.

@mcvflorin

you have created an plugin simple serial

I am trying to use it to and iptors232 adapter
I am getting the following error message “missing port”

I am using the ip adress 192.168.2.75 with the port 1470
so i enter the following data in the advanced tab at ip “192.168.2.75:1470”
what is wrong?
can you advise
rgds
Huib

Keeping it simple to send a RAW code, would I just change the following in I_SimpleSerial1.xml?

<implementation> <settings> <commUse>rs232</commUse> <protocol>raw</protocol> </settings>

And I want to send a Hex commands with no spaces between the codes.

HEX CODE

Port Status 0x02 0x30 0x30 0x31 0x03
Turn ON LED 0x02 0x30 0x30 0x33 0x03
Turn OFF LED 0x02 0x30 0x30 0x34 0x03
Turn ON Power 0x02 0x30 0x30 0x35 0x03
Turn OFF Power 0x02 0x30 0x30 0x36 0x03

The instructions say for Example: to Turn OFF LED Send: 02 30 30 34 03 ( in hex, no space)

From what I have read it sounds like a command like this is used?

luup.io.write(string.char(0x020x300x300x360x03))

Also if I want to do this over IP, (to a RaspPi, running Ser2net) what would I add for the IP and Port address?

[b]UPDATE : To confirm set up, I have the following

Raspberry Pi, with a static IP of 192.168.1.77,
Running Ser2net with the config set to the serial port speed/config and on port 4001
A USB to serial /RS232 cable connected to
An Octava HDMI Matrix switcher.[/b]

You need commas to separate your numbers into a list.

luup.io.write(string.char(0x02, 0x30, 0x30, 0x36, 0x03)

Or use a string literal (with decimal values):

luup.io.write("\002\048\048\054\003")

Or if you know your ASCII values for a few of the bytes:

luup.io.write("\002006\003")
Also if I want to do this over IP, (to a RaspPi, running Ser2net) what would I add for the IP and Port address?

The IP address of the Rasberry Pi, and the TCP port that you configured ser2net to listen on.

Thanks @futzle

So would that be…

luup.io.write(string.char(0x02, 0x30, 0x30, 0x36, 0x03), “192.168.1.77”, 4001)

Sadly no joy with any of those commands :frowning:

They claim to have been sent successfully by Vera , but nothing happens on the matrix to suggest it has been received.

I can check the port on the Pi, via telnet and it does not react to anything, which might suggests it’s not getting through…

Your next avenue is to try using the LuaSocket library instead of luup.io.write(). You’ve already found code that does this, so try adapting that.

Hi @futzle

I’ve been trying the following, and while that still is not working, using Rex’s LuaTest i can see if anything comes back.

local socket = require("socket") host = "192.168.1.77" c = assert(socket.connect(host, 4001)) c:send(string.char(0x02,0x32,0x31,0x33,0x03)) data = c:receive(300) luup.log (data) print (data) c:close()

Chris, you should add a timeout value to stop the send and receive from blocking. Also collect and print any errors returned.

local socket = require("socket") host = "192.168.1.77" c = assert(socket.connect(host, 4001)) c:settimeout(5) local sres, serr = c:send(string.char(0x02,0x32,0x31,0x33,0x03)) print("Send:", sres, serr) local data, rerr = c:receive(300) luup.log (data) print ("Receive:", data, rerr) c:close()

I would also be running tcpdump on the Raspberry Pi to see if anything is actually arriving on the network. The syntax is very esoteric but it looks something like:

tcpdump host 192.168.23.45

Replace the IP address with that of the Vera.

Edit: I assume that you have tested your commands locally on the Raspberry Pi and can be confident that your USB adapter and ser2net config are good?

Thanks all

@Futzle - I thought the same but, I’m not sure how to test the connection from the Pi itself, however I can see messages come back from the HDMI switch when I send certain commands (I can see the Ser2net banner reported back to me)

Hold on - I may have stumbled onto a potential contributing factor !! My ser2net.conf had the following

4001:telnet:0:/dev/ttyUSB0:9600 8DATABITS NONE 1STOPBIT banner

It was set to the telnet prorocol, not raw, which I assume is what I need - so i have updated the .conf to the following to see if that improves things…

4001:raw:600:/dev/ttyUSB0:9600 NONE 1STOPBIT 8DATABITS -XONXOFF -LOCAL -RTSCTS 4002:telnet:0:/dev/ttyUSB0:9600 NONE 1STOPBIT 8DATABITS banner1

Update : Using’s Rex’s bit of code (below) I’ve tried the following combinations, but no joy so far.

local socket = require("socket") host = "192.168.1.77" c = assert(socket.connect(host, 4001)) c:settimeout(5) local sres, serr = c:send(string.char(0x02,0x32,0x31,0x33,0x03)) print("Send:", sres, serr) local data, rerr = c:receive(25) luup.log (data) print ("Receive:", data, rerr) c:close()

Results via Lua Test are.

[b]Print output[/b] Send: 5 Receive: nil close

@Rex , not sure what the Send value us but it can vary depending on what I send.

Other variations of line 5 tried so far.

HEX - failed

local sres, serr = c:send(string.char(0x02,0x32,0x31,0x33,0x03))

Numbers (removing the 0x) - Failed

local sres, serr = c:send(0232313303)

Text - Failed

local sres, serr = c:send("0x02,0x32,0x31,0x33,0x03")
local sres, serr = c:send("02,32,31,33,03")

----oo0oo----

If I retry it with luup.io.write

luup.io.write(string.char(0x02, 0x32, 0x31, 0x33, 0x03), "192.168.1.77", 4001)

I get the following error in the logs

01 04/24/14 11:21:16.138 GetLuaInterface can't find device type: 4/0x90ee20 str: 192.168.1.77 <0x30254680> 01 04/24/14 11:21:16.139 luup_io_write 0x953878 args 3 <0x30254680>
Results via Lua Test are.

Quote
Print output
Send: 5
Receive: nil close

@Rex , not sure what the Send value us but it can vary depending on what I send.

This shows that it sent five characters - which is what you would expect. The Receive values show that the TCP client got closed - presumably by the Pi… You can see what the parameters are in LuaSocket Reference.

Thanks Rex for clarification, I had thought the ‘close’ value, was as a result of the final line

c:close ()

Thanks for the link too, which (I thin) suggests I’m using it correctly

[b]socket.connect ( address, port [, locaddr, locport] [/b]) Creates and returns a TCP client object connected to a remote host (address) at a given port. Optionally local address (locaddr) and port to bind (locport).

How can something that looked so straight forward be so difficult to do :frowning:

How can something that looked so straight forward be so difficult to do :(

It is only straightforward if you have a working serial port but it doesn’t look as though you do. I think you need to get the Pi end working before getting further bogged-down with Vera side.

If the Pi interface is working, you should be able to send your commands using a test tool like TCP Test Tool running on a PC (no it will not work on an iPad!). Once you have that working you can resume work on Vera. You can also use the test tool as a server to test your Vera send/receive if you set the IP and port appropriately.

As well as Rex’s advice, which you should follow, if you can install software on your Raspberry Pi you can do all your testing there.

netcat is a command-line program that you can use to send characters to a TCP stream. If you don’t need bidirectionality then it’s really simple to send bytes to as port. Here’s another discussion showing netcat: http://forum.micasaverde.com/index.php/topic,24743.msg172272.html#msg172272 (the only difference being that you would leave out the -u option because you want TCP not UDP). If you run nc on the Pi itself then you’d use “localhost” as the hostname instead of an IP address.

tcpdump I’ve already talked about. It’s most useful because with it you can definitively know if the problem is upstream or downstream of the Rapsberry Pi.

The USB port on a Raspberry Pi doesn’t have much oomph. I doubt it can drive a USB to Serial adapter without an intervening powered hub.