Page 1 of 1
Expanding variables and arrays
Posted: Monday 01 July 2019 11:37
by Varazir
Hello again,
I'm not doing this right and don't know how to google for it
I could do it in bash but LUA it's a bit harder.
I like to use something like this $domoticz.globalData.$currentGroup[1]
This is what I have done so far.
Brightness.lua and ikeaSelect.lua works if I don't use arrays
I have hard set few values for testing
https://gist.github.com/varazir/f611418 ... cdaabee311
Basically I like a variable to be expanded and used as variable name.
But I should maybe work with a object s
globObjGroups = { initial = { "Hallway": [ 65 ], "BedRoom": [ 13 ], "TvBench": [ 42, 74, 45, 43 ] } },
Something like this (JSON)
https://jsoneditoronline.org/?id=37989d ... fa38988a66
Re: Expanding variables and arrays
Posted: Monday 01 July 2019 13:13
by waaren
Varazir wrote: Monday 01 July 2019 11:37
I like to use something like this $domoticz.globalData.$currentGroup[1]
I don't understand this approach. Can you please explain in laymen's terms what you try to achieve and why ? Maybe this would help me understand better.
Also please note that you can pass the complete device to a helper function. You don't have to limit yourself to pass the name only.
If you pass the name a string is passed to the function. If you pass the device (= Lua table) only a pointer is passed to the function so no disadvantage there in terms of performance or resource usage.
Re: Expanding variables and arrays
Posted: Monday 01 July 2019 14:00
by Varazir
waaren wrote: Monday 01 July 2019 13:13
Varazir wrote: Monday 01 July 2019 11:37
I like to use something like this $domoticz.globalData.$currentGroup[1]
I don't understand this approach. Can you please explain in laymen's terms what you try to achieve and why ? Maybe this would help me understand better.
Also please note that you can pass the complete device to a helper function. You don't have to limit yourself to pass the name only.
If you pass the name a string is passed to the function. If you pass the device (= Lua table) only a pointer is passed to the function so no disadvantage there in terms of performance or resource usage.
Okay, I think I'm doing it the wrong way.
To start I have:
One "5 button" zigbee remote
5 groups with 1 - 4 devices per group
I like to control all groups with one remote.
Pressing the right or left button will switch to the next/previous group of devices
1 switch in the selected group should blink ones to indicate it's selected
Middle button should be able to toggle the current groups devices.
The button up and down should change the level for all devices in the group if it is supported.
Re: Expanding variables and arrays
Posted: Monday 01 July 2019 15:07
by waaren
Varazir wrote: Monday 01 July 2019 14:00
I like to control all groups with one remote.
Pressing the right or left button will switch to the next/previous group of devices
Are the groups and devices in these groups defined in a dzVents script or somewhere else ?
1 switch in the selected group should blink ones to indicate it's selected
Do you mean that one light in the group is switched on and off after a second ? And if it is already on switched Off and On again after a second ?
Middle button should be able to toggle the current groups devices.
On -> Off / Off -> On ?
The button up and down should change the level for all devices in the group if it is supported.
Should be doable. My approach would be to do this in one script without using global_data. Using a multi level table like this example.
Code: Select all
control =
{
group1 = {
device1 = { toggle = true, dimmer = true, blink = true},
device2 = {toggle = true},
device3 = {dimmer = true},
},
group2 = {
device4 = {toggle = true},
device5 = { toggle = true, blink = true},
device6 = { dimmer = true}
},
}
for group, devices in pairs(control) do
for device, attributes in pairs(devices) do
for attribute, value in pairs(attributes) do
print (group .. '.' .. device .. '.' .. attribute)
end
end
end
So test if the attribute is set using nested for loops.
Re: Expanding variables and arrays
Posted: Monday 01 July 2019 17:10
by Varazir
waaren wrote: Monday 01 July 2019 15:07
Varazir wrote: Monday 01 July 2019 14:00
I like to control all groups with one remote.
Pressing the right or left button will switch to the next/previous group of devices
Are the groups and devices in these groups defined in a dzVents script or somewhere else ?
Yes, but only the each idx for each device, you see it in the global lua file
waaren wrote: Monday 01 July 2019 15:07
1 switch in the selected group should blink ones to indicate it's selected
Do you mean that one light in the group is switched on and off after a second ? And if it is already on switched Off and On again after a second ?
Yes
waaren wrote: Monday 01 July 2019 15:07
Middle button should be able to toggle the current groups devices.
On -> Off / Off -> On ?
Yes
waaren wrote: Monday 01 July 2019 15:07
The button up and down should change the level for all devices in the group if it is supported.
Should be doable. My approach would be to do this in one script without using global_data. Using a multi level table like this example.
You gave me the solution in another post, I just moved it to the global_data file but I guess it could be in the same
waaren wrote: Monday 01 July 2019 15:07
Code: Select all
control =
{
group1 = {
device1 = { toggle = true, dimmer = true, blink = true},
device2 = {toggle = true},
device3 = {dimmer = true},
},
group2 = {
device4 = {toggle = true},
device5 = { toggle = true, blink = true},
device6 = { dimmer = true}
},
}
for group, devices in pairs(control) do
for device, attributes in pairs(devices) do
for attribute, value in pairs(attributes) do
print (group .. '.' .. device .. '.' .. attribute)
end
end
end
So test if the attribute is set using nested for loops.
I was looking for something like that kind of table.
But I need a way to select the group as well
Re: Expanding variables and arrays [Solved]
Posted: Monday 01 July 2019 18:34
by waaren
Varazir wrote: Monday 01 July 2019 17:10
I was looking for something like that kind of table.
But I need a way to select the group as well
Please have a look at this code. It should not be to difficult to translate the log statements into real actions
Code: Select all
-- OneRemoteToControlAll.lua
local scriptVar = 'remoteControl'
local groups = {'group1', 'group2', 'group3' }
return
{
on = { devices = { scriptVar }},
logging = { level = domoticz.LOG_DEBUG, marker = scriptVar },
data = { currentGroup = { initial = 1 }},
execute = function(dz, item)
control =
{
group1 =
{
device1 = { toggle = true, dimmer = true, blink = true},
device2 = { toggle = true},
device3 = { dimmer = true},
},
group2 =
{
device4 = { toggle = true},
device5 = { toggle = true, blink = true},
device6 = { dimmer = true}
},
group3 =
{
device7 = { toggle = true},
device8 = { toggle = true, blink = true},
device9 = { dimmer = true}
},
}
local selectedGroupNumber = dz.data.currentGroup
local maxGroup = #groups
local function doAction(action, direction)
selectedGroup = groups[selectedGroupNumber]
for device, attributes in pairs(control[selectedGroup]) do
for attribute, value in pairs(attributes) do
if attribute == action then
dz.log(device .. " will " .. action)
if action == 'dimmer' then
dz.log(device .. " direction is " .. direction)
end
end
end
end
end
local action = 'blink'
local direction = 'up'
if item.state == 'left' then
selectedGroupNumber = selectedGroupNumber - 1
if selectedGroupNumber == 0 then selectedGroupNumber = maxGroup end
elseif item.state == 'right' then
selectedGroupNumber = selectedGroupNumber + 1
if selectedGroupNumber > maxGroup then selectedGroupNumber = 1 end
elseif item.state == 'push' then
action = 'toggle'
elseif item.state == 'up' then
action = 'dimmer'
elseif item.state == 'down' then
action = 'dimmer'
direction = 'down'
else
dz.log('Unknown action requested; ignored' )
return
end
doAction(action, direction)
dz.data.currentGroup = selectedGroupNumber
end
}
Re: Expanding variables and arrays
Posted: Monday 01 July 2019 20:34
by Varazir
waaren wrote: Monday 01 July 2019 18:34
Varazir wrote: Monday 01 July 2019 17:10
I was looking for something like that kind of table.
But I need a way to select the group as well
Please have a look at this code. It should not be to difficult to translate the log statements into real actions
Looks like I can work with that.
Didn't say from the start that each button on remote is assigned it's own device.
That has the State Off, Click, Press and release.
I guess I can change
to
Code: Select all
item.state == "Click" and item.name == "IKEA Switch Left Arrow"
I have to in cooperate this as well
It's the function I use to dim devices
Code: Select all
local dimDevice = domoticz.devices(device)
local dimLevel = dimDevice.level
local delay = 0
if state == "Hold" then
repeat
delay = delay + 0.1
dimLevel = dimLevel - 1
domoticz.log('Set ' .. dimDevice.name .. ' to dimLevel '.. dimLevel .. '%, after ' .. delay .. ' seconds', domoticz.LOG_INFO)
dimDevice.dimTo(dimLevel).afterSec(delay)
until dimLevel <= 0
elseif state == "Release" then
domoticz.log('Stop dimming of ' .. dimDevice.name .. ' at ' .. dimLevel ..'%', domoticz.LOG_INFO)
dimDevice.cancelQueuedCommands()
if dimDevice.level == 0 then
dimDevice.switchOff()
end
end
Or if you can check if there are a cue running I could do something like this
Code: Select all
if item.state == "Click" and item.name == "IKEA Switch Brightness Down"
if item.QueuedCommands() then
item.cancelQueuedCommands()
else
repeat
delay = delay + 0.1
dimLevel = dimLevel - 1
domoticz.log('Set ' .. dimDevice.name .. ' to dimLevel '.. dimLevel .. '%, after ' .. delay .. ' seconds', domoticz.LOG_INFO)
dimDevice.dimTo(dimLevel).afterSec(delay)
until dimLevel <= 0
end
end
Re: Expanding variables and arrays
Posted: Monday 01 July 2019 21:33
by Varazir
I did this, but I guess numbers can't be used as variable names.
Tried to add the name of the device but it failed as well.
Code: Select all
-- OneRemoteToControlAll.lua
local scriptVar = 'IKEA Remote Down',
'IKEA Remote Up',
'IKEA Remote Left',
'IKEA Remote Right',
'IKEA Remote Toggle'
local groups = {'group1', 'group2', 'group3' }
return
{
on = { devices = { scriptVar }},
logging = { level = domoticz.LOG_DEBUG, marker = scriptVar },
data = { currentGroup = { initial = 1 }},
execute = function(dz, item)
control =
{
group3 = --Hallway
{
40 = { toggle = true, dimmer = true, blink = true},
15 = { toggle = true, dimmer = true},
17 = { toggle = true, dimmer = true},
19 = { toggle = true, dimmer = true}
},
group1 = --Bedroom
{
13 = { toggle = true, blink = true, dimmer = true}
},
group4 = --Lilvingroom
{
21 = { toggle = true, dimmer = true},
23 = { toggle = true, dimmer = true, blink = true},
25 = { toggle = true, dimmer = true}
},
group6 = --Computeroom
{
73 = { toggle = true, blink = true},
},
group5 = --TvBench
{
OnkyoHW = { toggle = true},
42 = { toggle = true, blink = true},
45 = { toggle = true},
43 = { toggle = true}
},
group2 = --BedroomBlilnder
{
59 = { toggle = true, dimmer = true },
},
}
local selectedGroupNumber = dz.data.currentGroup
local maxGroup = #groups
local function doAction(action, direction)
selectedGroup = groups[selectedGroupNumber]
for device, attributes in pairs(control[selectedGroup]) do
for attribute, value in pairs(attributes) do
if attribute == action then
dz.log(device .. " will " .. action)
if action == 'blink' then
local blinkDevice = domoticz.devices(device)
if blinkDevice.state == "Off" then
blinkDevice.switchOn()
blinkDevice.switchOff()
else
blinkDevice.switchOff()
blinkDevice.switchOn()
end
end
if action == 'dimmer' then
local dimDevice = domoticz.devices(device)
local dimLevel = dimDevice.level
local delay = 0
dz.log(device .. " direction is " .. direction)
if dimDevice.QueuedCommands() then
dimDevice.cancelQueuedCommands()
else
repeat
delay = delay + 0.1
if direction == "down" then dimLevel = dimLevel - 1 else dimLevel = dimLevel + 1 end
dz.log('Set ' .. item.name .. ' to dimLevel '.. dimLevel .. '%, after ' .. delay .. ' seconds', dz.LOG_INFO)
item.dimTo(dimLevel).afterSec(delay)
until dimLevel <= 0
end
end
end
end
end
end
local action = 'blink'
local direction = 'up'
if item.state == 'Click' and item.name "IKEA Remote Left" then
selectedGroupNumber = selectedGroupNumber - 1
if selectedGroupNumber == 0 then selectedGroupNumber = maxGroup end
elseif item.state == 'Click' and item.name "IKEA Remote Right" then
selectedGroupNumber = selectedGroupNumber + 1
if selectedGroupNumber > maxGroup then selectedGroupNumber = 1 end
elseif item.name "IKEA Remote Toggle" then
action = 'toggle'
elseif item.state == 'Click' and item.name "IKEA Remote Up" then
action = 'dimmer'
elseif item.state == 'Click' and item.name "IKEA Remote Down" then
action = 'dimmer'
direction = 'down'
else
dz.log('Unknown action requested; ignored' )
return
end
item.switchOff().silent()
doAction(action, direction)
dz.data.currentGroup = selectedGroupNumber
end
}
Re: Expanding variables and arrays
Posted: Monday 01 July 2019 22:02
by waaren
Varazir wrote: Monday 01 July 2019 21:33
I did this, but I guess numbers can't be used as variable names.
You guessed right. At least not like this. May I suggest that you have a look at some of the excellent pages on Lua.org ?
It will save you a lot of frustration and time.
Tried to add the name of the device but it failed as well.
Try to use this as trigger
on = { devices = { 'IKEA Remote*' }},
Re: Expanding variables and arrays
Posted: Tuesday 02 July 2019 9:24
by Varazir
I have been looking at that site but not sure what to look for or if I'm on the correct path.
Skickat från min EML-L29 via Tapatalk
Re: Expanding variables and arrays
Posted: Tuesday 02 July 2019 9:43
by waaren
Varazir wrote: Tuesday 02 July 2019 9:24
I have been looking at that site but not sure what to look for or if I'm on the correct path.
For most people who programmed before in other languages, the table type is not the easiest part of Lua but yet they present a very important part of the language and they are also frequently used in many areas in the dzVents API. If you understand the main aspects of Lua tables then you are more than halfway..
this is a good start
Re: Expanding variables and arrays
Posted: Tuesday 02 July 2019 11:15
by Varazir
waaren wrote: Tuesday 02 July 2019 9:43
Varazir wrote: Tuesday 02 July 2019 9:24
I have been looking at that site but not sure what to look for or if I'm on the correct path.
For most people who programmed before in other languages, the table type is not the easiest part of Lua but yet they present a very important part of the language and they are also frequently used in many areas in the dzVents API. If you understand the main aspects of Lua tables then you are more than halfway..
this is a good start
I think I have a workaround.
Back to the queued commands, can you test that?
If the device has any queued commands that is
Re: Expanding variables and arrays
Posted: Tuesday 02 July 2019 11:46
by Varazir
waaren wrote: Tuesday 02 July 2019 9:43
Varazir wrote: Tuesday 02 July 2019 9:24
I have been looking at that site but not sure what to look for or if I'm on the correct path.
For most people who programmed before in other languages, the table type is not the easiest part of Lua but yet they present a very important part of the language and they are also frequently used in many areas in the dzVents API. If you understand the main aspects of Lua tables then you are more than halfway..
this is a good start
I keep getting this and I don't understand why
Code: Select all
2019-07-02 11:41:40.333 Error: EventSystem: in test: [string "groups = {'group1', 'group2', 'group3', 'grou..."]:6: attempt to index global 'domoticz' (a nil value)
If I comment out the logg part I get
Code: Select all
Error: EventSystem: Lua script test did not return a commandArray
Code: Select all
groups = {'group1', 'group2', 'group3', 'group4', 'group5', 'group6' }
return {
on = { devices = { 'IKEA Remote*' }},
logging = { level = domoticz.LOG_DEBUG, marker = "IKEARemote" },
data = { currentGroup = { initial = 1 }},
execute = function(dz, item)
control =
{
group3 = --Hallway
{
lamp = { idx = 40, toggle = true, dimmer = true, blink = true},
spot1 = { idx = 15, toggle = true, dimmer = true},
spot2 = { idx = 17, toggle = true, dimmer = true},
spot3 = { idx = 19, toggle = true, dimmer = true}
},
group1 = --Bedroom
{
lamp = { idx = 13, toggle = true, blink = true, dimmer = true}
},
group4 = --Lilvingroom
{
spot1 = { idx = 21, toggle = true, dimmer = true},
spot2 = { idx = 23, toggle = true, dimmer = true, blink = true},
spot3 = { idx = 25, toggle = true, dimmer = true}
},
group6 = --Computeroom
{
lamp = { idx = 73, toggle = true, blink = true},
},
group5 = --TvBench
{
lamp = { idx = 42, toggle = true, blink = true},
onkyoHW = { idx = 19, toggle = true},
tv = { idx = 45, toggle = true},
onkyo = { idx = 43, toggle = true}
},
group2 = --BedroomBlilnder
{
blinder = { idx = 59, toggle = true, dimmer = true },
},
}
local selectedGroupNumber = dz.data.currentGroup
local maxGroup = #groups
local function doAction(action, direction)
selectedGroup = groups[selectedGroupNumber]
for device, attributes in pairs(control[selectedGroup]) do
for attribute, value in pairs(attributes) do
if attribute == idx then local idx = attribute.idx end
if attribute == action then
dz.log(device .. " will " .. action)
if action == 'blink' then
local blinkDevice = dz.devices(idx)
local blinkLevel = dz.devices(idx)
if blinkDevice.state == "Off" then
blinkDevice.switchOn().dimTo(blinkLevel)
blinkDevice.switchOff().dimTo(blinkLevel)
else
blinkDevice.switchOff().dimTo(blinkLevel)
blinkDevice.switchOn().dimTo(blinkLevel)
end
end
if action == 'dimmer' then
local dimDevice = dz.devices(idx)
local dimLevel = dimDevice.level
local delay = 0
dz.log(device .. " direction is " .. direction)
if dimDevice.QueuedCommands() then
dimDevice.cancelQueuedCommands()
else
repeat
delay = delay + 0.1
if direction == "down" then dimLevel = dimLevel - 1 else dimLevel = dimLevel + 1 end
dz.log('Set ' .. item.name .. ' to dimLevel '.. dimLevel .. '%, after ' .. delay .. ' seconds', dz.LOG_INFO)
dimDevice.dimTo(dimLevel).afterSec(delay)
until dimLevel <= 0
end
end
end
end
end
end
local action = 'blink'
local direction = 'up'
if item.state == 'Click' and item.name "IKEA Remote Left" then
selectedGroupNumber = selectedGroupNumber - 1
if selectedGroupNumber == 0 then selectedGroupNumber = maxGroup end
elseif item.state == 'Click' and item.name "IKEA Remote Right" then
selectedGroupNumber = selectedGroupNumber + 1
if selectedGroupNumber > maxGroup then selectedGroupNumber = 1 end
elseif item.name "IKEA Remote Toggle" then
action = 'toggle'
elseif item.state == 'Click' and item.name "IKEA Remote Up" then
action = 'dimmer'
elseif item.state == 'Click' and item.name "IKEA Remote Down" then
action = 'dimmer'
direction = 'down'
else
dz.log('Unknown action requested; ignored' )
return
end
item.switchOff().silent()
doAction(action, direction)
dz.data.currentGroup = selectedGroupNumber
end
}
Re: Expanding variables and arrays
Posted: Tuesday 02 July 2019 11:53
by waaren
Varazir wrote: Tuesday 02 July 2019 11:46
Error: EventSystem: Lua script test did not return a commandArray
If you see this message you saved your script as classic domoticz Lua and not as dzVents.
Re: Expanding variables and arrays
Posted: Tuesday 02 July 2019 11:58
by waaren
Varazir wrote: Tuesday 02 July 2019 11:15
I think I have a workaround.
Back to the queued commands, can you test that?
If the device has any queued commands that is
No need to test because the method QueuedCommands does not exist and there is no way to get that kind of information from domoticz in dzVents or any other event driven API. You don't need to test if there is a queue. The cancelQueuedCommands() method will not fail if there is no queue.
Your implementation of blink might not produce the desired effect. Better to code it like
Code: Select all
if blinkDevice.state == "Off" then
blinkDevice.switchOn()
blinkDevice.switchOff().afterSec(0.5)
else
blinkDevice.switchOff()
blinkDevice.switchOn()..afterSec(0.5)
end