We have moved at community.getvera.com

Author Topic: Issue with getting device info using Luup.devices command  (Read 4604 times)

Offline pasqualz

  • Sr. Newbie
  • *
  • Posts: 41
  • Karma: +2/-0
Issue with getting device info using Luup.devices command
« on: May 14, 2014, 12:00:51 am »

Hi all,
I'm trying to create a scene using Luup script that checks all of my window & door sensors to see if they're tripped or not. I know that I can create a bunch of if/then statements with the device id hard coded for each sensor i currently have, then add a new if/then statement with the device I'd whenever I add another sensor. BUT, I'd rather have my scene check for all devices of the correct type, then loop through them. Obviously this is better because my scene automatically checks new sensors without me having to add them manually. I've been fooling around with the Luup.devices command to accomplish this, but my first issue is that it appears that there my device ids are not contiguous and it causes my scene to error and stop. Below is my test code which loops through device ids 21 through 32, and logs whether or not a actual device is present for that I'd number. This is not working, as you can see below the script, I copied the Luup log entries that are produced. When this scene runs. The first id number (21) has an actual device (my wife's garage door sensor,) and the log output is beautiful, but the next ID number (22) has no device and it appears to break. Can anyone explain why it breaks and how I can fix my script? Perhaps there's an easier way to get all of my sensor devices loaded into an array for easy access???

for d=21,32 do
 if luup.devices[d].id == nil then
  luup.log('=> No device with that id!')
 else
  luup.log('===>Device # ' .. d .. ' id: ' .. luup.devices[d].id .. ' name: ' .. luup.devices[d].description .. ' type: ' .. luup.devices[d].device_type .. ' category: ' .. luup.devices[d].category_num)
end


Luup.log entries
50   05/13/14 23:31:30.591   luup_log:0: ===>Device # 21 id: 18 name: C Garage Door type: urn:schemas-micasaverde-com:device:DoorSensor:1 category: 4 <0x2e2bd680>
01   05/13/14 23:31:30.591   LuaInterface::CallFunction_Scene Scene  52 failed [string "function scene_51()..."]:12: attempt to index field '?' (a nil value) <0x2e2bd680>

Offline RexBeckett

  • Beta Testers
  • Master Member
  • *****
  • Posts: 3891
  • Karma: +483/-12
Re: Issue with getting device info using Luup.devices command
« Reply #1 on: May 14, 2014, 02:31:26 am »
There will be no entry in the luup.device() table for any device that has been deleted. If you are searching through the table by device number, you need to test for a nil entry before attempting to index it. An alternative is to use something like:

Code: [Select]
for deviceNo,d in pairs(luup.devices) do
    if d.device_type == "<device-type-you-want>" then
         luup.log('===>Device # ' .. deviceNo .. ' id: ' .. d.id .. ' name: ' .. d.description .. ' type: ' .. d.device_type .. ' category: ' .. d.category_num)
    end
end

Offline pasqualz

  • Sr. Newbie
  • *
  • Posts: 41
  • Karma: +2/-0
Re: Issue with getting device info using Luup.devices command
« Reply #2 on: May 14, 2014, 11:02:47 pm »
Rex, thanks for sending me in the right direction! I created the following script around your suggested code and it mostly works. One issue though. When I uncomment the four lines of code at the end, I get Lua errors. Is there an issue with my syntax or is it an issue with calling local variables?

local vol = 60
local son = 33
local devcnt = 0
local numopen = 0
luup.log('Commencing device search loop')
for deviceNo,d in pairs(luup.devices) do
    if d.category_num == 4 then
      luup.log('===>Device # ' .. deviceNo .. ' id: ' .. d.id ..  ' category: ' .. d.category_num .. ' room: ' .. d.room_num .. ' name: ' .. d.description .. ' type: ' .. d.device_type)
      local tripped = luup.variable_get(d.device_type, "Tripped", d.id)
      if (tripped == "1") then
        luup.call_action("urn:micasaverde-com:serviceId:Sonos1", "Say",
     {Text=d.description .. " is Open", Language="en", Volume=vol}, son)
      luup.log(d.description .. " status was " .. tripped)
        numopen = numopen + 1
      else
        luup.log(d.description .. " status was " .. tripped)
      end
      devcnt = devcnt + 1
    end
end
--[[
if numopen == 0 then
luup.call_action("urn:micasaverde-com:serviceId:Sonos1", "Say", {Text="All windows and doors are closed", Language="en", Volume=vol}, son)
end
--]]
luup.log('All done! There were ' .. devcnt .. ' door/window sensors found and .. ' numopen ' .. open')

Offline PJJP

  • Full Member
  • ***
  • Posts: 149
  • Karma: +2/-0
Re: Issue with getting device info using Luup.devices command
« Reply #3 on: May 14, 2014, 11:57:24 pm »
maybe you could also try looping through and using devices with the parent id of your alarm pane.

Offline akbooer

  • Beta Testers
  • Master Member
  • *****
  • Posts: 6387
  • Karma: +291/-70
  • "Less is more"
Re: Issue with getting device info using Luup.devices command
« Reply #4 on: May 15, 2014, 02:42:15 am »
Quote
luup.log('All done! There were ' .. devcnt .. ' door/window sensors found and .. ' numopen ' .. open')

Should be

Quote
luup.log('All done! There were ' .. devcnt .. ' door/window sensors found and ' .. numopen .. ' open')
3x Vera Lite-UI5/Edge-UI7, 25x Fibaro, 23x TKB, 9x MiniMote, 2x NorthQ Power, 2x Netatmo, 1x Foscam FI9831P, 9x Philips Hue,
Razberry, MySensors Arduino, HomeWave, AltUI, AltHue, DataYours, Grafana, openLuup, ZWay, ZeroBrane Studio.

Offline pasqualz

  • Sr. Newbie
  • *
  • Posts: 41
  • Karma: +2/-0
Re: Issue with getting device info using Luup.devices command
« Reply #5 on: May 15, 2014, 12:05:11 pm »
akbooer, thanks for catching my errant apostrophe. I fixed that part and the lua code stopped causing an error. Now I have another issue. I modified my code so that inside the for loop, I'm checking the tripped status of each device. Unfortunately, this command keeps failing when I run the scene. It works fine with an actual number, but I can't seem to use a variable in its place. It seems that the d.id works in my luup.log line, but doesn't work in the local tripped = line. I've tried several ways to pass the id f the device but they all do not work. The code is below with the two lines I'm talking about in bold and the lua log errors are below that. Any help would be greatly appreciated!

local vol = 10
local son = 33
local devcnt = 0
local devno = 0
local numopen = 0
luup.log('Commencing device search loop')
for deviceNo,d in pairs(luup.devices) do
    if d.category_num == 4 then
      luup.log('Device #' .. deviceNo .. ' id:' .. d.id ..  ' category:' .. d.category_num .. ' room:' .. d.room_num .. ' name:' .. d.description .. ' type: ' .. d.device_type)
     
      local tripped = luup.variable_get("urn:micasaverde-com:serviceId:SecuritySensor1", "Tripped", d.id)
      if (tripped == "1") then
        luup.call_action("urn:micasaverde-com:serviceId:Sonos1", "Say", {Text=d.description .. " is Open", Language="en", Volume=vol}, son)
        luup.log(d.description .. " status was " .. tripped)
        numopen = numopen + 1
      else
        luup.log(d.description .. " status was " .. tripped)
      end
      devcnt = devcnt + 1
    end
end
if numopen == 0 then
  luup.call_action("urn:micasaverde-com:serviceId:Sonos1", "Say", {Text="All windows and doors are closed", Language="en", Volume=vol}, son)
end

luup.log('All done! There were ' .. devcnt .. ' door/window sensors found and ' .. numopen ' .. open')

<=======================>

50   05/15/14 11:18:57.969   luup_log:0: Commencing device search loop <0x2d8c3680>
50   05/15/14 11:18:57.970   luup_log:0: Device #21 id:18 category:4 room:8 name:C Garage Door type: urn:schemas-micasaverde-com:device:DoorSensor:1 <0x2d8c3680>
01   05/15/14 11:18:57.971   LuaInterface::CallFunction_Scene Scene  52 failed [string "function scene_51()..."]:27: attempt to concatenate local 'tripped' (a nil value) <0x2d8c3680>

Offline RexBeckett

  • Beta Testers
  • Master Member
  • *****
  • Posts: 3891
  • Karma: +483/-12
Re: Issue with getting device info using Luup.devices command
« Reply #6 on: May 15, 2014, 12:23:35 pm »
Use deviceNo instead of d.id. d.id is the node of Z-Wave devices.

A trick to avoid code errors in these circumstances is to do this:

local tripped = luup.variable_get("urn:micasaverde-com:serviceId:SecuritySensor1", "Tripped", deviceNo) or "Nil"

This will give tripped the string value "Nil" if the luup.variable_get(...) returns nil. At least it will show-up in the log.
« Last Edit: May 15, 2014, 12:29:01 pm by RexBeckett »

Offline pasqualz

  • Sr. Newbie
  • *
  • Posts: 41
  • Karma: +2/-0
Re: Issue with getting device info using Luup.devices command
« Reply #7 on: May 15, 2014, 02:10:00 pm »
Rex, Thanks for the info. every time I think I understand, something new comes up that I didn't know! Anyway, the loop works great, but now, I get an error in the if section after the loop. It appears that the numopen variable I use in the loop no longer has a value. I'm aware that in Lua, local variables have a limited scope depending on the block or section they're declared in. I thought that by declaring numopen at the top of the code, it would be accessible everywhere within my code. Perhaps that's not even the issue. Anyway, here's the if code section followed by the error from the log.

if numopen == 0 then
  luup.call_action("urn:micasaverde-com:serviceId:Sonos1", "Say", {Text="All windows and doors are closed", Language="en", Volume=vol}, son)
end

<====================>

01   05/15/14 12:43:56.111   LuaInterface::CallFunction_Scene Scene  52 failed [string "function scene_51()..."]:34: attempt to call local 'numopen' (a number value) <0x2d4c1680>

Offline RexBeckett

  • Beta Testers
  • Master Member
  • *****
  • Posts: 3891
  • Karma: +483/-12
Re: Issue with getting device info using Luup.devices command
« Reply #8 on: May 15, 2014, 06:19:51 pm »
Declaring the variable ahead of the for loop should make it accessible both inside the loop and after it. Anyway, the error does not say it has a nil value but that you are trying to call it... The error also indicates that the problem is at line 34 but the code you posted earlier is only 26 lines. Please post your current code.

If you post it as code (use the # button), we can see the exact lines.
« Last Edit: May 15, 2014, 06:22:59 pm by RexBeckett »

Offline pasqualz

  • Sr. Newbie
  • *
  • Posts: 41
  • Karma: +2/-0
Re: Issue with getting device info using Luup.devices command
« Reply #9 on: May 15, 2014, 09:02:16 pm »
Rex, again, thanks for all you expert advice. Somehow it's working and I'm not so sure what I did. I think I've been mostly committing syntax errors and eventually worked them out. I have one more piece of the code to test and then I'll post it here for anyone else who might want a similar scene.
Thanks! Pasqual

Offline pasqualz

  • Sr. Newbie
  • *
  • Posts: 41
  • Karma: +2/-0
Re: Issue with getting device info using Luup.devices command
« Reply #10 on: May 15, 2014, 11:13:02 pm »
Ok, so it's finally working reliably. This script checks for all connected door/window sensors and announces how many there are and if any are open (tripped.) I plan to have two scenes, one for upstairs sonos and one for downstairs. The variables should be self explanatory.

Please Note: This scene requires the Sonis plugin to work correctly!

Feel free to reply with questions, comments, improvements, etc. Just needs some polish to make the speech slower and it will be dynamite!

-- Door/Window sensor check and speech annotation by Pasqual Zottola
local vol = 50
local son = 27 --mast bdr =33, kitch=27
local devcnt = 0
local devno = 0
local numopen = 0
local isare = "is"
local opensensors = " "
luup.log('Commencing sensor device search loop')
for deviceNo,d in pairs(luup.devices) do
   if d.category_num == 4 then
           
      local tripped = luup.variable_get("urn:micasaverde-com:serviceId:SecuritySensor1", "Tripped", deviceNo) or "Nil"
     
      if (tripped == "1") then
         opensensors = opensensors .. ". " .. d.description
         --[[ This line will change to recording info to an array so sonos speaks only once.
luup.call_action("urn:micasaverde-com:serviceId:Sonos1", "Say",
     {Text=d.description .. " is Open", Language="en", Volume=vol}, son)
         --]]     
         -- luup.log(d.description .. " status was " .. tripped)
         numopen = numopen + 1
      end
   luup.log(d.description .. ' status:' .. tripped .. ' Dev #' .. deviceNo .. ' id:' .. d.id ..  ' cat #:' .. d.category_num .. ' type:' .. d.device_type)     
   devcnt = devcnt + 1
    end
end
if numopen == 0 then   --If there are no sensors tripped, log and announce!
   luup.log('There were ' .. devcnt .. ' door and window sensors found and all are closed')
   luup.call_action("urn:micasaverde-com:serviceId:Sonos1", "Say", {Text="There were " .. devcnt .. " door and window sensors found, and all are closed", Language="en", Volume=vol}, son)
   
else   --If there are any sensors tripped, log and announce!
   if numopen > 1 then
      isare = "are"
   end
      luup.log('There were ' .. devcnt .. ' door and window sensors found and ' .. numopen .. " " .. isare .. ' open' .. opensensors)
      luup.call_action("urn:micasaverde-com:serviceId:Sonos1", "Say", {Text="There were " .. devcnt .. " sensors found and " .. numopen .. " " .. isare .. " open." .. opensensors, Language="en", Volume=vol}, son)
     
end

Offline Grwebster

  • Sr. Member
  • ****
  • Posts: 388
  • Karma: +7/-4
Re: Issue with getting device info using Luup.devices command
« Reply #11 on: July 22, 2014, 10:45:32 pm »
Nice bit of programming.  Just interested in how it will be used?  Check for proper lockdown before arming?


Sent from my iPad using Tapatalk

Offline pasqualz

  • Sr. Newbie
  • *
  • Posts: 41
  • Karma: +2/-0
Re: Issue with getting device info using Luup.devices command
« Reply #12 on: July 28, 2014, 09:57:56 am »
Grwebster, I have this script in a scene that is scheduled to run at 10pm, 11pm, and 12am. This way, if we leave doors or windows open at night, we get a verbal reminder of which ones so we can close them. I don't currently have a scene configured for alerting me if one of the doors/windows is opened during the night, but that would be a. Simple matter of playing a siren sound through my Sonos system...