Posts: 155
Threads: 12
Joined: Sep 2015
Reputation:
13
06.10.2016, 13:18
(This post was last modified: 06.10.2016, 13:56 by AEK.)
hello everyone!!
I made function (with Admin's big help), which will show you what Lutron send by telnet
I have lutron Homework QS
create user libruary "lutron"
Code: local socket = require("socket")
local user = 'default'
local password = 'default'
function lutron_connect()
local tcp = assert(socket.tcp())
tcp:settimeout(31)
local res, err = tcp:connect('192.168.0.105', 23)
if res then
return tcp
else
tcp:close()
return nil, err
end
end
function lutron_login()
local tcp, tcp_err = lutron_connect()
if not tcp then
return nil, tcp_err
end
tcp:receive(7)
tcp:send(user..'\r\n')
tcp:receive(10)
tcp:send(password..'\r\n')
local res = tcp:receive(9)
if res == nil or res == 'bad login' then
tcp:close()
return nil, res
end
return tcp
end
function lutron_receive(tcp)
res, err = tcp:receive()
if not res then
tcp:close()
return nil, err
end
return res
end
and resident script
Code: require('user.lutron')
tcp, err = lutron_login()
if not tcp then
log('no connection to device', err)
end
while tcp do
res, err = lutron_receive(tcp)
log(res,err)
if (res == nil) then
return
end
end
Posts: 155
Threads: 12
Joined: Sep 2015
Reputation:
13
12.10.2016, 12:07
(This post was last modified: 12.10.2016, 13:38 by AEK.)
some additions for that case
Lutron message parser
For example I shall show you how to receive setpoint temperature from Lutron panel/switch
Let’s write all messages from Lutron to knx group address
Change resident script
Code: require('user.lutron')
tcp, err = lutron_login()
if not tcp then
log('no connection to device', err)
end
while tcp do
res, err = lutron_receive(tcp)
--log(res,err)
if (res == nil) then
return
else
grp.write('15/1/1', res)
end
end
From Lutron we receive a lot of messages when we change setpoint
For example, this 4 message we will receive twice, when we will change setpoint:
~HVAC,11,78,26,26 – i dont know what is it
~HVAC,11,18, 79,0,0 – setpoint in Fahrenheit
~HVAC,11,19, 26,0,0 -- setpoint in Celsius degree
~HVAC,11,10,26,26 -- i dont know what is it
Let’s see, what we have in setpoint in Celsius degree
~HVAC,11,19,26,0,0
~HVAC – status from device
11 – device id, which send this message
19 – type of information (Celsius degree in this example)
26 - Celsius degree
0,0 – some other parameters
To parse this message and write temperature to knx address create event based script for message group address (15/1/1)
Code: --lutron parser
-- get string
temp = event.getvalue()
-- convert sting to table
temp = string.split(temp, ',')
-- if comand type is ~HVAC let's move forward
if temp[1] == '~HVAC' then
-- if device id = id of our panel let's move forward
if temp[2] == '11' then -- be carefull, temp[2] is string, not number
-- if in message is celsius degree
if temp[3] == '19' then
-- convert temperature from string to number
temp = tonumber(temp[4])
-- check current value of setpoint, to not to write the same value
cur_temp = grp.getvalue('lutron_temp_setpoint')
if temp~=cur_temp then
-- write walue to temp address
grp.write('lutron_temp_setpoint', temp)
end
end
end
end
To write value from LM to Lutron create event script for setpoint object
Code: require('user.lutron')
value = event.getvalue()
-- round setmoint to integer
value = math.floor(value)
tcp, err = lutron_login()
if not tcp then
log('no connection to device', err)
end
tcp:send('#HVAC,11,19,'..value..',0,0\r\n')
to read some data from lutron use next script (resident in my case)
Code: require('user.lutron')
--Подключаемся и делаем запрос
tcp, err = lutron_login()
if not tcp then
log('no connection to device', err)
else
-- send some request
tcp:send('?HVAC,11,15\r\n')
-- and receive answer
x = tcp:receive()
-- log answer, or write it to message address
log(x)
tcp:close()
end
Posts: 1764
Threads: 6
Joined: Jul 2015
Reputation:
117
12.10.2016, 14:15
(This post was last modified: 12.10.2016, 14:16 by Erwin van der Zwart.)
Hi AEK,
We did this Lutron link 2 years ago on a big project.
Keep in mind to send a telegam once every x period otherwise the TCP connection will be closed (after 12 hours i believe) by Lutron.
We included a mechanisme to request date or time every hour from the Lutron server to keep the connection alive.
BR,
Erwin
Posts: 155
Threads: 12
Joined: Sep 2015
Reputation:
13
(12.10.2016, 14:15)Erwin van der Zwart Wrote: Hi AEK,
We did this Lutron link 2 years ago on a big project.
Keep in mind to send a telegam once every x period otherwise the TCP connection will be closed (after 12 hours i believe) by Lutron.
We included a mechanisme to request date or time every hour from the Lutron server to keep the connection alive.
BR,
Erwin
Hi, Erwin!
thanks for your advice.
there will be request of current temperature every N minutes in our case, so I think there will be no problem.
if you did this 2 years ago, could you post your code here to?
I'm not programmer, so i understand my code only partially
Posts: 400
Threads: 88
Joined: Jul 2016
Reputation:
3
Hi Erwin,
is it possible to have some suggestion about Lutron integration? In the next week I will have to integrate it.
Let me know if it could be possible.
Thanks.
Posts: 15
Threads: 2
Joined: Nov 2022
Reputation:
0
(02.02.2017, 17:44)Domoticatorino Wrote: Hi Erwin,
is it possible to have some suggestion about Lutron integration? In the next week I will have to integrate it.
Let me know if it could be possible.
Thanks.
I am integrating knx keypad and lutron controller using Logic Machine, I am able to send command but how do I get the status message from lutron please help.
Posts: 7773
Threads: 42
Joined: Jun 2015
Reputation:
447
What kind of status do you want to get? Do you already know the required status request message that should be sent to Lutron?
Posts: 15
Threads: 2
Joined: Nov 2022
Reputation:
0
(14.11.2022, 16:36)admin Wrote: What kind of status do you want to get? Do you already know the required status request message that should be sent to Lutron?
I just want to get On/off status and brightness value. No, how to send the required status to lutron? Please guide.
Posts: 7773
Threads: 42
Joined: Jun 2015
Reputation:
447
Which commands are you using for control? The status command is similar but it begins with ? instead of # and the last parameter (value) is skipped. This example parses HVAC query: https://forum.logicmachine.net/showthrea...97#pid2197
You will need a separate resident script for status queries.
Posts: 15
Threads: 2
Joined: Nov 2022
Reputation:
0
(21.11.2022, 08:12)admin Wrote: Which commands are you using for control? The status command is similar but it begins with ? instead of # and the last parameter (value) is skipped. This example parses HVAC query: https://forum.logicmachine.net/showthrea...97#pid2197
You will need a separate resident script for status queries.
I am using this event based script to send command, can you please share the resident script for the same.
require('user.lutron')
tcp, err = lutron_login()
if not tcp then
log('no connection to device', err)
end
tcp end('#DEVICE,10,6,3\r\n')
Posts: 7773
Threads: 42
Joined: Jun 2015
Reputation:
447
Try this, no guarantees that it will work because we don't have any Lutron devices to test. Check Logs for any errors if the script does not work.
Adjust each query call as needed. First argument is the query request (without \r\n, it's added automatically), second argument is the status group address where the new value is written.
Code: require('user.lutron')
sock, err = lutron_login()
if not sock then
log('no connection to device', err)
os.sleep(5)
end
function close(err)
sock:close()
sock = nil
log('receive failed', err)
end
function query(req, out)
if not sock then
return
end
sock:send(req .. '\r\n')
local res, err = sock:receive()
if not res then
return close(err)
end
if res:sub(1, 1) ~= '~' then
return close('invalid reply ' .. res)
end
if res:sub(2, #req) ~= req:sub(2) then
return close('invalid reply ' .. res)
end
local val = res:sub(#req + 2)
val = tonumber(val)
if val then
grp.checkupdate(out, val)
end
end
while sock do
query('?DEVICE,10,6,3', '1/1/1')
query('?DEVICE,10,1,2', '1/1/2')
query('?DEVICE,10,3,4', '1/1/3')
if sock then
os.sleep(5) -- delay between each poll cycle
else
break
end
end
Posts: 15
Threads: 2
Joined: Nov 2022
Reputation:
0
(22.11.2022, 12:29)admin Wrote: Try this, no guarantees that it will work because we don't have any Lutron devices to test. Check Logs for any errors if the script does not work.
Adjust each query call as needed. First argument is the query request (without \r\n, it's added automatically), second argument is the status group address where the new value is written.
Code: require('user.lutron')
sock, err = lutron_login()
if not sock then
log('no connection to device', err)
os.sleep(5)
end
function close(err)
sock:close()
sock = nil
log('receive failed', err)
end
function query(req, out)
if not sock then
return
end
sock:send(req .. '\r\n')
local res, err = sock:receive()
if not res then
return close(err)
end
if res:sub(1, 1) ~= '~' then
return close('invalid reply ' .. res)
end
if res:sub(2, #req) ~= req:sub(2) then
return close('invalid reply ' .. res)
end
local val = res:sub(#req + 2)
val = tonumber(val)
if val then
grp.checkupdate(out, val)
end
end
while sock do
query('?DEVICE,10,6,3', '1/1/1')
query('?DEVICE,10,1,2', '1/1/2')
query('?DEVICE,10,3,4', '1/1/3')
if sock then
os.sleep(5) -- delay between each poll cycle
else
break
end
end
The script you have shared worked, but sometimes it goes into the sleep mode or update the status very late. Also How do I get the brightness status through this script. I am using the event based script to send the brightness value command to lutron. Please guide
require('user.lutron')
tcp, err = lutron_login()
if not tcp then
log('no connection to device', err)
end
value = event.getvalue()
value = math.floor(value)
tcp end('#OUTPUT,151,1,'..value..'\r\n')
Posts: 7773
Threads: 42
Joined: Jun 2015
Reputation:
447
What is the resident script sleep time set to?
For outputs use this query format:
Code: query('?OUTPUT,151,1', '1/1/151')
Posts: 15
Threads: 2
Joined: Nov 2022
Reputation:
0
(29.11.2022, 10:14)admin Wrote: What is the resident script sleep time set to?
For outputs use this query format:
Code: query('?OUTPUT,151,1', '1/1/151')
Sleep Interval for script is set to 0,
while sock do
query('?OUTPUT,151,1', '0/0/2')
query('?OUTPUT,151,1', '0/0/4')
I am using this but I it is updating the ON/OFF status only in the script but not giving me the value. First One is for ON/OFF status and second one is for the BR value, '0/0/2' is 1-bit object and '0/0/4' is 1byte Scale object.
Posts: 7773
Threads: 42
Joined: Jun 2015
Reputation:
447
Add logging to the query function like this and post what you get in Logs tab:
Code: function query(req, out)
if not sock then
return
end
sock:send(req .. '\r\n')
local res, err = sock:receive()
if not res then
return close(err)
end
if res:sub(1, 1) ~= '~' then
return close('invalid reply ' .. res)
end
if res:sub(2, #req) ~= req:sub(2) then
return close('invalid reply ' .. res)
end
local val = res:sub(#req + 2)
log('response', req, out, val)
val = tonumber(val)
if val then
grp.checkupdate(out, val)
end
end
Posts: 15
Threads: 2
Joined: Nov 2022
Reputation:
0
(29.11.2022, 10:35)admin Wrote: Add logging to the query function like this and post what you get in Logs tab:
Code: function query(req, out)
if not sock then
return
end
sock:send(req .. '\r\n')
local res, err = sock:receive()
if not res then
return close(err)
end
if res:sub(1, 1) ~= '~' then
return close('invalid reply ' .. res)
end
if res:sub(2, #req) ~= req:sub(2) then
return close('invalid reply ' .. res)
end
local val = res:sub(#req + 2)
log('response', req, out, val)
val = tonumber(val)
if val then
grp.checkupdate(out, val)
end
end
Lutron Status 29.11.2022 16:17:17
* arg: 1
* string: receive failed
* arg: 2
* string: invalid reply QNET> ~OUTPUT,151,1,11.00
Lutron Status 29.11.2022 16:17:17
* arg: 1
* string: receive failed
* arg: 2
* string: invalid reply NET>
Lutron Status 29.11.2022 16:17:17
* arg: 1
* string: receive failed
* arg: 2
* string: invalid reply NET>
Lutron Status 29.11.2022 16:17:18
* arg: 1
* string: receive failed
* arg: 2
* string: invalid reply QNET> ~OUTPUT,151,1,11.00
Lutron Status 29.11.2022 16:17:18
* arg: 1
* string: receive failed
* arg: 2
* string: invalid reply QNET> ~OUTPUT,151,1,11.00
Lutron Status 29.11.2022 16:17:18
* arg: 1
* string: no connection to device
* arg: 2
* nil
Lutron Status 29.11.2022 16:17:23
* arg: 1
* string: receive failed
* arg: 2
* string: invalid reply QNET> ~OUTPUT,151,1,11.00
Posts: 7773
Threads: 42
Joined: Jun 2015
Reputation:
447
Try this query function:
Code: function query(req, out)
if not sock then
return
end
sock:send(req .. '\r\n')
local res, err = sock:receive()
if not res then
return close(err)
end
local pos = res:find('~')
if not pos then
return close('invalid reply1 ' .. res)
end
res = res:sub(pos)
if res:sub(2, #req) ~= req:sub(2) then
return close('invalid reply2 ' .. res)
end
local val = res:sub(#req + 2)
log('response', req, out, val)
val = tonumber(val)
if val then
grp.checkupdate(out, val)
end
end
Posts: 15
Threads: 2
Joined: Nov 2022
Reputation:
0
(29.11.2022, 11:01)admin Wrote: Try this query function:
Code: function query(req, out)
if not sock then
return
end
sock:send(req .. '\r\n')
local res, err = sock:receive()
if not res then
return close(err)
end
local pos = res:find('~')
if not pos then
return close('invalid reply1 ' .. res)
end
res = res:sub(pos)
if res:sub(2, #req) ~= req:sub(2) then
return close('invalid reply2 ' .. res)
end
local val = res:sub(#req + 2)
log('response', req, out, val)
val = tonumber(val)
if val then
grp.checkupdate(out, val)
end
end
Now this is working great, but still sometimes are status update is immediate, but many times it is taking significant amount of time to update.
Posts: 7773
Threads: 42
Joined: Jun 2015
Reputation:
447
You can lower the sleep time between polling cycles by modifying this line (currently it's 5 seconds):
Code: os.sleep(5) -- delay between each poll cycle
Posts: 15
Threads: 2
Joined: Nov 2022
Reputation:
0
(29.11.2022, 11:16)admin Wrote: You can lower the sleep time between polling cycles by modifying this line (currently it's 5 seconds):
Code: os.sleep(5) -- delay between each poll cycle
I have made it 1 second. Now it is working fine, I hope it will work when I add more data points.
Thank You Very much for your support.
|