Page 1 of 1
Attempt to index local 'device' (a nil value)
Posted: Saturday 20 January 2018 12:14
by htilburgs
In my first attempt to make a dzVents script, I get an error that I can't explain.
As far as I can see, nothing is wrong.
Domoticz v3.8833
The dzVents script:
Code: Select all
return {
active = true,
on = {
timer = {
'between 11:46 and 12:00'
},
devices = {
'PIR Sensor'
}
},
execute = function(domoticz, device)
if (device.name == 'PIR Sensor' and device.state == 'On') then
domoticz.devices('Lamp Gang').switchOn().forMin(1)
domoticz.log('Lamp gang ingeschakeld door PIR')
end
end
}
The error message
Code: Select all
2018-01-20 11:54:56.035 dzVents: Info: Handling events for: "PIR Sensor", value: "Off"
2018-01-20 11:54:56.035 dzVents: Info: ------ Start internal script: PIR2: Device: "PIR Sensor (Aeon Labs Z-Stick GEN5)", Index: 489
2018-01-20 11:54:56.035 dzVents: Info: ------ Finished PIR2
2018-01-20 11:55:00.521 dzVents: Info: ------ Start internal script: PIR2:, trigger: between 11:46 and 12:00
2018-01-20 11:55:00.521 Error: dzVents: Error: An error occured when calling event handler PIR2
2018-01-20 11:55:00.521 Error: dzVents: Error: ...e/pi/domoticz/scripts/dzVents/generated_scripts/PIR2.lua:18: attempt to index local 'device' (a nil value)
2018-01-20 11:55:00.521 dzVents: Info: ------ Finished PIR2
The second thing I noticed, is that the script still works, even the timer is not true.
The error "attempt to index local 'device' (a nil value)" disappeared:
Code: Select all
2018-01-20 12:01:43.930 EventSystem: Script event triggered: /home/pi/domoticz/dzVents/runtime/dzVents.lua
2018-01-20 12:02:15.174 dzVents: Info: Handling events for: "PIR Sensor", value: "Off"
2018-01-20 12:02:15.175 dzVents: Info: ------ Start internal script: PIR2: Device: "PIR Sensor (Aeon Labs Z-Stick GEN5)", Index: 489
2018-01-20 12:02:15.175 dzVents: Info: ------ Finished PIR2
2018-01-20 12:02:27.628 dzVents: Info: Handling events for: "PIR Sensor", value: "On"
2018-01-20 12:02:27.629 dzVents: Info: ------ Start internal script: PIR2: Device: "PIR Sensor (Aeon Labs Z-Stick GEN5)", Index: 489
2018-01-20 12:02:27.630 dzVents: Info: Lamp gang ingeschakeld door PIR
2018-01-20 12:02:27.631 dzVents: Info: ------ Finished PIR2
Probably I'm doing something wrong, but as it is my first attempt and the Wiki is not helping me with this, I need some help
Re: Attempt to index local 'device' (a nil value)
Posted: Saturday 20 January 2018 12:49
by waaren
You asked dzVents to trigger between 11:46 and 12:00 or when anything changed on the PIR sensor.
If program is triggered by the timer then device is nil
Syntaxis for what you try to achieve:
devices = { ['PIR Sensor'] = {'between 11:46 and 12:00'}
Re: Attempt to index local 'device' (a nil value)
Posted: Saturday 20 January 2018 13:38
by htilburgs
waaren wrote: ↑Saturday 20 January 2018 12:49
You asked dzVents to trigger between 11:46 and 12:00 or when anything changed on the PIR sensor.
If program is triggered by the timer then device is nil
Syntaxis for what you try to achieve:
devices = { ['PIR Sensor'] = {'between 11:46 and 12:00'}
Ok, nice. That works!
The next attempt is to turn it on at 50% for 1 minute.
I used:
Code: Select all
domoticz.devices('Lamp Gang').DimTo(50).forMin(1)
and
Code: Select all
domoticz.devices('Lamp Gang').level:50.forMin(1)
but no luck, both give errors
attempt to call field 'DimTo' (a nil value)
attempt to call field 'level' (a number value)
Re: Attempt to index local 'device' (a nil value)
Posted: Saturday 20 January 2018 14:01
by waaren
according to wiki you should use dimTo(50) -- Case matters
Re: Attempt to index local 'device' (a nil value)
Posted: Saturday 20 January 2018 17:31
by htilburgs
waaren wrote: ↑Saturday 20 January 2018 14:01
according to wiki you should use dimTo(50) -- Case matters
Ok, thanks again, didn't noticed it.
Now this simple script works!
Code: Select all
return {
active = true,
on =
{
devices = {['PIR Sensor'] = {'between 23:30 and 06:30'}}
},
execute = function(domoticz, device)
if (device.name == 'PIR Sensor' and device.state == 'On') then
domoticz.devices('Lamp Gang').dimTo(50).forMin(1)
domoticz.log('Lamp gang ingeschakeld door PIR')
end
end
}
Re: Attempt to index local 'device' (a nil value)
Posted: Saturday 20 January 2018 22:40
by waaren
Your welcome,
your line of code
Code: Select all
if (device.name == 'PIR Sensor' and device.state == 'On') then
can be shortened to
Code: Select all
if device.state == 'On' then -- when code reach this line device.name is always 'PIR Sensor' because code is triggered by change of this device
Re: Attempt to index local 'device' (a nil value)
Posted: Thursday 19 December 2019 22:20
by bertbigb
Hello,
I have a different but similar problem what I can't find myself and I hope someone can help me.
I have a script what should put on the gardenlights at 06:00, put off at sunrise and put on at sunset and then depending on the day of the week at 22:30 put the lights off.
This is my script:
Code: Select all
return {
on = {
devices = {},
timer = {'every minute'},
},
execute = function(domoticz, triggeredItem)
local GardenLights = 'Tuinlamp'
local VerandaLight = 'Veranda'
local GardenSeason = 'GardenSeason'
if domoticz.devices(GardenLights).state == 'Off' and
(domoticz.timer.matchesRule('at 06:00') or
domoticz.timer.matchesRule('at sunset')) then
-- at 6 and at sunset we put on the gardenlights
domoticz.log('Gardenlight switched on', domoticz.LOG_INFO)
domoticz.devices(GardenLights).switchOn().checkFirst()
-- at Gardenseason also put light in Veranda on
if domoticz.variables(GardenSeason) == 'True' then domoticz.devices(VerandaLight).switchOn().checkFirst() end
else
if domoticz.devices(GardenLights).state == 'On' and
(domoticz.timer.matchesRule('at sunrise') or
domoticz.timer.matchesRule('at 22:30 on sun,mon,tue,wed,thu') or
domoticz.timer.matchesRule('at 01:00 on fri,sat')) then
-- put off the lights at sunrise and at certain times at night
domoticz.log('Gardenlight switched off', domoticz.LOG_INFO)
domoticz.devices(GardenLights).switchOff().checkFirst()
domoticz.devices(VerandaLight).switchOff().checkFirst()
else
domoticz.log('Nothing triggered', domoticz.LOG_INFO)
end
end
end
}
but the code gives the following error:
Code: Select all
2019-12-19 22:16:00.559 Status: dzVents: Info: ------ Start internal script: Buitenverlichting:, trigger: every minute
2019-12-19 22:16:00.581 Status: dzVents: Error (2.4.19): An error occured when calling event handler Buitenverlichting
2019-12-19 22:16:00.581 Status: dzVents: Error (2.4.19): .../scripts/dzVents/generated_scripts/Buitenverlichting.lua:23: attempt to index field 'timer' (a nil value)
2019-12-19 22:16:00.581 Status: dzVents: Info: ------ Finished Buitenverlichting
Line 23 is the line domoticz.timer.matchesRule('at sunrise').
I hope someone can help me because I'm not really seasoned in dzVentz.
Thanks already for anyone providing help !
Re: Attempt to index local 'device' (a nil value)
Posted: Thursday 19 December 2019 22:49
by waaren
bertbigb wrote: ↑Thursday 19 December 2019 22:20
The code gives the following error:
Code: Select all
2019-12-19 22:16:00.581 Status: dzVents: Error (2.4.19): .../scripts/dzVents/generated_scripts/Buitenverlichting.lua:23: attempt to index field 'timer' (a nil value)
The object (table) is domoticz.time not domoticz.timer
Can you check this ?
Code: Select all
return
{
on =
{
timer = {'every minute'},
},
execute = function(domoticz)
local GardenLights = domoticz.devices('Tuinlamp')
local VerandaLight = domoticz.devices('Veranda')
local GardenSeason = domoticz.variables('GardenSeason')
if GardenLights.state == 'Off' and ( domoticz.time.matchesRule('at 06:00') or
domoticz.time.matchesRule('at sunset')) then
-- at 6 and at sunset we put on the gardenlights
domoticz.log('Gardenlight switched on', domoticz.LOG_INFO)
GardenLights.switchOn().checkFirst()
-- at Gardenseason also put light in Veranda on
if GardenSeason.value == 'True' then
VerandaLight.switchOn().checkFirst()
end
else
if GardenLights.state == 'On' and ( domoticz.time.matchesRule('at sunrise') or
domoticz.time.matchesRule('at 22:30 on sun,mon,tue,wed,thu') or
domoticz.time.matchesRule('at 01:00 on fri,sat')) then
-- put off the lights at sunrise and at certain times at night
domoticz.log('Gardenlight switched off', domoticz.LOG_INFO)
GardenLights.switchOff().checkFirst()
VerandaLight.switchOff().checkFirst()
else
domoticz.log('Nothing triggered', domoticz.LOG_INFO)
end
end
end
Re: Attempt to index local 'device' (a nil value)
Posted: Friday 20 December 2019 8:37
by bertbigb
Hello Waaren,
That is a really quick reply, thank you very much.
I have no errors anymore and it works!!
Thanks for telling what the problem is --> The object (table) is domoticz.time not domoticz.timer
Do you know a place on the internet where you can find all the objects, I know about the wiki ofcourse but I more or less looking for a place where I can find things like concatenated commands --> domoticz.timer.matchesRule and domoticz(<name>). switchOff().checkFirst()
Your help is very much appreciated!
Re: Attempt to index local 'device' (a nil value)
Posted: Friday 20 December 2019 11:04
by waaren
bertbigb wrote: ↑Friday 20 December 2019 8:37
I have no errors anymore and it works!!
Do you know a place on the internet where you can find all the objects, I know about the wiki ofcourse but I more or less looking for a place where I can find things like concatenated commands --> domoticz.timer.matchesRule and domoticz(<name>). switchOff().checkFirst()
What you call concatenated commands are in fact nested tables / functions. See below example script where I tried to visualize this using a switch type device as trigger.
A good place to start understanding Lua functions and tables is
this Lua users wiki
With a short introduction to tables
here
Code: Select all
return
{
on =
{
devices = { 199 } -- changes to a virtual switch type device that you can use as trigger for this example script
},
execute = function(dz, item)
dz.log('Device ' .. item.name, dz.LOG_INFO)
dz.log('type silent(): ' .. type(item.switchOff().silent()),dz.LOG_INFO)
dz.utils.dumpTable(item.switchOff().silent())
dz.log('type afterHour(): ' .. type(item.switchOff().silent().afterHour(1)),dz.LOG_INFO)
dz.utils.dumpTable(item.switchOff().silent().afterHour(1))
dz.log('type checkFirst(): ' .. type(item.switchOff().silent().afterHour(1).checkFirst()),dz.LOG_INFO)
dz.utils.dumpTable(item.switchOff().silent().afterHour(1).checkFirst())
dz.log('type forSec(): ' .. type(item.switchOff().silent().afterHour(1).checkFirst().forSec(2)),dz.LOG_INFO)
dz.utils.dumpTable(item.switchOff().silent().afterHour(1).checkFirst().forSec(2))
dz.log('type repeatAfterSec(): ' .. type(item.switchOff().silent().afterHour(1).checkFirst().forSec(2).repeatAfterSec(3)),dz.LOG_INFO)
dz.utils.dumpTable(item.switchOff().silent().afterHour(1).checkFirst().forSec(2).repeatAfterSec(7))
dz.log('type _latest: ' .. type(item.switchOff().silent().afterHour(1).checkFirst().forSec(2).repeatAfterSec(3)._latest),dz.LOG_INFO)
dz.utils.dumpTable(item.switchOff().silent().afterHour(1).checkFirst().forSec(2).repeatAfterSec(7)._latest)
dz.log('type _latest: ' .. type(item.switchOff().silent().afterHour(1).checkFirst().forSec(2).repeatAfterSec(3)._latest[item.name]),dz.LOG_INFO)
dz.log('_latest.' .. item.name .. ': ' .. item.switchOff().silent().afterHour(1).checkFirst().forSec(2).repeatAfterSec(7)._latest[item.name],dz.LOG_INFO)
end
}
Re: Attempt to index local 'device' (a nil value)
Posted: Friday 20 December 2019 16:49
by bertbigb
Hi Waaren,
Thank you very much for this guidance. I will read that stuff during this Christmas holiday.
This morning I tested your script with a single time and it worked.
But I also wanted to extend the script a bit since in the past I have found out that sometimes a time event was missed. So I thought to extend the script with some margins
So I made it as follows:
Code: Select all
return
{
on =
{
timer = {'sunrise',
'sunset',
'every minute'},
},
execute = function(domoticz)
local GardenLights = domoticz.devices('Tuinlamp')
local VerandaLight = domoticz.devices('Veranda')
local GardenSeason = domoticz.variables('GardenSeason')
if GardenLights.state == 'Off' and ( domoticz.time.matchesRule('at 06:00-sunrise') or
domoticz.time.matchesRule('at sunset-22:00')) then
-- at 6 and at sunset we put on the gardenlights
domoticz.log('Gardenlight switched on', domoticz.LOG_INFO)
GardenLights.switchOn().checkFirst()
-- at Gardenseason also put light in Veranda on
if GardenSeason.value == 'True' then
VerandaLight.switchOn().checkFirst()
end
else
if GardenLights.state == 'On' and ( domoticz.time.matchesRule('at sunrise-09:00') or
domoticz.time.matchesRule('at 22:30-22:45 on sun,mon,tue,wed,thu') or
domoticz.time.matchesRule('at 01:00-01:15 on fri,sat')) then
-- put off the lights at sunrise and at certain times at night
domoticz.log('Gardenlight switched off', domoticz.LOG_INFO)
GardenLights.switchOff().checkFirst()
VerandaLight.switchOff().checkFirst()
else
domoticz.log('Nothing triggered', domoticz.LOG_INFO)
end
end
end
}
At Sunset the script wasn't triggerd, so I thought it would do on domoticz.time.matchesRule('at sunset-22:00') but it doesn't do also
Code: Select all
2019-12-20 16:37:00.414 Status: dzVents: Info: ------ Start internal script: Buitenverlichting:, trigger: every minute
2019-12-20 16:37:00.437 Status: dzVents: Info: Nothing triggered
2019-12-20 16:37:00.437 Status: dzVents: Info: ------ Finished Buitenverlichting
Did I do something wrong with at ' sunset-22:00' I thought that the script would check between sunset and 10 'o clock but obvious it doesn't.
Can you help me a little bit more?
Re: Attempt to index local 'device' (a nil value)
Posted: Friday 20 December 2019 18:56
by waaren
bertbigb wrote: ↑Friday 20 December 2019 16:49
Did I do something wrong with at ' sunset-22:00' I thought that the script would check between sunset and 10 'o clock but obvious it doesn't.
Can you help me a little bit more?
I know there is a remark in the dzVents wiki about missed time triggers but I never experienced one on my systems.
at 06:00-sunrise, at sunset-22:00 and
at sunrise-09:00 are no valid dzVents time rules.
A couple of remarks:
Please note that between 06:00 and sunrise will never be true during winter in large parts of the world. Similar for between sunset and 22:00 in summer.
Code: Select all
if GardenLights.state == 'Off' and GardenLights.switchOn().checkFirst() -- this is double.
. Only 1 check should be enough.
Code: Select all
domoticz.time.matchesRule('at 01:00-01:15 on fri,sat'))
. -- are you sure you don't want this to happen only in the weekends ?
The domoticz event system triggers time based event scripts max. once a minute. So
Code: Select all
timer = {'sunrise', 'sunset', 'every minute' },
does not add any value over
in this script. Both settings causes the script to trigger 1440 times / day. My approach would be to have the script to trigger only when it has something to do. Here it would be something like below (not tested!)
Code: Select all
local sunrise = 'at sunrise'
local sunset = 'at sunset'
local onMorningTime = 'at 06:00'
local offEveningWeekdays = 'at 22:30 on mon, tue, wed, thu, fri'
local offNightWeekend = 'at 01:00 on sat,sun'
return
{
on =
{
timer = { sunrise, sunset, onMorningTime, offEveningWeekdays, offNightWeekend }
},
execute = function(dz, item)
local GardenLights = dz.devices('Tuinlamp')
local VerandaLight = dz.devices('Veranda')
local GardenSeason = dz.variables('GardenSeason')
local now = math.floor(dz.time.secondsSinceMidnight / 60) -- minutesSinceMidnight does not exist
local activeRule = item.trigger
if ( activeRule == onMorningTime and dz.time.sunriseInMinutes > now ) or -- at 6 if sunrise is after 6
activeRule == sunset then
-- at 6 AM and at sunset we put on the gardenlights
GardenLights.switchOn().checkFirst()
if GardenSeason.value == 'True' then
VerandaLight.switchOn().checkFirst()
end
dz.log('Lights should be on now', dz.LOG_INFO)
elseif activeRule == sunrise or activeRule == offEveningWeekdays or activeRule == offNightWeekend then
-- at sunrise and in the evening / at night we switch off the lights.
GardenLights.switchOff().checkFirst()
VerandaLight.switchOff().checkFirst()
dz.log('Lights should be off now', dz.LOG_INFO)
end
end
}
Re: Attempt to index local 'device' (a nil value)
Posted: Saturday 21 December 2019 12:11
by bertbigb
Hi Waaren,
Thanks again. I learn a whole lot from all your explications and samples. Hopefully I will come to a level I can help others also on these kind of subjects. A lot of what you were telling me makes sense.
Please note that between 06:00 and sunrise will never be true during winter in large parts of the world. Similar for between sunset and 22:00 in summer.
This I do not understand very well. Like now in winter the time 06:00 is before sunrise at 08:41(sunrise) so although the syntax was not ok but between 06:00 - sunrise I thought is similar to 06:00 - 08:41. But nevertheless the syntax is not correct anyway as you wrote. My meaning was to have the gardenlights on from 06;00 (when I'm awake) till sunrise, because then it is light enough.
That is probably why I do not understand this piece very well
Code: Select all
local now = math.floor(dz.time.secondsSinceMidnight / 60) -- minutesSinceMidnight does not exist
local activeRule = item.trigger
if ( activeRule == onMorningTime and dz.time.sunriseInMinutes > now ) or -- at 6 if sunrise is after 6
activeRule == sunset then
-- at 6 AM and at sunset we put on the gardenlights
GardenLights.switchOn().checkFirst()
I would have thought that it should be something like
Code: Select all
local now = math.floor(dz.time.secondsSinceMidnight / 60) -- minutesSinceMidnight does not exist
local activeRule = item.trigger
if ( activeRule == onMorningTime and dz.time.sunriseInMinutes < now ) then
-- at 6 AM and BEFORE sunset we put on the gardenlights
GardenLights.switchOn().checkFirst()
I will test the script and see if it works today. I will post the result here so if anyone needs a similar script they know they can make use of it.
Thanks once again. Great help you are giving.
Re: Attempt to index local 'device' (a nil value)
Posted: Saturday 21 December 2019 19:45
by waaren
bertbigb wrote: ↑Saturday 21 December 2019 12:11
I would have thought that it should be something like
Code: Select all
local now = math.floor(dz.time.secondsSinceMidnight / 60) -- minutesSinceMidnight does not exist
local activeRule = item.trigger
if ( activeRule == onMorningTime and dz.time.sunriseInMinutes < now ) then
-- at 6 AM and BEFORE sunset we put on the gardenlights
GardenLights.switchOn().checkFirst()
If you would code it like that and sunrise is at 5:59 or earlier the light will be switched on at 6:00 and will not switched off again until very late in the evening.
Re: Attempt to index local 'device' (a nil value) [Solved]
Posted: Sunday 22 December 2019 22:42
by bertbigb
Hi Waaren,
Just to let you know but the script you supplied works very good.
Thanks again for all your help!