Something like:
Code: Select all
local StatusNames = {
'Is * Alive',
'Monit: * alive'
}
local StatusDevices = domoticz.devices().filter(StatusNames)
StatusDevices.forEach(function(light)
BLABLA )
Moderator: leecollings
Code: Select all
local StatusNames = {
'Is * Alive',
'Monit: * alive'
}
local StatusDevices = domoticz.devices().filter(StatusNames)
StatusDevices.forEach(function(light)
BLABLA )
Not sure if I understand you correctly but if you want to process devices where the state matches a given wildcard you could use something likeFearNaBoinne wrote: ↑Wednesday 01 January 2020 21:11 Is there a way to use filter() with wildcards, so it only selects the devices I need without having to iterate through every one of them and checking the names myself?
Code: Select all
return
{
on =
{
devices =
{
'filterTrigger' -- just a virtual switch to trigger this script
}
},
logging =
{
level = domoticz.LOG_ERROR,
},
execute = function(dz)
_G.logMarker = _G.moduleLabel
function string.sMatch(text, match) -- specialized sanitized match function to allow combination of Lua magic chars in wildcards
local sanitizedMatch = ('^' .. match:gsub("[%^$]","."):gsub("*", ".*"):gsub("?", ".") .. '$') -- convert to Lua wildcards
local escapedSanitizedMatch = sanitizedMatch:gsub("([%%%(%)%[%]%+%-%?])", "%%%1") -- escaping all 'magic' chars except *, ., ^ and $
return text:match(escapedSanitizedMatch)
end
local wildcardedStatusTable =
{
'Is * Alive',
'Monit: * alive',
'Auto *',
'*us?d*',
'*domoticz*',
}
-- chain all devices -->> filter -->> forEach
dz.devices().filter(function(dv)
for _, status in ipairs(wildcardedStatusTable) do
if dv.sValue:sMatch(status) ~= nil then
return true
end
end
end).forEach(function(foundDevice)
dz.log('sValue of device ' .. foundDevice.name .. ' is ' .. foundDevice.sValue,dz.LOG_FORCE )
end)
-- or using table to store interim results
local variables = dz.variables()
local filteredVariables = variables.filter(function(vars)
for _, status in ipairs(wildcardedStatusTable) do
if tostring(vars.value):sMatch(status) ~= nil then
return true
end
end
end)
filteredVariables.forEach(function(foundVariable)
dz.log('value of variable ' .. foundVariable.name .. ' is ' .. foundVariable.value,dz.LOG_FORCE )
end)
end
}
It will never be possible to filter a collection without iteration at some level; that's true for any computer language today. Maybe it will change with quantum computing but I would not hold my breath waiting for it.FearNaBoinne wrote: ↑Thursday 02 January 2020 9:41 Thanls for the suggestion, but no, I am trying to create an array of devices with a NAME matching the wildcards, WITHOUT iterating through every device manually to check it's name...
Code: Select all
return
{
on =
{
devices =
{
'filterTrigger' -- just a virtual switch to trigger this script
}
},
logging =
{
level = domoticz.LOG_ERROR,
},
execute = function(dz)
_G.logMarker = _G.moduleLabel
function string.sMatch(text, match) -- specialized sanitized match function to allow combination of Lua magic chars in wildcards
local sanitizedMatch = ('^' .. match:gsub("[%^$]","."):gsub("*", ".*"):gsub("?", ".") .. '$') -- convert to Lua wildcards
local escapedSanitizedMatch = sanitizedMatch:gsub("([%%%(%)%[%]%+%-%?])", "%%%1") -- escaping all 'magic' chars except *, ., ^ and $
return text:match(escapedSanitizedMatch)
end
local wildcardedNameTable =
{
'Is * Alive',
'Monit: * alive',
'*rigger',
'*r*r*',
'*domoticz*',
'*?omoticz*',
}
-- chain all devices -->> filter -->> forEach
dz.devices().filter(function(dv)
for _, wildcardString in ipairs(wildcardedNameTable) do
if dv.name:sMatch(wildcardString) ~= nil then
dv.matchingWildcard = wildcardString
return true
end
end
end).forEach(function(foundDevice)
dz.log('Device ' .. foundDevice.name .. ' matches ' .. foundDevice.matchingWildcard,dz.LOG_FORCE )
end)
-- or using tables to store interim results
local variables = dz.variables()
local filteredVariables = variables.filter(function(var)
for _, wildcardString in ipairs(wildcardedNameTable) do
if tostring(var.name):sMatch(wildcardString) ~= nil then
var.matchingWildcard = wildcardString
return true
end
end
end)
filteredVariables.forEach(function(foundVariable)
dz.log('Variable ' .. foundVariable.name .. ' matches ' .. foundVariable.matchingWildcard,dz.LOG_FORCE )
end)
end
}
I realize that, but if filter() could do that for me (and save me a few steps), it'd make my scripts smaller and more legible... Hence my question!
Code: Select all
.forEach(function(foundDevice,wildcardString)
dz.log('Device ' .. foundDevice.name .. ' matches ' .. foundDevice.matchingWildcard,dz.LOG_FORCE )
if (foundDevice.matchingWildcard == wildcardedNameTable[1]) then
dz.log('only the first wildcard',dz.LOG_FORCE )
end
end)
Users browsing this forum: No registered users and 1 guest