Author Topic: Creating triggers from luup code  (Read 23418 times)

Offline dunked

  • Jr. Member
  • **
  • Posts: 88
  • Karma: +3/-0
Creating triggers from luup code
« on: August 04, 2013, 11:32:24 am »
Hi,

I have over 10 door and motion sensors. I've written some luup code to alert me (using Vera Alerts - great app!) when they get tripped and also they get logged to a mysql database using some php code as well. That all works very well.

My issue is that I've done this by creating a scene for every sensor that calls my luup function, passing in a device id - so that's a lot of scenes I've had to manually create - and I'm wondering if there is a better way (it's not very tidy!). I have tried creating one scene and manually creating lots of triggers for it (one for each sensor) that seems to be working but again that's a lot of manual triggers to create.

I'd rather somehow automate this in my lua startup to run some code that can read through all my devices of a certain type (e.g. door sensors) and create a trigger for each of them that calls my function. I've not seen any obvious way to do that (create the trigger  that is, I know how to read the device list)

The only way I can think of is to use variable_watch checking for changes to "Tripped" I've not tried that yet and worry about how efficient and quick it might be. But I do wonder if that is what the Vera is doing internally whenever you create a trigger for a scene.

Does anyone know or have any ideas? I'd appreciate some guidance.

Thanks

Offline RichardTSchaefer

  • Master Member
  • *******
  • Posts: 10061
  • Karma: +759/-141
Re: Creating triggers from luup code
« Reply #1 on: August 05, 2013, 11:13:34 pm »
You can replace the many scenes with many triggers in 1 scene ... one for each trigger.
In the LUA you can set a variable indicating witch trigger caused the scene to wake up.

In the Scene Level LUA you can do the common code, using the variable that was set by the trigger level lua code.

Or you can use the Program Logic Event Generator plugin.


Offline akbooer

  • Master Member
  • *******
  • Posts: 5882
  • Karma: +251/-69
  • "Less is more"
Re: Creating triggers from luup code
« Reply #2 on: August 06, 2013, 08:14:05 am »
I know it's not popular with some folk, but since you know how to scan the device list, then why don't you just poll the required sensors with a one minute scheduled scene?
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 dunked

  • Jr. Member
  • **
  • Posts: 88
  • Karma: +3/-0
Re: Creating triggers from luup code
« Reply #3 on: August 23, 2013, 08:51:27 pm »
Thanks for the replies - it's taken me a while to get them as I've been away on holiday (... seems like distant memory already ...)

I spotted the trick with many triggers in each scene and had a go - but it still didn't meet my insane desire to do it in code rather than muck around in the Vera UI.

I had a look at PLEG some time back, I think it could work, but, I want to learn more about luup coding and write my own. So I'm determined to do it the hard way!
And yes polling could be a plan B, but it would add a performance hit.
There must be some code internally to the Vera that sets up triggers and I'm guessing that it's something like variable_watch - but not sure enough to stake my life on it! What I don't know is just how reliable variable_watch is.

So what I've done is run some tests using variable_watch to watch for SwitchPower1 status changes - so capturing when lights etc. are turned on and off - it does seem to work consistently well - there are too many such events to be absolutely sure none have been missed, but all the ones I know about have been fine.
and rather than write a loop to go through the device list  I just manually added a variable_watch line for each device in my startup code using notepad++ it's a doddle to copy and paste those and a darn sight easier than setting up all those scenes and triggers manually.

So I think I'll bite the bullet and add variable_watch for all my security sensors too. If it goes horribly wrong I'll report back.

Cheers

Offline akbooer

  • Master Member
  • *******
  • Posts: 5882
  • Karma: +251/-69
  • "Less is more"
Re: Creating triggers from luup code
« Reply #4 on: August 24, 2013, 02:00:19 am »
So it's really about event logging rather than triggering per se.  Have you looked at all the discussion on alternative notification?  See http://forum.micasaverde.com/index.php/topic,15245.0.html.

For variable_watch, it's pretty fundamental to how the system works, and lots of very trusted apps (DataMine an example, I think) use this. No reason to suppose what you are planning won't work.

Let us know how it goes!
« Last Edit: August 24, 2013, 02:03:06 am by akbooer »
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 parkerc

  • Sr. Hero Member
  • ******
  • Posts: 2405
  • Karma: +33/-45
  • Life Moves Pretty Fast....
Re: Creating triggers from luup code
« Reply #5 on: September 12, 2013, 04:35:53 pm »
How did it go @dunked?

I'm always interest to see the code people use..

Offline dunked

  • Jr. Member
  • **
  • Posts: 88
  • Karma: +3/-0
Re: Creating triggers from luup code
« Reply #6 on: September 15, 2013, 07:31:48 am »
Well so far so good. I've had this running for over a week now. I did decide on a simple loop in my code that sets a callback on all my sensors (that way if I add a sensor or take one out it gets picked up automatically) and it all seems very reliable.

My callback is getting more complicated as initially I used it just to log events to a database, now I have it sending alerts to my phone if a sensor is armed (using Vera Alerts), and I've just added a bit more code to help me manage my automatic lights (if a light gets turned manually off and back on then it resets a variable which stops any timers running that would turn it off automatically).

To akbooer's point I hadn't spotted the alternate event server you pointed me at. It won't work for me as I want to run LUA code on the Vera when something happens, but I may well use it another time.

My current challenge is to tweak my code so that I can spot if a device is actually owned by another Vera (I have 3 with some bridging), so that I don't start tracking a device from another Vera if that one is also tracking it - luckily I think using the parent device id will help with that.

I still don't know for sure but my guess is that when you set a trigger using the Vera UI it's just adding a variable_watch to its own code. I wondered if that was the case when I started this thread, I'm more confident now. I wonder if the Vera's own routines are written in LUA and I can find them somewhere to check this out.

Offline akbooer

  • Master Member
  • *******
  • Posts: 5882
  • Karma: +251/-69
  • "Less is more"
Re: Creating triggers from luup code
« Reply #7 on: September 15, 2013, 08:31:22 am »
Good to hear.  Can you be explicit about where you have the code running?  I've never had any luck with callbacks in startup or scene code.

Regarding the alternate server, I'm excited to have found an old post by @TOP320
http://forum.micasaverde.com/index.php/topic,9525.msg91855.html#msg91855
which shows how to run that server locally on the Vera, opening up a host of opportunities to do the sort of things you are doing.  I just can't understand why this hasn't been taken up in the discussions on this topic.  I'm obviously missing something.

« Last Edit: September 15, 2013, 09:54:08 am by akbooer »
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 dunked

  • Jr. Member
  • **
  • Posts: 88
  • Karma: +3/-0
Re: Creating triggers from luup code
« Reply #8 on: September 15, 2013, 10:30:24 am »
The technique I use for running my code stemmed from what seems to be best advice from the forums (and it works so I'm happy).
Essentially I have 2 Vera 3s and a Vera Lite. I have one lua file for each of them and a common file. These are where I keep all my code - most of the code is in my common file as it contains routines that all the veras use. So in my case I have 4 files -
my_common_code.lua
my_vera_house_code.lua
my_vera_stables_code.lua
my_vera_study_code.lua

So in the Apps/ Develop Apps / Luup files section I upload two files to each Vera - The common one and the one specific to that device. So for my Study one (which is my test Vera) I upload my_common_code.lua and my_vera_study_code.lua.

Then in the Edit Startup Lua section I have two lines
require("my_common_code.lua")
require("my_vera_study_code.lua")


those require statements tell the vera that when it starts up to load those two files and run whatever's in them.

I'm an old fashioned programmer so I prefer procedural rather than Object Oriented programming so my common code file is full of functions such as turn_device_on(dev_id). When the startup runs those functions all get loaded (as part of that require statement above) and then I can call the function from luup code in a scene e.g. turn_device_on(26)

Hope that all makes sense.

Offline akbooer

  • Master Member
  • *******
  • Posts: 5882
  • Karma: +251/-69
  • "Less is more"
Re: Creating triggers from luup code
« Reply #9 on: September 15, 2013, 10:56:23 am »
@dunked

Thanks for the speedy reply with very full information.  And, in fact, yes, I do all that too with the only difference being that I have exactly the same files 'required' on all three machines and they auto-configure depending of what installed devices they find.

One utility code I use everywhere maps device names to IDs so that helps with machine independence too.

My problem is simply that when I've tried to use any callback like variable watch or timers, etc., then the function supplied as a named string in the setup call is never found and generates a runtime error when the event occurs.  What am I doing wrong ??
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 dunked

  • Jr. Member
  • **
  • Posts: 88
  • Karma: +3/-0
Re: Creating triggers from luup code
« Reply #10 on: September 15, 2013, 11:15:16 am »
The error messages can be a pain and really unhelpful sometimes  >:(

Here are some genuine working code snippets.

luup.variable_watch("device_power_state_change", "urn:upnp-org:serviceId:SwitchPower1","Status", 112)

sets up the callback to the function pasted below

function device_power_state_change(dev_id,service, variable, old_val, new_val)
   -- called when a device is switched on or off - from a variable_watch
   if new_val == "1" then
      device_switched_on_or_off(dev_id,"true")         -- NOTE WE ARE USING A TEXT STRING FOR TRUE NOT A BOOLEAN VALUE
   else
      device_switched_on_or_off(dev_id,"false")
   end
end


as an aside(and you may know this already) but when I'm testing a function (such as that above) if you copy and paste it into the test luup code box and run it, it will seemingly do nothing but it does get registered, so then you can clear the text box and happily call it. If it doesn't work right then you can tweak the code in an editor and then paste the function in again and it will use the new code. Of course as soon as you restart Lua for whatever reason the function goes back to what's defined in your luup files. Doing it this way means you haven't got to save your code and upload it each time.

Offline akbooer

  • Master Member
  • *******
  • Posts: 5882
  • Karma: +251/-69
  • "Less is more"
Re: Creating triggers from luup code
« Reply #11 on: September 15, 2013, 11:38:48 am »
Thanks, will give it a go again.

Re. your "aside", yes indeed, I'm a proponent of the approach to Vera development...
http://forum.micasaverde.com/index.php/topic,14815.msg112418.html#msg112418

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 dunked

  • Jr. Member
  • **
  • Posts: 88
  • Karma: +3/-0
Re: Creating triggers from luup code
« Reply #12 on: September 15, 2013, 01:20:32 pm »
Aha! I should have read your post a few months back!

I just realised you also mentioned timers so here's working call_delay code snippet

luup.call_delay('turn_off_device_timer', timer_value,dev_id_string)    

and the first two lines of the function

function turn_off_device_timer(dev_id_string)
   -- called as a call_delay timer, does a few checks and turns a device off, for example if light level has been changed then don't turn device off

Good luck with the callbacks.

(I'm making a concerted effort to see if I can use eclipse for my LUA development before I start my next project - trying to build a very simple web UI for the rest of the family to use!)

Offline parkerc

  • Sr. Hero Member
  • ******
  • Posts: 2405
  • Karma: +33/-45
  • Life Moves Pretty Fast....
Re: Creating triggers from luup code
« Reply #13 on: September 15, 2013, 01:33:32 pm »
Hi @dunked

Here are some genuine working code snippets.

luup.variable_watch("device_power_state_change", "urn:upnp-org:serviceId:SwitchPower1","Status", 112)

sets up the callback to the function pasted below

function device_power_state_change(dev_id,service, variable, old_val, new_val)
   -- called when a device is switched on or off - from a variable_watch
   if new_val == "1" then
      device_switched_on_or_off(dev_id,"true")         -- NOTE WE ARE USING A TEXT STRING FOR TRUE NOT A BOOLEAN VALUE
   else
      device_switched_on_or_off(dev_id,"false")
   end
end

Please forgive the non programmer question, but what goes next in the code? I'm keen to monitor an obscure variable on a thermostat. E.g if variable ModeStatus is set to 'HeatOn' or 'Off' - if it's 'HeatOn' then I want to do something like notify me or run a scene.?
« Last Edit: September 15, 2013, 01:36:03 pm by parkerc »

Offline akbooer

  • Master Member
  • *******
  • Posts: 5882
  • Karma: +251/-69
  • "Less is more"
Re: Creating triggers from luup code
« Reply #14 on: September 15, 2013, 01:46:38 pm »
Please forgive the non programmer question, but what goes next in the code? I'm keen to monitor an obscure variable on a thermostat. E.g if variable ModeStatus is set to 'HeatOn' or 'Off' - if it's 'HeatOn' then I want to do something like notify me or run a scene.?

Nothing "next" really. The function...

Code: [Select]
function device_power_state_change(dev_id,service, variable, old_val, new_val)
-- called when a device is switched on or off - from a variable_watch

end

...is exactly what the comment says.  You can put whatever you like in the body to call a notification plugin or whatever.

Sorry if that's not a complete answer for you.  Just ask again.
@dunked can probably do better.

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.