Creating triggers from luup code

I’m going to cheat and not check through your code (I’ve got 10 minutes before I have to go out!)

But it looks like you’re trying to call a web page with some parameters - something I do a lot but I do it a different way

function log_temperature_change(dev_id,service, variable, old_val, new_val)
	luup.log("--MC-- ======================== log_temperature_change RUNNING ======================== ")
	local dev_name = get_dev_name(dev_id)
	dev_name = string.gsub(dev_name, "%s", "+")
	dev_name = string.gsub(dev_name,"&","%%26")			-- change & for %26
	local reading_ts_as_datestring = string.gsub(os.date("%Y-%m-%d %H:%M:%S"),"%s","+")
	local url = "http://10.10.10.210/energy/add_temperature_reading.php?dev_name="..dev_name.."&reading_ts="..reading_ts_as_datestring.."&temperature="..new_val
	luup.log(url)
	local result = luup.inet.wget(url, 0)
	luup.log("--MC-- ======================== log_temperature_change ENDED ======================== ")
end

get_dev_name is a function that gets the device name that I wrote (it only has one line of code so you don’t really need it, but it’s neater)

this function is called from a variable_watch also (for devices that report a temperature). I had to spend lot of time working out how to escape characters and encode the URL, and the code above does work so it may save you some time if you hit that problem (particularly where a device name has a space in it).

Have a look and see if it’ll help you. I may get back on line later tonight. but I doubt it.

Cheers

Not quite sure about the semantics or syntax of your http.request (“3=3” “40=40” looks weird), but the key parameters you need from the callback function parameter list are [tt]dev_id[/tt] and [tt]new_val[/tt]. You can use the string concatenation operator “…” to join these to what you will.

For example:

local x = "Var 241 : "
local y = x .. new_val

would result in [tt]y[/tt] having a value of “Var 241 : 42” if the received value of [tt]new_val[/tt] was “42”. You can use identical syntax for [tt]dev_id[/tt] (even though it is, in fact, a number.)

While you are at it, you should remove the “require” statement from the function (put it earlier in the code.) Also, if you’re not going to check the return value of [tt]result[/tt] or [tt]status[/tt] then you don’t need them there.

Hope this helps.

[quote=“dunked, post:41, topic:176379”]I’m going to cheat and not check through your code (I’ve got 10 minutes before I have to go out!)

But it looks like you’re trying to call a web page with some parameters - something I do a lot but I do it a different way

function log_temperature_change(dev_id,service, variable, old_val, new_val)
	luup.log("--MC-- ======================== log_temperature_change RUNNING ======================== ")
	local dev_name = get_dev_name(dev_id)
	dev_name = string.gsub(dev_name, "%s", "+")
	dev_name = string.gsub(dev_name,"&","%%26")			-- change & for %26
	local reading_ts_as_datestring = string.gsub(os.date("%Y-%m-%d %H:%M:%S"),"%s","+")
	local url = "http://10.10.10.210/energy/add_temperature_reading.php?dev_name="..dev_name.."&reading_ts="..reading_ts_as_datestring.."&temperature="..new_val
	luup.log(url)
	local result = luup.inet.wget(url, 0)
	luup.log("--MC-- ======================== log_temperature_change ENDED ======================== ")
end

get_dev_name is a function that gets the device name that I wrote (it only has one line of code so you don’t really need it, but it’s neater)

this function is called from a variable_watch also (for devices that report a temperature). I had to spend lot of time working out how to escape characters and encode the URL, and the code above does work so it may save you some time if you hit that problem (particularly where a device name has a space in it).

Have a look and see if it’ll help you. I may get back on line later tonight. but I doubt it.

Cheers[/quote]

Wow, now you lost me…

Yes I agree. I have just consulted my 3rd party HA Controller community and advised to use the following syntax to send a fixed data value-
(“http://192.168.0.23:3005/HVTableVar.html","Var 241 : 3==”)

Just to confirm the 3 repersents node id number 3 so this is where I need to parse the dev-id. I tried this code below with no luck -
(“http://192.168.0.23:3005/HVTableVar.html","Var 241 : dev-ID==”)
(“http://192.168.0.23:3005/HVTableVar.html","Var 241 : (dev-ID)==”)
(“http://192.168.0.23:3005/HVTableVar.html","Var 241 : “dev-ID”==”)

but the key parameters you need from the callback function parameter list are [b][tt]dev_id[/tt][/b] and [b][tt]new_val[/tt][/b]. You can use the string concatenation operator ".." to join these to what you will.

For example:

local x = "Var 241 : "
local y = x .. new_val

would result in [tt]y[/tt] having a value of “Var 241 : 42” if the received value of [tt]new_val[/tt] was “42”. You can use identical syntax for [tt]dev_id[/tt] (even though it is, in fact, a number.)

I’m not sure I understand what you mean in your above recommendation. Just to confirm the 3rd party HA controller variable number Var 241 needs to have the device ID parsed and Var 242 needs the light level parsed in.

While you are at it, you should remove the "require" statement from the function (put it earlier in the code.) Also, if you're not going to check the return value of [tt][b]result[/b][/tt] or [tt][b]status[/b][/tt] then you don't need them there.

I’m not sure where to put it earlier in the code. Where should it be?

Currently its now looking like this so far (I have taken the macro command out for now as I know that works ok)-

[Code]
luup.variable_watch(“my_function_to_handle_dimming_level_change”, “urn:upnp-org:serviceId:Dimming1”, “LoadLevelStatus”, dev_id)

function my_function_to_handle_dimming_level_change(dev_id,service, variable, old_val, new_val)
– called when a device is switched on or off - from a variable_watch

local http = require(“socket.http”)
http.TIMEOUT = 5
http.request(“http://192.168.0.23:3005/HVTableVar.html","Var 241 : 3==”)
http.request(“http://192.168.0.23:3005/HVTableVar.html","Var 242 : (new_val)==”)
end
[\Code]

I really appreciate the help you guys are giving…

Steve[/code]

So to be even more specific:

local http = require("socket.http")
http.TIMEOUT = 5
local url = "http://192.168.0.23:3005/HVTableVar.html"

function my_function_to_handle_dimming_level_change(dev_id,service, variable, old_val, new_val)
   -- called when a device is switched on or off - from a variable_watch
  http.request(url, "Var 241 : " .. dev_id .. "==")  
  http.request(url, "Var 242 : " .. new_val .. "==")
end

luup.variable_watch("my_function_to_handle_dimming_level_change", "urn:upnp-org:serviceId:Dimming1", "LoadLevelStatus", YOUR_DEV_ID_HERE)

[quote=“akbooer, post:45, topic:176379”]So to be even more specific:

[code]
local http = require(“socket.http”)
http.TIMEOUT = 5
local url = “http://192.168.0.23:3005/HVTableVar.html

function my_function_to_handle_dimming_level_change(dev_id,service, variable, old_val, new_val)
– called when a device is switched on or off - from a variable_watch
http.request(url, "Var 241 : " … dev_id … “==”)
http.request(url, "Var 242 : " … new_val … “==”)
end

luup.variable_watch(“my_function_to_handle_dimming_level_change”, “urn:upnp-org:serviceId:Dimming1”, “LoadLevelStatus”, YOUR_DEV_ID_HERE)

[/code][/quote]

Fantastic! That works a treat.

Many thanks

Steve

Great! Thanks for the karma!!

No thank you for all your help.

Oh, where should I now put the code? Do I just paste it in the “Edit Startup Lua” ?

Steve

Yes, then remember to press GO and then RELOAD.

OR

[ul][li]put it into a file, say “watcher.lua”[/li]
[li]upload the file to Vera from the Luup files page[/li]
[li]put [tt]require “watcher”[/tt] into Lua Startup and then press GO and RESTART[/li][/ul]

so, having written this, I guess just put the code itself into startup!
This will do until you want to get more sophisticated and it gets too long to manage.

[quote=“akbooer, post:49, topic:176379”]Yes, then remember to press GO and then RELOAD.

OR

[ul][li]put it into a file, say “watcher.lua”[/li]
[li]upload the file to Vera from the Luup files page[/li]
[li]put [tt]require “watcher”[/tt] into Lua Startup and then press GO and RESTART[/li][/ul]

so, having written this, I guess just put the code itself into startup!
This will do until you want to get more sophisticated and it gets too long to manage.[/quote]

Sounds like putting the code in it’s own file maybe the best idea?

I assume I paste the code into notepad and rename it to watcher.lua ready for upload. Is this correct?

Not sure what format ‘Notepad’ writes it out in (needs to be just a plain text file), but essentially yes, that’s the thing to do. Best in a file if you’re not actively changing/debugging it, but, again, if it’s relatively compact, then no harm with it living in startup.

Sorry to be a complete pain… I thought I had this sorted I updated the code to watch for on/off modules and dimmer modules i.e.

On/Off modules to output status as 1 for ON or 0 for OFF

Dimmer modules to output status as 1 to 100 for ON and 0 for OFF.

The code looks like this -

local http = require("socket.http")
http.TIMEOUT = 5
local url = "http://192.168.0.23:3005/HVTableVar.html"


   -- called when a device is switched on or off - from a variable_watch
function my_function_to_handle_dimming_level_change(dev_id,service, variable, old_val, new_val)
  http.request(url, "Var 241 : " .. dev_id .. "==")  
  http.request(url, "Var 242 : " .. new_val .. "==")
  http.request(url, "Macro 251=Run Macro")
end
luup.variable_watch("my_function_to_handle_dimming_level_change", "urn:upnp-org:serviceId:Dimming1", "LoadLevelStatus", YOUR_DEV_ID_HERE)


   -- called when a device is switched on or off - from a variable_watch
function my_function_to_handle_power_state_change(dev_id,service, variable, old_val, new_val)
  http.request(url, "Var 241 : " .. dev_id .. "==")  
  http.request(url, "Var 242 : " .. new_val .. "==")
  http.request(url, "Macro 251=Run Macro")
end
luup.variable_watch("my_function_to_handle_power_state_change", "urn:upnp-org:serviceId:SwitchPower1","Status", YOUR_DEV_ID_HERE)

My issue is with the dimmer output level reporting. If I set the light to 80% it displays 80 correctly in my variable pushed by http. If I them change the level of the light to 100%. It then updates the variable pushed by http to display 100 a second or two later it changes to 1. So I looks like its picking upon the function my_function_to_handle_power_state_change.

If I remove this function the 100% level displays ok but then the On/Off module is not tracked.

Any ideas how I can work around this? ???

This is the (sort of) expected result. A dimmer has both Status and LoadLevel variables. Setting its level to 100% will also ensure that the state is “1”. Similarly, setting it to 0% will make the state go to “0”.

You appear to have set up a watch function for both variables of the same device, but both being sent as Var 242 to your remote system. It’s perhaps a lottery as to which one beats the other in terms of timing (perhaps not.) So, the moral is:

[ul][li]don’t set watch callbacks for both on/off and dimming level for the same device[/li]
[li]if you do, then, at least, report them as different variables to your external system[/li][/ul]

Ideally, then, you’d just set the handler [tt]my_function_to_handle_dimming_level_change[/tt] for dimming devices and [tt]my_function_to_handle_power_state_change[/tt] to binary switches.

[quote=“akbooer, post:53, topic:176379”]This is the (sort of) expected result. A dimmer has both Status and LoadLevel variables. Setting its level to 100% will also ensure that the state is “1”. Similarly, setting it to 0% will make the state go to “0”.

You appear to have set up a watch function for both variables of the same device, but both being sent as Var 242 to your remote system. It’s perhaps a lottery as to which one beats the other in terms of timing (perhaps not.) So, the moral is:

[ul][li]don’t set watch callbacks for both on/off and dimming level for the same device[/li]
[li]if you do, then, at least, report them as different variables to your external system[/li][/ul]

Ideally, then, you’d just set the handler [tt]my_function_to_handle_dimming_level_change[/tt] for dimming devices and [tt]my_function_to_handle_power_state_change[/tt] to binary switches.[/quote]

Ok fair enough. I guess it’s no big deal really to show 100% as 1 I can set my remote system to show 1 as ON.

Cheers

Steve

a bit late getting to this. But I only look at the dimmer level not the Status to see what a dimmer switch is up to, I only use Status for lights that are controlled using a simple on off z-wave plug, e.g. the one in the fish tank!

Hello,

Using luup request can able to run thrid party url ? Actually I want create functionality with vera motion sensor and ip camera
When motion sensor is trip then start foscam ip camera video recording. 

Waiting for reply

Hi,

I’ve come back to a chunk of code I did from this thread ages ago to see if I could get it to work - but it’s not, and I must have looked at it so many time that I now cannot see the wood for the trees (that might just be a UK saying :slight_smile: - meaning I’m blind to what’s perhaps obvious)

Its supposed to respond to motion being triggered on a sensor, and then turn on a light (if no already on, and it is not night time) - and if/when the light is on to set a call back to check every 30 seconds if there is no further motion so the light can be turned off.

What am I missing ?

[code]local period = 30 – Seconds
local motion = 354 – motion sensor device ID
local daynight = 204 – daynight sensor device ID
local status = luup.variable_get(“urn:rts-services-com:serviceId:DayTime”,“Status”,daynight)
local status1, power = luup.inet.wget(“http://192.168.1.183:3480/data_request?id=variableget&DeviceNum=103&serviceId=urn:upnp-org:serviceId:SwitchPower1&Variable=Status”)

local function checkLastTrip()
local lastTrip = luup.variable_get (“urn:micasaverde-com:serviceId:SecuritySensor1”, “LastTrip”, motion) or os.time()
if (os.difftime (os.time(), tonumber (lastTrip)) >= period) then
luup.inet.wget(“http://192.168.1.183:3480/data_request?id=lu_action&DeviceNum=90&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=0”)
else
luup.call_delay (“checkLastTrip”, period) – Check when the sensor was last tripped every seconds.
end
end

local function turn_remote_light_on_with_motion()
– first check if the light is already on
if power == “1” then – if the light is already on, set up a call back to monitor it so it can be turned off
luup.call_delay (“checkLastTrip”, period)
elseif status == “0” then – check if it’s night time to know if the light needs to be on.
luup.inet.wget(“http://192.168.1.183:3480/data_request?id=lu_action&DeviceNum=90&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=1”)
luup.call_delay (“checkLastTrip”, period)
end

luup.variable_watch(“turn_remote_light_on_with_motion”, “urn:micasaverde-com:serviceId:SecuritySensor1”, “Tripped”, motion)[/code]

Is that in your startup LUA ? (Yes I am a capitalist)

If you restarts just after motion … your 30 second delay function will no longer be called.

I stand by the 2nd response to this thread! Use PLEG … it solves the boundary/restart conditions of this type of logic.

status, status1, and power are set once initially and never updated again. Is that what you intended? Your if/then/else checks them later so I suspect you want them updated?

[quote=“RichardTSchaefer, post:58, topic:176379”]Is that in your startup LUA ? (Yes I am a capitalist)

If you restarts just after motion … your 30 second delay function will no longer be called.

I stand by the 2nd response to this thread! Use PLEG … it solves the boundary/restart conditions of this type of logic.[/quote]

Hi @RTS.

Agreed and I have various things running va your great PLEG app, but (and call me old fashioned) I like using my Vera set up to teach myself Lua. It?s the only thing I?ve found that fuels me interest in programming :wink:

As for a restart effecting the 30 second delay, you?re right - but in the end I thought if I can get the code and checking function right, the impact (if/when it occurred) could be minimal.