Page 1 of 1
Event triggered multiple times at once
Posted: Friday 22 June 2018 9:25
by galinette
Hi,
I have a first dzvents script which updates 4 virtual sensors (solar angles, direct and diffuse irradiance)
I have another dzvents script which is triggered by the 4 devices
The issue is, each time the first one is executed, the second is fired 4 times in less than a second. This causes issues in the subsequent radio device calls. Even worse, at first call only one device has been updated, at second call another one, etc... This totally messes the script behavior, and I can't even add a condition to stop the script if it has already been called recently, as it then runs with only one of the device values updated.
Is there any solution? I'm using the stable release.
Thanks!
Re: Event triggered multiple times at once
Posted: Friday 22 June 2018 9:28
by galinette
Fragment of the first script which updates the solar data:
Code: Select all
domoticz.devices(idxDNI).updateRadiation(DNI)
domoticz.devices(idxGHI).updateRadiation(GHI)
domoticz.devices(idxSolarAzimuth).updateCustomSensor(domoticz.round(azimuth,0))
domoticz.devices(idxSolarAltitude).updateCustomSensor(domoticz.round(sunAltitude,0))
And the full event that gets executed four times:
Code: Select all
return {
logging = {
level = domoticz.LOG_INFO,
marker = 'Shading'
},
on = {
timer = {
'every 10 minutes'
},
devices = {
1150,
1151,
1155,
1156
}
},
data = {
lastDNI = {initial=0},
lastGHI = {initial=0},
lastAlt = {initial=0},
lastAzi = {initial=0}
},
execute = function(domoticz, device)
local idxSolarAzimuth = 1150
local idxSolarAltitude = 1151
local idxDNI = 1155 -- (Solar Radiation) Direct Normal Irradiance Device ID
local idxGHI = 1156 -- (Solar Radiation) Global Horizontal Irradiance Device ID
local groundAlbedo = 0.2
local solarAzi = domoticz.devices(idxSolarAzimuth).rawData[1]
local solarAlt = domoticz.devices(idxSolarAltitude).rawData[1]
local DNI = domoticz.devices(idxDNI).radiation
local GHI = domoticz.devices(idxGHI).radiation
local change = false
if solarAzi~=lastAzi then
domoticz.log('Azimuth changed', domoticz.LOG_INFO)
change = true
lastAzi = solarAzi
end
if solarAlt~=lastAlt then
domoticz.log('Altitude changed', domoticz.LOG_INFO)
change = true
lastAlt = solarAlt
end
if DNI~=lastDNI then
domoticz.log('DNI changed', domoticz.LOG_INFO)
change = true
lastDNI = DNI
end
if GHI~=lastGHI then
domoticz.log('GHI changed', domoticz.LOG_INFO)
change = true
lastGHI = GHI
end
if change then
local solarAziRad = solarAzi*3.14159/180
local solarAltRad = solarAlt*3.14159/180
local sx = math.cos(solarAziRad)*math.cos(solarAltRad)
local sy = math.sin(solarAziRad)*math.cos(solarAltRad)
local sz = math.sin(solarAltRad)
local horizontalDiffuseIrradiance = GHI-DNI*sz
local verticalDiffuseIrradiance = horizontalDiffuseIrradiance*(groundAlbedo*0.5+0.5)
local sqrthalf = math.sqrt(0.5)
local GI_SW = verticalDiffuseIrradiance+DNI*math.max(0.0,-sx*sqrthalf+sy*sqrthalf)
local GI_SE = verticalDiffuseIrradiance+DNI*math.max(0.0,-sx*sqrthalf-sy*sqrthalf)
local GI_NW = verticalDiffuseIrradiance+DNI*math.max(0.0, sx*sqrthalf+sy*sqrthalf)
local GI_NE = verticalDiffuseIrradiance+DNI*math.max(0.0, sx*sqrthalf-sy*sqrthalf)
domoticz.log('SW='..GI_SW, domoticz.LOG_INFO)
domoticz.log('SE='..GI_SE, domoticz.LOG_INFO)
domoticz.log('NW='..GI_NW, domoticz.LOG_INFO)
domoticz.log('NE='..GI_NE, domoticz.LOG_INFO)
end
end
}
Re: Event triggered multiple times at once
Posted: Monday 25 June 2018 18:03
by rrozema
Inside your function, use the device parameter to identify the device that actually was changed. Then only update the information for that particular device. Here's a snippet of code (untested) that might serve as an example. It checks only two devices, you'll have to add more elseif's at the location indicated by the comments, plus add some more code in the bottom:
Code: Select all
execute = function(domoticz, device)
local change = false
if (device.idx == idxSolarAzimuth) then
if (device.rawData[1] ~= domoticz.data.lastAzi) then
domoticz.log('Azimuth changed', domoticz.LOG_INFO)
domoticz.data.lastAzi = device.rawData[1]
change = true
end
elseif (device.idx == idxSolarAltitude) then
if (device.rawData[1] ~= domoticz.data.lastAlt) then
domoticz.log('Altitude changed', domoticz.LOG_INFO)
domoticz.data.lastAlt = device.rawData[1]
change = true
end
// add more elseifs, one for each device...
end
if change then
// do something
end
end
Your code will still be executed 4 times, once for each device, but it will know what data to act upon.