1 | -- |
---|
2 | -- |
---|
3 | module("L_LutronRA2Telnet1", package.seeall) |
---|
4 | local g_username = "" |
---|
5 | local g_password = "" |
---|
6 | local pollPeriod = "" |
---|
7 | local pollPeriodOccupancy = "5" |
---|
8 | local index = 0 |
---|
9 | local log = luup.log |
---|
10 | local socket = require("socket") |
---|
11 | local flagConnect = false |
---|
12 | local flagSendCredentials = true |
---|
13 | local ipAddress = "" |
---|
14 | local ipPort = "" |
---|
15 | local DEBUG_MODE = false |
---|
16 | local g_lastTripFlag = false |
---|
17 | local g_occupancyFlag = false |
---|
18 | |
---|
19 | local SID = { |
---|
20 | ["LUTRON"] = "urn:schemas-micasaverde-com:serviceId:LutronRA2Telnet1", |
---|
21 | ["SW_POWER"] = "urn:upnp-org:serviceId:SwitchPower1", |
---|
22 | ["DIMMER"] = "urn:upnp-org:serviceId:Dimming1", |
---|
23 | ["BLINDS"] = "urn:upnp-org:serviceId:WindowCovering1", |
---|
24 | ["SHADEGRP"] = "urn:upnp-org:serviceId:WindowCovering1", |
---|
25 | ["KEYPAD"] = "urn:upnp-org:serviceId:LutronKeypad1", |
---|
26 | ["AREA"] = "urn:micasaverde-com:serviceId:SecuritySensor1", |
---|
27 | } |
---|
28 | local DEVTYPE = { |
---|
29 | ["SW_POWER"] = "urn:schemas-upnp-org:device:BinaryLight:1", |
---|
30 | ["DIMMER"] = "urn:schemas-upnp-org:device:DimmableLight:1", |
---|
31 | ["BLINDS"] = "urn:schemas-micasaverde-com:device:WindowCovering:1", |
---|
32 | ["SHADEGRP"] = "urn:schemas-micasaverde-com:device:WindowCovering:1", |
---|
33 | ["KEYPAD"] = "urn:schemas-micasaverde-com:device:LutronKeypad:1", |
---|
34 | ["AREA"] = "urn:schemas-micasaverde-com:device:MotionSensor:1" |
---|
35 | } |
---|
36 | |
---|
37 | local errorMessage = { |
---|
38 | ["1"] = "Parameter count mismatch", |
---|
39 | ["2"] = "Object does not exist", |
---|
40 | ["3"] = "Invalid action number", |
---|
41 | ["4"] = "Parameter data out of range", |
---|
42 | ["5"] = "Parameter data malformed", |
---|
43 | ["6"] = "Unsupported Command" |
---|
44 | } |
---|
45 | |
---|
46 | local deviceActionNumber = { |
---|
47 | ["3"] = "Press / Close / Occupied", |
---|
48 | ["4"] = "Release / Open / Unoccupied", |
---|
49 | ["9"] = "Set (#) or Get (?) LED State", |
---|
50 | ["14"] = "Set or Get Light Level", |
---|
51 | ["18"] = "Start Raising", |
---|
52 | ["19"] = "Start Lowering", |
---|
53 | ["20"] = "Stop Raising / Lowering", |
---|
54 | ["22"] = "Get battery status", |
---|
55 | ["23"] = "Set a custom lift and tilt level of venetian blinds programmed to the phantom button", |
---|
56 | ["24"] = "Set a custom lift level only of venetian blinds programmed to the phantom button", |
---|
57 | ["25"] = "Set a custom tilt level only of venetian blinds programmed to the phantom button" |
---|
58 | } |
---|
59 | |
---|
60 | local outputActionNumber = { |
---|
61 | ["1"] = "Set or Get Zone Level", |
---|
62 | ["2"] = "Start Raising", |
---|
63 | ["3"] = "Start Lowering", |
---|
64 | ["4"] = "Stop Raising / Lowering", |
---|
65 | ["5"] = "Start Flash", |
---|
66 | ["6"] = "Pulse", |
---|
67 | ["9"] = "Set (#) or Get (?) Venetian tilt level only", |
---|
68 | ["10"] = "Set (#) or Get (?) Venetian lift & tilt level", |
---|
69 | ["11"] = "Start raising Venetian tilt", |
---|
70 | ["12"] = "Start lowering Venetian tilt", |
---|
71 | ["13"] = "Stop Venetian tilt", |
---|
72 | ["14"] = "Start raising Venetian lift", |
---|
73 | ["15"] = "Start lowering Venetian lift", |
---|
74 | ["16"] = "Stop Venetian lift" |
---|
75 | } |
---|
76 | |
---|
77 | local shadegroupActionNumber = { |
---|
78 | ["1"] = "Set or Get Zone Level", |
---|
79 | ["2"] = "Start Raising", |
---|
80 | ["3"] = "Start Lowering", |
---|
81 | ["4"] = "Stop Raising / Lowering", |
---|
82 | ["6"] = "Set (#) or Get (?) Current Preset", |
---|
83 | ["14"] = "Set (#) Venetian Tilt", |
---|
84 | ["15"] = "Set (#) Lift and Tilt for venetians", |
---|
85 | ["16"] = "Raise Venetian Tilt", |
---|
86 | ["17"] = "Lower Venetian Tilt", |
---|
87 | ["18"] = "Stop Venetian Tilt", |
---|
88 | ["19"] = "Raise Venetian Lift", |
---|
89 | ["20"] = "Lower Venetian Lift", |
---|
90 | ["21"] = "Stop Venetian Lift", |
---|
91 | ["28"] = "Get Horizontal Sheer Shade Region" |
---|
92 | } |
---|
93 | |
---|
94 | local g_childDevices = { |
---|
95 | -- .id -> vera id |
---|
96 | -- .integrationId -> lutron internal id |
---|
97 | -- .devType -> device type (dimmer, blinds , binary light or keypad) |
---|
98 | -- .fadeTime |
---|
99 | -- .componentNumber = {} -> only for keypads |
---|
100 | } |
---|
101 | |
---|
102 | ------------------------------------------------------------------------------------------ |
---|
103 | local function debug() end |
---|
104 | ------------------------------------------------------------------------------------------ |
---|
105 | function sendCmd(command) |
---|
106 | -- [[ |
---|
107 | local cmd = command |
---|
108 | local startTime, endTime |
---|
109 | local dataSize = string.len(cmd) |
---|
110 | assert(dataSize <= 135) |
---|
111 | startTime = socket.gettime() |
---|
112 | luup.sleep(200) |
---|
113 | if (luup.io.write(cmd) == false) then |
---|
114 | log("(Lutron RA2 Gateway PLugin)::(sendCmd) : Cannot send command " .. command .. " communications error") |
---|
115 | return false |
---|
116 | end |
---|
117 | endTime = socket.gettime() |
---|
118 | debug("(Lutron RA2 Gateway PLugin)::(debug)::(sendCmd) : Sending cmd = [" .. cmd .. "]") |
---|
119 | debug("(Lutron RA2 Gateway PLugin)::(debug)::(sendCmd) : Request returned in " .. math.floor((endTime - startTime) * 1000) .. "ms") |
---|
120 | luup.sleep(100) |
---|
121 | -- ]] |
---|
122 | -- debug("(Lutron RA2 Gateway PLugin)::(debug)::(sendCmd) : Sending cmd = [" .. command .. "]") |
---|
123 | return true |
---|
124 | end |
---|
125 | local function setUI(parameters, cmdType) |
---|
126 | local devType = "" |
---|
127 | local id = -1 |
---|
128 | local index = 1 |
---|
129 | for key,value in pairs(g_childDevices) do |
---|
130 | if value.integrationId == parameters[index] then |
---|
131 | devType = value.devType |
---|
132 | id = value.id |
---|
133 | end |
---|
134 | end |
---|
135 | if cmdType == "OUTPUT" then |
---|
136 | index = index + 1 |
---|
137 | if parameters[index] == "1" then |
---|
138 | if devType == "SW_POWER" then |
---|
139 | local val = tonumber(parameters[index + 1]) |
---|
140 | if val == 100 or val == 1 then |
---|
141 | luup.variable_set(SID["SW_POWER"],"Status","1",id) |
---|
142 | else |
---|
143 | luup.variable_set(SID["SW_POWER"],"Status","0",id) |
---|
144 | end |
---|
145 | debug("(Lutron RA2 Gateway PLugin)::(debug)::(setUI) : SW_POWER : UI has been set") |
---|
146 | elseif devType == "DIMMER" or devType == "BLINDS" then |
---|
147 | luup.variable_set(SID["DIMMER"],"LoadLevelStatus", parameters[index + 1], id) |
---|
148 | debug("(Lutron RA2 Gateway PLugin)::(debug)::(setUI) : DIMMER or BLINDS : UI has been set") |
---|
149 | else |
---|
150 | debug("(Lutron RA2 Gateway PLugin)::(debug)::(setUI) : Unknown command type! ") |
---|
151 | end |
---|
152 | end |
---|
153 | elseif cmdType == "SHADEGRP" then |
---|
154 | index = index + 1 |
---|
155 | if parameters[index] == "1" then |
---|
156 | if devType == "SHADEGRP" then |
---|
157 | luup.variable_set(SID["SHADEGRP"],"LoadLevelStatus", parameters[index + 1], id) |
---|
158 | debug("(Lutron RA2 Gateway PLugin)::(debug)::(setUI) : SHADEGROUP : UI has been set") |
---|
159 | end |
---|
160 | end |
---|
161 | elseif cmdType == "AREA" then |
---|
162 | if parameters[3] == "3" then |
---|
163 | luup.variable_set(SID["AREA"], "Tripped", "1", id) |
---|
164 | if not g_lastTripFlag then |
---|
165 | luup.variable_set(SID["AREA"], "LastTrip", os.time(), id) |
---|
166 | g_lastTripFlag = true |
---|
167 | end |
---|
168 | debug("(Lutron RA2 Gateway PLugin)::(debug)::(setUI) : AREA : Device " .. id .. " has been tripped!") |
---|
169 | elseif parameters[3] == "4" then |
---|
170 | luup.variable_set(SID["AREA"], "Tripped", "0", id) |
---|
171 | if g_lastTripFlag then |
---|
172 | g_lastTripFlag = false |
---|
173 | end |
---|
174 | debug("(Lutron RA2 Gateway PLugin)::(debug)::(setUI) : AREA : Device " .. id .. "is not tripped!") |
---|
175 | else |
---|
176 | debug("(Lutron RA2 Gateway PLugin)::(debug)::(setUI) : AREA : Unknown parameters received!!! " .. tostring(parameters[3])) |
---|
177 | end |
---|
178 | else |
---|
179 | index = index + 1 |
---|
180 | if parameters[index + 1] == "3" then |
---|
181 | luup.variable_set(SID["LUTRON"],"KeypadCommand",parameters[index],id) |
---|
182 | debug("(Lutron RA2 Gateway PLugin)::(debug)::(setUI) : DEVICE : Unknown command type! ") |
---|
183 | end |
---|
184 | end |
---|
185 | end |
---|
186 | ------------------------------------------------------------------------------------------ |
---|
187 | local RESPONSES_HANDLERS = { |
---|
188 | |
---|
189 | ["OUTPUT"] = function ( parameters) -- param[1] = Integration ID |
---|
190 | debug("(Lutron RA2 Gateway PLugin)::(debug)::(RESPONSES_HANDLERS) : OUTPUT : PARAMETER received :" .. parameters) |
---|
191 | local param = {} -- param[2] = Action Number |
---|
192 | local k = 0 -- param[3-5] = Parameters |
---|
193 | for v in parameters:gmatch("(.-),") do |
---|
194 | k = k + 1 |
---|
195 | param[k] = v |
---|
196 | end |
---|
197 | -------------- |
---|
198 | setUI(param,"OUTPUT") |
---|
199 | debug("(Lutron RA2 Gateway PLugin)::(debug)::(RESPONSES_HANDLERS) : OUTPUT : " .. outputActionNumber[param[2]] .." for device with Integration ID :" .. param[1]) |
---|
200 | end, |
---|
201 | |
---|
202 | ["DEVICE"] = function ( parameters) -- param[1] = Integration ID |
---|
203 | debug("(Lutron RA2 Gateway PLugin)::(debug)::(RESPONSES_HANDLERS) : DEVICE : PARAMETER received :" .. parameters) |
---|
204 | local param = {} -- param[2] = Component number |
---|
205 | local k = 0 -- param[3] = Action Number |
---|
206 | for v in parameters:gmatch("(.-),") do -- param[4-6] = Parameters |
---|
207 | k = k + 1 |
---|
208 | param[k] = v |
---|
209 | end |
---|
210 | -------------- |
---|
211 | setUI(param,"DEVICE") |
---|
212 | debug("(Lutron RA2 Gateway PLugin)::(debug)::(RESPONSES_HANDLERS) : DEVICE : " .. deviceActionNumber[param[3]] .." for device with Component number : " .. param[2] .. " and Integration ID : " .. param[1] ) |
---|
213 | end, |
---|
214 | |
---|
215 | ["SHADEGRP"] = function ( parameters) -- param[1] = Integration ID |
---|
216 | debug("(Lutron RA2 Gateway PLugin)::(debug)::(RESPONSES_HANDLERS) : SHADEGRP : PARAMETER received :" .. parameters) |
---|
217 | local param = {} -- param[2] = Action Number |
---|
218 | local k = 0 -- param[3-6] = Parameters |
---|
219 | for v in parameters:gmatch("(.-),") do |
---|
220 | k = k + 1 |
---|
221 | param[k] = v |
---|
222 | end |
---|
223 | -------------- |
---|
224 | setUI(param,"SHADEGRP") |
---|
225 | debug("(Lutron RA2 Gateway PLugin)::(debug)::(RESPONSES_HANDLERS) : SHADEGRP : " .. shadegroupActionNumber[param[2]] .." for device with Integration ID : " .. param[1] ) |
---|
226 | end, |
---|
227 | |
---|
228 | ["AREA"] = function ( parameters) -- param[1] = Integration ID |
---|
229 | debug("(Lutron RA2 Gateway PLugin)::(debug)::(RESPONSES_HANDLERS) : SHADEGRP : PARAMETER received :" .. parameters) |
---|
230 | local param = {} -- param[2] = Action Number |
---|
231 | local k = 0 -- param[3-6] = Parameters |
---|
232 | for v in parameters:gmatch("(.-),") do |
---|
233 | k = k + 1 |
---|
234 | param[k] = v |
---|
235 | end |
---|
236 | -------------- |
---|
237 | setUI(param,"AREA") |
---|
238 | debug("(Lutron RA2 Gateway PLugin)::(debug)::(RESPONSES_HANDLERS) : AREA : Setting Occupancy State") |
---|
239 | end, |
---|
240 | |
---|
241 | ["ERROR"] = function ( parameters) |
---|
242 | local param = parameters:sub(1,1) |
---|
243 | debug("(Lutron RA2 Gateway PLugin)::(debug)::(RESPONSES_HANDLERS) : ERROR : " .. errorMessage[param]) |
---|
244 | end |
---|
245 | } |
---|
246 | ------------------------------------------------------------------------------------------ |
---|
247 | function handleResponse(data) |
---|
248 | debug("(Lutron RA2 Gateway PLugin)::(debug)::(handleResponse) : data received:'" .. data .. "'") |
---|
249 | local param = "" |
---|
250 | local cmd = string.match(data,"(%u+)") or "" |
---|
251 | |
---|
252 | if flagSendCredentials == false then |
---|
253 | if data:find("login") then |
---|
254 | sendCmd(g_username) |
---|
255 | sendCmd(g_password) |
---|
256 | end |
---|
257 | end |
---|
258 | if cmd == "" then |
---|
259 | debug("(Lutron RA2 Gateway PLugin)::(debug)::(handleResponse) : 1 Unknown or unhandled message received") |
---|
260 | else |
---|
261 | if cmd == "GNET" then |
---|
262 | data = string.gsub(data,"GNET> ","") |
---|
263 | cmd = string.match(data,"(%u+)") |
---|
264 | end |
---|
265 | end |
---|
266 | if cmd == "OUTPUT" or cmd == "DEVICE" then |
---|
267 | param = string.match(data, ",(.*)") .. "," |
---|
268 | RESPONSES_HANDLERS[cmd](param) |
---|
269 | elseif cmd == "ERROR" then |
---|
270 | param = string.match(data, ",(.*)") |
---|
271 | RESPONSES_HANDLERS[cmd](param) |
---|
272 | elseif cmd == "SHADEGRP" then |
---|
273 | param = string.match(data, ",(.*)") .. "," |
---|
274 | RESPONSES_HANDLERS[cmd](param) |
---|
275 | elseif cmd == "AREA" then |
---|
276 | param = string.match(data, ",(.*)") .. "," |
---|
277 | RESPONSES_HANDLERS[cmd](param) |
---|
278 | else |
---|
279 | debug("(Lutron RA2 Gateway PLugin)::(debug)::(handleResponse) : 2 Unknown or unhandled message received") |
---|
280 | end |
---|
281 | return true |
---|
282 | end |
---|
283 | ------------------------------------------------------------------------------------------ |
---|
284 | |
---|
285 | |
---|
286 | ------------------------------------------------------------------------------------------ |
---|
287 | local function SplitString (str, delimiter) |
---|
288 | delimiter = delimiter or "%s+" |
---|
289 | local result = {} |
---|
290 | local from = 1 |
---|
291 | local delimFrom, delimTo = str:find( delimiter, from ) |
---|
292 | while delimFrom do |
---|
293 | table.insert( result, str:sub( from, delimFrom-1 ) ) |
---|
294 | from = delimTo + 1 |
---|
295 | delimFrom, delimTo = str:find( delimiter, from ) |
---|
296 | end |
---|
297 | table.insert( result, str:sub( from ) ) |
---|
298 | return result |
---|
299 | end |
---|
300 | |
---|
301 | local function getDevices(device) |
---|
302 | local dev = luup.variable_get(SID["LUTRON"],"DeviceList",device) or "" |
---|
303 | if dev == "" then |
---|
304 | luup.variable_set(SID["LUTRON"],"DeviceList","",lug_device) |
---|
305 | return false |
---|
306 | else |
---|
307 | -- Parse the DeviceData variable. |
---|
308 | local deviceList = SplitString( dev, ';' ) |
---|
309 | for k,v in pairs(deviceList) do |
---|
310 | local typedev = v:sub(1,1) |
---|
311 | for val in v:gmatch("(%d+)") do |
---|
312 | index = index + 1 |
---|
313 | g_childDevices[index] = {} |
---|
314 | g_childDevices[index].id = -1 |
---|
315 | if typedev == "D" then |
---|
316 | g_childDevices[index].integrationId = val |
---|
317 | g_childDevices[index].devType = "DIMMER" |
---|
318 | elseif typedev == "B" then |
---|
319 | g_childDevices[index].integrationId = val |
---|
320 | g_childDevices[index].devType = "BLINDS" |
---|
321 | elseif typedev == "S" then |
---|
322 | g_childDevices[index].integrationId = val |
---|
323 | g_childDevices[index].devType = "SW_POWER" |
---|
324 | elseif typedev == "K" then |
---|
325 | g_childDevices[index].integrationId = val |
---|
326 | g_childDevices[index].devType = "KEYPAD" |
---|
327 | elseif typedev == "G" then |
---|
328 | g_childDevices[index].integrationId = val |
---|
329 | g_childDevices[index].devType = "SHADEGRP" |
---|
330 | elseif typedev == "A" then |
---|
331 | g_childDevices[index].integrationId = val |
---|
332 | g_childDevices[index].devType = "AREA" |
---|
333 | else |
---|
334 | log("(Lutron RA2 Gateway PLugin)::(getDevices) : ERROR : DeviceList spelling error found") |
---|
335 | end |
---|
336 | end |
---|
337 | end |
---|
338 | end |
---|
339 | return true |
---|
340 | end |
---|
341 | |
---|
342 | local function appendDevices(device) |
---|
343 | local ptr = luup.chdev.start(device) |
---|
344 | local index = 0 |
---|
345 | for key, value in pairs(g_childDevices) do |
---|
346 | if value.devType == "DIMMER" then |
---|
347 | luup.chdev.append(device,ptr, value.integrationId,"DIMMER_" .. value.integrationId,DEVTYPE[value.devType],"D_DimmableLight1.xml","","",false) |
---|
348 | elseif value.devType == "BLINDS" then |
---|
349 | luup.chdev.append(device,ptr, value.integrationId,"BLINDS_" .. value.integrationId,DEVTYPE[value.devType],"D_WindowCovering1.xml","","",false) |
---|
350 | elseif value.devType == "SW_POWER" then |
---|
351 | luup.chdev.append(device,ptr, value.integrationId,"BINARY_LIGHT_" .. value.integrationId,DEVTYPE[value.devType],"D_BinaryLight1.xml","","",false) |
---|
352 | elseif value.devType == "KEYPAD" then |
---|
353 | luup.chdev.append(device,ptr, value.integrationId,"KEYPAD_" .. value.integrationId,DEVTYPE[value.devType],"D_LutronKeypad1.xml","","",false) |
---|
354 | elseif value.devType == "SHADEGRP" then |
---|
355 | luup.chdev.append(device,ptr, value.integrationId,"SHADEGRP_" .. value.integrationId,DEVTYPE[value.devType],"D_WindowCovering1.xml","","",false) |
---|
356 | elseif value.devType == "AREA" then |
---|
357 | luup.chdev.append(device,ptr, value.integrationId,"AREA_" .. value.integrationId,DEVTYPE[value.devType],"D_MotionSensor1.xml","","",false) |
---|
358 | g_occupancyFlag = true |
---|
359 | else |
---|
360 | log("(Lutron RA2 Gateway PLugin)::(appendDevices) : ERROR : Unknown device type!") |
---|
361 | end |
---|
362 | if index > 49 then |
---|
363 | log("(Lutron RA2 Gateway PLugin)::(appendDevices) : ERROR : High number of new devices to create, possible ERROR!") |
---|
364 | break |
---|
365 | end |
---|
366 | end |
---|
367 | luup.chdev.sync(device,ptr) |
---|
368 | end |
---|
369 | |
---|
370 | local function getComponentNumber(id) |
---|
371 | local list = luup.variable_get(SID["LUTRON"],"componentNumber",id) |
---|
372 | local flagError = true |
---|
373 | local componentNumber = {} |
---|
374 | local sub = list:gmatch("(%d+)") |
---|
375 | local index = 1 |
---|
376 | for v in sub do |
---|
377 | componentNumber[index] = v |
---|
378 | index = index + 1 |
---|
379 | end |
---|
380 | for key,value in pairs(g_childDevices) do |
---|
381 | if value.id == id then |
---|
382 | g_childDevices[key].componentNumber = {} |
---|
383 | for i = 1, 6 do |
---|
384 | if componentNumber[i] then |
---|
385 | g_childDevices[key].componentNumber[i] = componentNumber[i] |
---|
386 | else |
---|
387 | log("(Lutron RA2 Gateway PLugin)::(getComponentNumber) : ERROR : 'componentNumber' error for device : " .. id) |
---|
388 | flagError = false |
---|
389 | end |
---|
390 | end |
---|
391 | end |
---|
392 | end |
---|
393 | return flagError |
---|
394 | end |
---|
395 | |
---|
396 | ------------------------------------------------------------------------------------------ |
---|
397 | local function setChildID(device) |
---|
398 | local flagError = true |
---|
399 | for key, value in pairs(luup.devices) do |
---|
400 | if value.device_num_parent == device then |
---|
401 | for k,v in pairs(g_childDevices) do |
---|
402 | if v.integrationId == value.id then |
---|
403 | g_childDevices[k].id = key |
---|
404 | end |
---|
405 | end |
---|
406 | end |
---|
407 | end |
---|
408 | |
---|
409 | for key,value in pairs(g_childDevices) do |
---|
410 | if value.devType == "KEYPAD" then |
---|
411 | local componentNumber = luup.variable_get(SID["LUTRON"],"componentNumber",value.id) or "" |
---|
412 | if componentNumber == "" or componentNumber == "default" then |
---|
413 | luup.variable_set(SID["LUTRON"],"componentNumber","default",value.id) |
---|
414 | log("(Lutron RA2 Gateway PLugin)::(setChildID) : ERROR : 'componentNumber' cannot be 'null' or 'default' for device " .. value.id) |
---|
415 | flagError = false |
---|
416 | else |
---|
417 | flagError = getComponentNumber(value.id) |
---|
418 | end |
---|
419 | elseif value.devType == "SHADEGRP" then |
---|
420 | local delay = luup.variable_get(SID[value.devType],"delayTime",value.id) or "" |
---|
421 | if delay == "" then |
---|
422 | g_childDevices[key].delay = "0" |
---|
423 | luup.variable_set(SID[value.devType],"delayTime","0",value.id) |
---|
424 | else |
---|
425 | g_childDevices[key].delay = delay |
---|
426 | end |
---|
427 | else |
---|
428 | local fadeTime = luup.variable_get(SID[value.devType],"fadeTime",value.id) or "" |
---|
429 | if fadeTime == "" then |
---|
430 | g_childDevices[key].fadeTime = "0" |
---|
431 | luup.variable_set(SID[value.devType],"fadeTime","0",value.id) |
---|
432 | else |
---|
433 | g_childDevices[key].fadeTime = fadeTime |
---|
434 | end |
---|
435 | end |
---|
436 | end |
---|
437 | return flagError |
---|
438 | end |
---|
439 | |
---|
440 | local function getInfo(device) |
---|
441 | local flagError = true |
---|
442 | g_username = luup.devices[device].user or "" |
---|
443 | g_password = luup.devices[device].pass or "" |
---|
444 | local period = luup.variable_get(SID["LUTRON"],"pollPeriod", device) or "" |
---|
445 | if g_username == "" or g_password == "" or g_username == "default" or g_password == "default" then |
---|
446 | luup.attr_set("username","default",device) |
---|
447 | luup.attr_set("password","default",device) |
---|
448 | log( "(Lutron RA2 Gateway PLugin)::(getInfo) : ERROR : Username or Password field cannot be blank or default!" ) |
---|
449 | flagError = false |
---|
450 | end |
---|
451 | if period == "" then |
---|
452 | pollPeriod = "30" |
---|
453 | luup.variable_set(SID["LUTRON"], "pollPeriod", pollPeriod, device) |
---|
454 | debug("(Lutron RA2 Gateway PLugin)::(debug)::(getInfo) : ERROR : Polling period set to default value!" ) |
---|
455 | else |
---|
456 | pollPeriod = period |
---|
457 | end |
---|
458 | local trash |
---|
459 | ipAddress, trash, ipPort = string.match(luup.devices[lug_device].ip, "^([%w%.%-]+)(:?(%d-))$") |
---|
460 | if ipAddress and ipAddress ~= "" then |
---|
461 | if ipPort==nil or ipPort == "" then |
---|
462 | ipPort = "23" |
---|
463 | end |
---|
464 | flagConnect = true |
---|
465 | else |
---|
466 | log("(Lutron RA2 Gateway PLugin)::(getInfo) : ERROR : Insert IP address!") |
---|
467 | flagError = false |
---|
468 | end |
---|
469 | return flagError |
---|
470 | end |
---|
471 | -------------------- |
---|
472 | ------ACTIONS------- |
---|
473 | function setTarget(device,value) |
---|
474 | local integrationId = "" |
---|
475 | local cmd = "" |
---|
476 | local fadeTime = "" |
---|
477 | for k,v in pairs(g_childDevices) do |
---|
478 | if v.id == device then |
---|
479 | integrationId = v.integrationId |
---|
480 | fadeTime = v.fadeTime |
---|
481 | end |
---|
482 | end |
---|
483 | luup.variable_set(SID["SW_POWER"], "Status", value, device) |
---|
484 | if value == "1" then |
---|
485 | value = 100 |
---|
486 | end |
---|
487 | cmd = "#OUTPUT," .. integrationId .. ",1," .. value .. "," .. fadeTime |
---|
488 | sendCmd(cmd) |
---|
489 | debug("(Lutron RA2 Gateway PLugin)::(debug)::(setTarget) : Sending command :'" .. cmd .."' ...") |
---|
490 | end |
---|
491 | |
---|
492 | function setArmed(device,value) |
---|
493 | luup.variable_set(SID["AREA"], "Armed", value, device) |
---|
494 | debug("(Lutron RA2 Gateway PLugin)::(debug)::(setArmed) : Device Arm Status was set to " .. value) |
---|
495 | end |
---|
496 | |
---|
497 | function setLoadLevelTarget(device,value) |
---|
498 | local integrationId = "" |
---|
499 | local devType = "" |
---|
500 | local cmd = "" |
---|
501 | local fadeTime |
---|
502 | local delay |
---|
503 | for k,v in pairs(g_childDevices) do |
---|
504 | if v.id == device then |
---|
505 | integrationId = v.integrationId |
---|
506 | devType = v.devType |
---|
507 | if devType == "SHADEGRP" then |
---|
508 | delay = v.delay |
---|
509 | else |
---|
510 | fadeTime = v.fadeTime |
---|
511 | end |
---|
512 | end |
---|
513 | end |
---|
514 | if devType == "SHADEGRP" then |
---|
515 | cmd = "#SHADEGRP," .. integrationId .. ",1," .. value .. "," .. delay |
---|
516 | else |
---|
517 | cmd = "#OUTPUT," .. integrationId .. ",1," .. value .. "," .. fadeTime |
---|
518 | end |
---|
519 | sendCmd(cmd) |
---|
520 | debug("(Lutron RA2 Gateway PLugin)::(debug)::(setLoadLevelTarget) : Sending command :'" .. cmd .."' ...") |
---|
521 | end |
---|
522 | function blindsUP(device) |
---|
523 | local integrationId = "" |
---|
524 | local devType = "" |
---|
525 | local cmd = "" |
---|
526 | for k,v in pairs(g_childDevices) do |
---|
527 | if v.id == device then |
---|
528 | integrationId = v.integrationId |
---|
529 | devType = v.devType |
---|
530 | end |
---|
531 | end |
---|
532 | |
---|
533 | if devType == "SHADEGRP" then |
---|
534 | cmd = "#SHADEGRP," .. integrationId .. ",2" |
---|
535 | else |
---|
536 | cmd = "#OUTPUT," .. integrationId .. ",2" |
---|
537 | end |
---|
538 | sendCmd(cmd) |
---|
539 | debug("(Lutron RA2 Gateway PLugin)::(debug)::(blindsUP) : Sending command :'" .. cmd .."' ...") |
---|
540 | end |
---|
541 | function blindsDown(device) |
---|
542 | local integrationId = "" |
---|
543 | local devType = "" |
---|
544 | local cmd = "" |
---|
545 | for k,v in pairs(g_childDevices) do |
---|
546 | if v.id == device then |
---|
547 | integrationId = v.integrationId |
---|
548 | devType = v.devType |
---|
549 | end |
---|
550 | end |
---|
551 | if devType == "SHADEGRP" then |
---|
552 | cmd = "#SHADEGRP," .. integrationId .. ",3" |
---|
553 | else |
---|
554 | cmd = "#OUTPUT," .. integrationId .. ",3" |
---|
555 | end |
---|
556 | sendCmd(cmd) |
---|
557 | debug("(Lutron RA2 Gateway PLugin)::(debug)::(blindsDown) : Sending command :'" .. cmd .."' ...") |
---|
558 | end |
---|
559 | function blindsStop(device) |
---|
560 | local integrationId = "" |
---|
561 | local devType = "" |
---|
562 | local cmd = "" |
---|
563 | for k,v in pairs(g_childDevices) do |
---|
564 | if v.id == device then |
---|
565 | integrationId = v.integrationId |
---|
566 | devType = v.devType |
---|
567 | end |
---|
568 | end |
---|
569 | if devType == "SHADEGRP" then |
---|
570 | cmd = "#SHADEGRP," .. integrationId .. ",4" |
---|
571 | else |
---|
572 | cmd = "#OUTPUT," .. integrationId .. ",4" |
---|
573 | end |
---|
574 | sendCmd(cmd) |
---|
575 | debug("(Lutron RA2 Gateway PLugin)::(debug)::(blindsStop) : Sending command :'" .. cmd .."' ...") |
---|
576 | end |
---|
577 | function sendCommandButton(value) |
---|
578 | if value then |
---|
579 | local first = value:sub(1,1) |
---|
580 | if first ~= "?" and first ~= "~" then |
---|
581 | value = "#" .. value |
---|
582 | sendCmd(value) |
---|
583 | debug("(Lutron RA2 Gateway PLugin)::(debug)::(sendCommandButton) : Sending command :'" .. value .."' ...") |
---|
584 | else |
---|
585 | sendCmd(value) |
---|
586 | debug("(Lutron RA2 Gateway PLugin)::(debug)::(sendCommandButton) : Sending command :'" .. value .."' ...") |
---|
587 | end |
---|
588 | else |
---|
589 | log("(Lutron RA2 Gateway PLugin)::(sendCommandButton) : Field cannot be null") |
---|
590 | end |
---|
591 | end |
---|
592 | function sendCommandKeypad(device, value) |
---|
593 | local integrationId = "" |
---|
594 | local componentNumber = {} |
---|
595 | for key,value in pairs(g_childDevices) do |
---|
596 | if value.id == device then |
---|
597 | integrationId = value.integrationId |
---|
598 | for i= 1,6 do |
---|
599 | componentNumber[i] = value.componentNumber[i] |
---|
600 | end |
---|
601 | end |
---|
602 | end |
---|
603 | if componentNumber[tonumber(value)] == "0" then |
---|
604 | log("(Lutron RA2 Gateway PLugin)::(sendCommandKeypad) : No scene attached to this button!") |
---|
605 | else |
---|
606 | local cmd = "#DEVICE," .. integrationId .. "," .. componentNumber[tonumber(value)] .. "," .. "3" |
---|
607 | sendCmd(cmd) |
---|
608 | debug("(Lutron RA2 Gateway PLugin)::(debug)::(sendCommandKeypad) : Device <" .. device .. "> with Integration ID <" .. integrationId .. "> running scene <" .. componentNumber[tonumber(value)] .. ">" ) |
---|
609 | end |
---|
610 | luup.variable_set(SID["LUTRON"],"KeypadCommand",value,device) |
---|
611 | end |
---|
612 | |
---|
613 | function getStatus(value) |
---|
614 | local cmd = "" |
---|
615 | local period = tonumber(value) |
---|
616 | for key, value in pairs(g_childDevices) do |
---|
617 | if value.devType == "DIMMER" or value.devType == "BLINDS" or value.devType == "SW_POWER" then |
---|
618 | cmd = "?OUTPUT," .. value.integrationId .. ",1" |
---|
619 | sendCmd(cmd) |
---|
620 | else |
---|
621 | if value.devType == "SHADEGRP" then |
---|
622 | cmd = "?SHADEGRP," .. value.integrationId .. ",1" |
---|
623 | sendCmd(cmd) |
---|
624 | end |
---|
625 | end |
---|
626 | end |
---|
627 | luup.call_delay("getStatus", period, value) |
---|
628 | debug("(Lutron RA2 Gateway PLugin)::(debug)::(getStatus) : Status checked") |
---|
629 | end |
---|
630 | |
---|
631 | function getOccupancyStatus(value) |
---|
632 | local cmd = "" |
---|
633 | local period = tonumber(value) |
---|
634 | for key, value in pairs(g_childDevices) do |
---|
635 | if value.devType == "AREA" then |
---|
636 | cmd = "?AREA," .. value.integrationId .. ",8" |
---|
637 | sendCmd(cmd) |
---|
638 | end |
---|
639 | end |
---|
640 | luup.call_delay("getOccupancyStatus", period, value) |
---|
641 | debug("(Lutron RA2 Gateway PLugin)::(debug)::(getOccupancyStatus) : Occupancy Status checked") |
---|
642 | end |
---|
643 | |
---|
644 | local function checkVersion() |
---|
645 | local ui7Check = luup.variable_get(SID["LUTRON"], "UI7Check", lug_device) or "" |
---|
646 | |
---|
647 | if ui7Check == "" then |
---|
648 | luup.variable_set(SID["LUTRON"], "UI7Check", "false", lug_device) |
---|
649 | ui7Check = "false" |
---|
650 | end |
---|
651 | |
---|
652 | if( luup.version_branch == 1 and luup.version_major == 7 ) then |
---|
653 | luup.variable_set(SID["LUTRON"], "UI7Check", "true", lug_device) |
---|
654 | return true |
---|
655 | else |
---|
656 | luup.variable_set(SID["LUTRON"], "UI7Check", "false", lug_device) |
---|
657 | return false |
---|
658 | end |
---|
659 | end |
---|
660 | |
---|
661 | -------------------- |
---|
662 | function Init (lul_device) |
---|
663 | lug_device = lul_device |
---|
664 | local debugMode = luup.variable_get( SID["LUTRON"], "DebugMode", lug_device ) or "" |
---|
665 | if debugMode == "" then |
---|
666 | luup.variable_set( SID["LUTRON"], "DebugMode", (DEBUG_MODE and "1" or "0"), lug_device ) |
---|
667 | else |
---|
668 | DEBUG_MODE = (debugMode == "1") and true or false |
---|
669 | end |
---|
670 | |
---|
671 | if DEBUG_MODE then |
---|
672 | debug = log |
---|
673 | end |
---|
674 | local flagError = getDevices(lug_device) |
---|
675 | local flagError2 = getInfo(lug_device) |
---|
676 | --[[ |
---|
677 | ------------------------------------------------------------------------------ |
---|
678 | appendDevices(lug_device) |
---|
679 | local flagError3 = setChildID(lug_device) |
---|
680 | getStatus(pollPeriod) |
---|
681 | if g_occupancyFlag then |
---|
682 | getOccupancyStatus(pollPeriodOccupancy) |
---|
683 | end |
---|
684 | ------------------------------------------------------------------------------ |
---|
685 | -- ]] |
---|
686 | -- [[ |
---|
687 | if flagError and flagError2 then |
---|
688 | appendDevices(lug_device) |
---|
689 | local flagError3 = setChildID(lug_device) |
---|
690 | if flagError3 == false then |
---|
691 | log( "(Lutron RA2 Gateway PLugin)::(Startup) : ERROR : Startup failed! " ) |
---|
692 | return |
---|
693 | end |
---|
694 | else |
---|
695 | if flagError == false then |
---|
696 | log( "(Lutron RA2 Gateway PLugin)::(Startup) : ERROR : Insert Devices List " ) |
---|
697 | end |
---|
698 | log( "(Lutron RA2 Gateway PLugin)::(Startup) : ERROR : Startup failed! " ) |
---|
699 | return |
---|
700 | end |
---|
701 | if flagConnect then |
---|
702 | log(string.format ("(Lutron RA2 Gateway PLugin)::(Startup) : ipAddress=%s, ipPort=%s", tostring (ipAddress), tostring (ipPort))) |
---|
703 | luup.io.open (lug_device, ipAddress, ipPort) |
---|
704 | if luup.io.is_connected(lug_device) == false then |
---|
705 | log("(Lutron RA2 Gateway PLugin)::(Startup) : ERROR : Could not connect to the device!") |
---|
706 | return |
---|
707 | else |
---|
708 | log("(Lutron RA2 Gateway PLugin)::(Startup) : OK : Connection established, continuing startup ...") |
---|
709 | sendCmd(g_username) |
---|
710 | luup.sleep(500) |
---|
711 | sendCmd(g_password) |
---|
712 | flagSendCredentials = false |
---|
713 | getStatus(pollPeriod) |
---|
714 | if g_occupancyFlag then |
---|
715 | getOccupancyStatus(pollPeriodOccupancy) |
---|
716 | end |
---|
717 | end |
---|
718 | else |
---|
719 | log( "(Lutron RA2 Gateway PLugin)::(Startup) : ERROR : Insert IP address!" ) |
---|
720 | end |
---|
721 | -- ]] |
---|
722 | if checkVersion() then |
---|
723 | luup.set_failure(0, lul_device) |
---|
724 | end |
---|
725 | log( "(Lutron RA2 Gateway PLugin)::(Startup) : Startup Successful " ) |
---|
726 | return true |
---|
727 | end |
---|