Re: need a loop for reading messages for logging
Posted: Sunday 30 June 2019 20:33
it is the dashticz environment....
Open source Home Automation System
https://forum.domoticz.com/
Next try.pvklink wrote: ↑Sunday 30 June 2019 22:22 Lines attached is only when the script has executed more than one
globalMessage(add, message .. ' AVOND AAN: huiskamerverlichting wordt AAN gezet...')
before globalMessage() -- dump
When it concerns only one globalMessage(add, message .. ' AVOND AAN: huiskamerverlichting wordt AAN gezet...')
all went OK!
Code: Select all
return
{
data =
{
myGlobalVar = { initial = 12 }
},
helpers =
{
alertLidl = function(dz, action, period)
local controlVar = dz.variables("controlVar")
local value = controlVar.value
if controlVar.value ~= action then
controlVar.set(action)
if period then
controlVar.set(value).afterSec(period)
dz.log("alert requested; controlVar set to " .. action .. ". It will return to ".. value .. " after " .. period .. " seconds." ,dz.LOG_FORCE)
else
dz.log("alert requested; controlVar set to " .. action ,dz.LOG_FORCE)
end
else
dz.log("No changed needed; controlVar is already set to " .. value,dz.LOG_DEBUG)
end
end,
addMessage =
function(dz, item, info, message, messages)
local trigger = item.isDevice and (", Device: " .. item.name ) or (", Timer: " .. item.trigger)
messages[#messages + 1] = {}
messages[#messages].log = 'scriptname: ' .. info.scriptName .. trigger .. ' ' .. message
messages[#messages].text = dz.time.rawDate .. ' ' .. dz.time.rawTime .. ' : ' .. message
return messages
end,
dumpMessages =
function(dz, messages)
local maxLines = 8 -- user configurable
local dashticz = true -- true or false
local textDevice = dz.devices('timerlog') -- user configurable
local currentText = textDevice.text
local newText = currentText
local lf = "\r\n"
local dashticzLF = "<br>"
for i, record in ipairs(messages) do
dz.log(record.log, dz.LOG_INFO)
lf = dahshticz and (lf .. dashticzLF) or lf
newText = record.text .. lf .. newText
end
dz.log(newText, dz.LOG_INFO)
if newText ~= currentText then
lines = dz.utils.stringSplit(newText, lf) -- create lines table from newText string
newText = table.concat(lines,lf, 1, (math.min(maxLines,#lines))) -- recreate newText string from first maxLines
textDevice.updateText(newText)
end
end,
}
}
Code: Select all
return
{
data =
{
myGlobalVar = { initial = 12 }
},
helpers =
{
alertLidl = function(dz, action, period)
local controlVar = dz.variables("controlVar")
local value = controlVar.value
if controlVar.value ~= action then
controlVar.set(action)
if period then
controlVar.set(value).afterSec(period)
dz.log("alert requested; controlVar set to " .. action .. ". It will return to ".. value .. " after " .. period .. " seconds." ,dz.LOG_FORCE)
else
dz.log("alert requested; controlVar set to " .. action ,dz.LOG_FORCE)
end
else
dz.log("No changed needed; controlVar is already set to " .. value,dz.LOG_DEBUG)
end
end,
addMessage =
function(dz, item, info, message, messages)
local trigger = item.isDevice and (", Device: " .. item.name ) or (", Timer: " .. item.trigger)
messages[#messages + 1] = {}
messages[#messages].log = 'scriptname: ' .. info.scriptName .. trigger .. ' ' .. message
--messages[#messages].text = dz.time.rawDate .. ' ' .. dz.time.rawTime .. ' : ' .. message -- deze werkt met local if <br> en lines en newText disablen
messages[#messages].text = dz.time.rawDate .. ' ' .. dz.time.rawTime .. ' : ' .. message .. '<br>'
return messages
end,
dumpMessages =
function(dz, messages)
local textDevice = dz.devices('timerlog')
local currentText = textDevice.text
local newText = currentText
--local lf = '<br>'
--local lf = "\n"
local lf = "\r\n"
local maxLines = 8
for i, record in ipairs(messages) do
dz.log(record.log, dz.LOG_INFO)
newText = record.text .. lf .. newText
end
dz.log(newText, dz.LOG_INFO)
if newText ~= currentText then
lines = dz.utils.stringSplit(newText, lf) -- create lines table from newText string
newText = table.concat(lines, lf, 1, (math.min(maxLines,#lines))) -- recreate newText string from first maxLines
textDevice.updateText(newText)
end
end,
}
}
Code: Select all
return
{
data =
{
myGlobalVar = { initial = 12 }
},
helpers =
{
alertLidl = function(dz, action, period)
local controlVar = dz.variables("controlVar")
local value = controlVar.value
if controlVar.value ~= action then
controlVar.set(action)
if period then
controlVar.set(value).afterSec(period)
dz.log("alert requested; controlVar set to " .. action .. ". It will return to ".. value .. " after " .. period .. " seconds." ,dz.LOG_FORCE)
else
dz.log("alert requested; controlVar set to " .. action ,dz.LOG_FORCE)
end
else
dz.log("No changed needed; controlVar is already set to " .. value,dz.LOG_DEBUG)
end
end,
addMessage =
function(dz, item, info, message, messages)
local trigger = item.isDevice and (", Device: " .. item.name ) or (", Timer: " .. item.trigger)
messages[#messages + 1] = {}
messages[#messages].log = 'scriptname: ' .. info.scriptName .. trigger .. ' ' .. message
messages[#messages].text = dz.time.rawDate .. ' ' .. dz.time.rawTime .. ' : ' .. message
--messages[#messages].text = dz.time.rawDate .. ' ' .. dz.time.rawTime .. ' : ' .. message .. '<br>'
return messages
end,
dumpMessages =
function(dz, messages)
local textDevice = dz.devices('timerlog')
local currentText = textDevice.text
local newText = currentText
local lf = '<br>'
--local lf = "\n"
--local lf = "\r\n"
local maxLines = 8
for i, record in ipairs(messages) do
dz.log(record.log, dz.LOG_INFO)
newText = record.text .. lf .. newText
end
dz.log(newText, dz.LOG_INFO)
if newText ~= currentText then
--lines = dz.utils.stringSplit(newText, lf) -- create lines table from newText string
--newText = table.concat(lines, lf, 1, (math.min(maxLines,#lines))) -- recreate newText string from first maxLines
textDevice.updateText(newText)
end
end,
}
}
Code: Select all
local iftttvar = "iftttvar"
return
{
on =
{ variables = { iftttvar },
},
logging =
{
level = domoticz.LOG_DEBUG,
marker = 'ifttt',
},
execute = function(dz, item, info)
local validBaseTypes = { device=true, group=true, scene=true, uservariable=false, camera=false }
local validActions = { ON=true, OFF=true }
result = dz.utils.stringSplit(item.value,'/')
local name = result[1]
local action = string.upper(result[2])
local parm1 = result[3]
local stype = result[4]
local messageTable = {}
local add = 'add'
local function globalMessage(actionx, message )
if actionx == add then
messageTable = dz.helpers.addMessage(dz, item, info, message, messageTable )
else
dz.helpers.dumpMessages(dz, messageTable)
end
end
if parm1 == nil then parm1 = 'undefined' end -- par1 is de selectornaam of selectorlevel
if stype == nil then stype = 'undefined' end -- stype is of par naam 1 of level is 2
local function getBaseType(name)
for i, tuple in ipairs(_G.domoticzData) do
if tuple.name == name then
return tuple.baseType, tuple.id
end
end
end
local baseType, idx = getBaseType(name)
if baseType and validBaseTypes[baseType] then
local target
if baseType == 'device' then
target = dz.devices(name)
elseif baseType == 'group' then
target = dz.groups(name)
elseif baseType == 'scene' then
target = dz.scenes(name)
validActions.OFF = nil -- No Off action for scenes
end
if validActions[action] then
if action == 'ON' then
if parm1 ~= 'undefined' then
if stype == '1' or stype == 'undefined' then
globalMessage(add, ' IFTTT AAN: ,settings: ' .. item.value)
target.switchSelector(parm1) --parm selector_name
elseif stype == '2' then
globalMessage(add, ' IFTTT AAN: ,settings: ' .. item.value)
target.switchSelector(tonumber(parm1)) --parm selector_id
else -- foute waarde
globalMessage(add, ' IFTTT AAN: ,foute waarde: settings: ' .. item.value)
end
else
globalMessage(add, ' IFTTT AAN: ,settings: ' .. item.value)
target.switchOn()
end
elseif action == 'OFF' then
globalMessage(add, ' IFTTT AAN: ,settings: ' .. item.value )
target.switchOff()
else -- no other actions implemented yet
globalMessage(add, ' IFTTT AAN: ,foute action waarde: settings: ' .. action)
end
else
globalMessage(add, ' IFTTT AAN: , action: ' .. action .. ' is not implemented for ' .. baseType .. ' Name ' .. name .. '!')
end
elseif baseType then
globalMessage(add, ' IFTTT AAN: , onbekende basetype: ' .. baseType) -- dz.LOG_ERROR evt ook doorgeven
else
globalMessage(add, ' IFTTT AAN: , name not found!: ' .. name )
end
globalMessage() -- dump
end
}
Code: Select all
return
{
data =
{
myGlobalVar = { initial = 12 }
},
helpers =
{
alertLidl = function(dz, action, period)
local controlVar = dz.variables("controlVar")
local value = controlVar.value
if controlVar.value ~= action then
controlVar.set(action)
if period then
controlVar.set(value).afterSec(period)
dz.log("alert requested; controlVar set to " .. action .. ". It will return to ".. value .. " after " .. period .. " seconds." ,dz.LOG_FORCE)
else
dz.log("alert requested; controlVar set to " .. action ,dz.LOG_FORCE)
end
else
dz.log("No changed needed; controlVar is already set to " .. value,dz.LOG_DEBUG)
end
end,
addMessage =
function(dz, item, info, message, messages)
local trigger = item.isDevice and (", Device: " .. item.name ) or (", Timer: " .. item.trigger)
messages[#messages + 1] = {}
messages[#messages].log = 'scriptname: ' .. info.scriptName .. trigger .. ' ' .. message
messages[#messages].text = dz.time.rawDate .. ' ' .. dz.time.rawTime .. ' : ' .. message
--messages[#messages].text = dz.time.rawDate .. ' ' .. dz.time.rawTime .. ' : ' .. message .. '<br>'
return messages
end,
dumpMessages =
function(dz, messages)
local textDevice = dz.devices('timerlog')
local currentText = textDevice.text
local newText = currentText
local lf = '<br>'
--local lf = "\n"
--local lf = "\r\n"
local maxLines = 8
for i, record in ipairs(messages) do
dz.log(record.log, dz.LOG_INFO)
newText = record.text .. lf .. newText
end
dz.log(newText, dz.LOG_INFO)
if newText ~= currentText then
--lines = dz.utils.stringSplit(newText, lf) -- create lines table from newText string
--newText = table.concat(lines, lf, 1, (math.min(maxLines,#lines))) -- recreate newText string from first maxLines
textDevice.updateText(newText)
end
end,
}
}
Yes, that is indeed why you see the error. Try and replace that part of global data withpvklink wrote: ↑Wednesday 03 July 2019 10:14 Only with ifttt control var script i cant find why it is missing a value!
I think that it has something to do with global_data
local trigger = item.isDevice and (", Device: " .. item.name ) or (", Timer: " .. item.trigger)
iftttvar i not a device or timer..
Code: Select all
addMessage =
function(dz, item, info, message, messages)
local trigger
if item.isDevice then trigger = ", Device: " .. item.name
elseif item.isTimer then trigger = ", Timer: " .. item.trigger
elseif item.isVariable then trigger = ", Variable: " .. item.name
else trigger = ", Unknown trigger"
end
messages[#messages + 1] = {}
messages[#messages].log = 'scriptname: ' .. info.scriptName .. trigger .. ' ' .. message
messages[#messages].text = dz.time.rawDate .. ' ' .. dz.time.rawTime .. ' : ' .. message
--messages[#messages].text = dz.time.rawDate .. ' ' .. dz.time.rawTime .. ' : ' .. message .. '<br>'
return messages
end,
Code: Select all
return {
on = { devices = { 'test' }},
execute = function(dz, item, info)
local messageTable = {}
local add = 'add'
local function globalMessage(action, message )
if action == add then
messageTable = dz.helpers.addMessage(dz, item, info, message, messageTable )
else
dz.helpers.dumpMessages(dz, messageTable)
end
end -- dz.devices('timerlog').updateText(dz.time.rawDate .. ' ' .. dz.time.rawTime .. ' : leeg')
globalMessage(add, ' test 0 voor usb')
--globalMessage() -- dump
dz.devices('usb lamp').switchSelector(40) -- the script for usb lamp also writes to the log !!!when is is not remarked out the other logs are not visible
--dz.devices('Bewegingsservice').switchOff()
globalMessage(add, ' test 1 na usb')
globalMessage(add, ' test 2 na usb')
globalMessage() -- dump
end
}
}
Code: Select all
addMessage =
function(dz, item, info, message, messages, logcode)
-- logcode 0=no message written, 1= message domoticz log written, 2 =message = textbox, 3= all written
-- what if logcode nil is, then default = 3
if logcode > 0 then
local trigger
if item.isDevice then
trigger = ", Device: " .. item.name
elseif item.isTimer then
trigger = ", Timer: " .. item.trigger
elseif item.isVariable then
trigger = ", Variable: " .. item.name
else trigger = ", Unknown trigger"
end
messages[#messages + 1] = {}
if logcode =1 or logcode = 3 then
messages[#messages].log = 'scriptname: ' .. info.scriptName .. trigger .. ' ' .. message
if logcode =2 or logcode = 3 then
messages[#messages].text = dz.time.rawDate .. ' ' .. dz.time.rawTime .. ' : ' .. message
--messages[#messages].text = dz.time.rawDate .. ' ' .. dz.time.rawTime .. ' : ' .. message .. '<br>'
end
end
return messages
end,
dumpMessages =
function(dz, messages)
local textDevice = dz.devices('timerlog')
local currentText = textDevice.text
local newText = currentText
local lf = '<br>'
--local lf = "\n"
--local lf = "\r\n"
local maxLines = 8
for i, record in ipairs(messages) do
dz.log(record.log, dz.LOG_INFO)
newText = record.text .. lf .. newText
end
dz.log(newText, dz.LOG_INFO)
if newText ~= currentText then
--lines = dz.utils.stringSplit(newText, lf) -- create lines table from newText string
--newText = table.concat(lines, lf, 1, (math.min(maxLines,#lines))) -- recreate newText string from first maxLines
textDevice.updateText(newText)
end
end,
Code: Select all
return {
on = { devices = { 'test' }},
execute = function(dz, item, info)
local logcode = 3
local messageTable = {}
local add = 'add'
local del = 'del'
local chg = 'chg'
local function globalMessage(action, message, logcode)
if logcode == nil then logcode = 3 end
if action == add and logcode > 0 then
messageTable = dz.helpers.addMessage(dz, item, info, message, messageTable, logcode)
elseif action == del then
dz.devices('timerlog').updateText(message)
elseif action == chg then
dz.helpers.dumpMessages(dz, messageTable)
end
end
--globalMessage(del, 'nu verwijderen') -- delete
globalMessage(add, ' test 0 voor usb',0)
-- globalMessage() -- dump
--dz.devices('usb lamp').switchSelector(40) -- the script for usb lamp also writes to the log !!!when is is not remarked out the other logs are not visible
--dz.devices('Bewegingsservice').switchOff()
globalMessage(add, ' test 1 na usb',0)
globalMessage(add, ' test 2 na usb',0)
globalMessage(add, ' test 3 na usb',0)
globalMessage(add, ' test 4 na usb',0)
globalMessage(add, ' test 5 na usb',logcode)
globalMessage(chg) -- dump
end
}
There is no such thing as nested scripts in the domoticz Eventsystem.
Probably because they both use the same domoticz object so there 'currenttext' is the same for both. A way to prevent this type of conflict is to get 'currenttext' from a variable in global data and not from the text device.
Code: Select all
return {
on = { devices = { 'test' }},
execute = function(dz, item, info)
local logcode = 3
local messageTable = {}
local add = 'add'
local del = 'del'
local chg = 'chg'
local function globalMessage(dz, action, message, logcode)
if logcode == nil then logcode = 3 end
if action == add and logcode > 0 then
messageTable = dz.helpers.addMessage(dz, item, info, message, messageTable, logcode)
elseif action == del then
dz.globalData.mylogging = message
dz.devices('timerlog').updateText(message)
elseif action == chg then
dz.helpers.dumpMessages(dz, messageTable)
end
end
--globalMessage(dz,del, dz.time.rawDate .. ' ' .. dz.time.rawTime .. ' :' .. ' TIMERLOG CLEAN: timerlog wordt geschoond...') -- delete
globalMessage(dz,del, dz.time.rawDate .. ' ' .. dz.time.rawTime .. ' :' .. ' TIMERLOG CLEAN: timerlog wordt geschoond...' .. '<br>') -- delete
globalMessage(dz,add, ' test 0 voor usb',1)
globalMessage(dz,add, ' test 1 voor usb',1)
dz.devices('usb lamp').switchSelector(40) -- the script for usb lamp also writes to the log !!!when is is not remarked out the other logs are not visible
--dz.devices('Bewegingsservice').switchOff()
globalMessage(dz,add, ' test 2 na usb',0)
globalMessage(dz,add, ' test 3 na usb',0)
globalMessage(dz,add, ' test 4 na usb',3)
globalMessage(dz,add, ' test 5 na usb',0)
globalMessage(dz,add, ' test 6 na usb',logcode)
globalMessage(dz,chg) -- dump
end
}
Code: Select all
return
{
data =
{
myGlobalVar = { initial = 12 },
mylogging = {initial = 'Eerst aanmaak van global variable mylogging in global_data.lua'},
},
helpers =
{
alertLidl = function(dz, action, period)
local controlVar = dz.variables("controlVar")
local value = controlVar.value
if controlVar.value ~= action then
controlVar.set(action)
if period then
controlVar.set(value).afterSec(period)
dz.log("alert requested; controlVar set to " .. action .. ". It will return to ".. value .. " after " .. period .. " seconds." ,dz.LOG_FORCE)
else
dz.log("alert requested; controlVar set to " .. action ,dz.LOG_FORCE)
end
else
dz.log("No changed needed; controlVar is already set to " .. value,dz.LOG_DEBUG)
end
end,
addMessage =
function(dz, item, info, message, messages)
local trigger
if item.isDevice then
trigger = ", Device: " .. item.name
elseif item.isTimer then
trigger = ", Timer: " .. item.trigger
elseif item.isVariable then
trigger = ", Variable: " .. item.name
else trigger = ", Unknown trigger"
end
messages[#messages + 1] = {}
messages[#messages].log = 'scriptname: ' .. info.scriptName .. trigger .. ' ' .. message
messages[#messages].text = dz.time.rawDate .. ' ' .. dz.time.rawTime .. ' : ' .. message
return messages
end,
dumpMessages =
function(dz, messages)
local textDevice = dz.devices('timerlog')
local currentText = dz.globalData.mylogging
local newText = currentText
local lf = '<br>' --local lf = "\n" --local lf = "\r\n" --PVK \n of \r\n UITGEZET ANDERS werkt dashticz niet
local maxLines = 8
for i, record in ipairs(messages) do
dz.log(record.log, dz.LOG_INFO)
newText = record.text .. lf .. newText
end
dz.log(newText, dz.LOG_INFO)
if newText ~= currentText then
--lines = dz.utils.stringSplit(newText, lf) -- create lines table from newText string --PVK UITGEZET ANDERS werkt dashticz niet
--newText = table.concat(lines, lf, 1, (math.min(maxLines,#lines))) -- recreate newText string from first maxLines --PVK UITGEZET ANDERS werkt dashticz niet
textDevice.updateText(newText)
dz.globalData.mylogging = newText -- ADDED
end
end,
}
}
Code: Select all
local logcode = 3
local messageTable = {}
local add = 'add'
local del = 'del'
local chg = 'chg'
local function globalMessage(action, message, logcode)
if logcode == nil then logcode = 3 end
if action == add and logcode > 0 then
messageTable = dz.helpers.addMessage(dz, item, info, message, messageTable, logcode)
elseif action == del then
dz.globalData.mylogging = message
dz.devices('timerlog').updateText(message)
elseif action == chg then
dz.helpers.dumpMessages(dz, messageTable)
end
end
Code: Select all
019-07-06 13:53:05.460 (zwavepluspvk) Light/Switch (printer)
2019-07-06 13:53:05.416 Error: dzVents: Error: (2.4.24) Timers: An error occurred when calling event handler DZ_schakelgroepen
2019-07-06 13:53:05.416 Error: dzVents: Error: (2.4.24) Timers: /home/pi/domoticz/scripts/dzVents/scripts/global_data.lua:58: attempt to concatenate field 'text' (a nil value)
Code: Select all
return
{
data =
{
myGlobalVar = { initial = 12 },
mylogging = {initial = 'Eerst aanmaak van global variable mylogging in global_data.lua'},
},
helpers =
{
alertLidl = function(dz, action, period)
local controlVar = dz.variables("controlVar")
local value = controlVar.value
if controlVar.value ~= action then
controlVar.set(action)
if period then
controlVar.set(value).afterSec(period)
dz.log("alert requested; controlVar set to " .. action .. ". It will return to ".. value .. " after " .. period .. " seconds." ,dz.LOG_FORCE)
else
dz.log("alert requested; controlVar set to " .. action ,dz.LOG_FORCE)
end
else
dz.log("No changed needed; controlVar is already set to " .. value,dz.LOG_DEBUG)
end
end,
addMessage =
function(dz, item, info, message, messages,logcode)
local trigger
if item.isDevice then
trigger = ", Device: " .. item.name
elseif item.isTimer then
trigger = ", Timer: " .. item.trigger
elseif item.isVariable then
trigger = ", Variable: " .. item.name
else trigger = ", Unknown trigger"
end
messages[#messages + 1] = {}
if logcode == 1 or logcode == 3 then
messages[#messages].log = 'scriptname: ' .. info.scriptName .. trigger .. ' ' .. message
end
if logcode >= 2 then
messages[#messages].text = dz.time.rawDate .. ' ' .. dz.time.rawTime .. ' : ' .. message
end
return messages
end,
dumpMessages =
function(dz, messages)
local textDevice = dz.devices('timerlog')
local currentText = dz.globalData.mylogging
local newText = currentText
local lf = '<br>' --local lf = "\n" --local lf = "\r\n" --PVK \n of \r\n UITGEZET ANDERS werkt dashticz niet
local maxLines = 8
for i, record in ipairs(messages) do
dz.log(record.log, dz.LOG_INFO)
newText = record.text .. lf .. newText
end
dz.log(newText, dz.LOG_INFO)
if newText ~= currentText then
--lines = dz.utils.stringSplit(newText, lf) -- create lines table from newText string --PVK UITGEZET ANDERS werkt dashticz niet
--newText = table.concat(lines, lf, 1, (math.min(maxLines,#lines))) -- recreate newText string from first maxLines --PVK UITGEZET ANDERS werkt dashticz niet
textDevice.updateText(newText)
dz.globalData.mylogging = newText -- ADDED
end
end,
}
}
When using the parm 1, you don't enter anything in the text field of the messages record in function addMessage but in function dumpMessages you still expect something to be there. dzVents (Lua) is quite powerful but without a wand it cannot perform magic