Page 1 of 2
Update of Lua to version 5.3 in domoticz V4.11439. with potential effects on Lua and dzVents scripts
Posted: Thursday 31 October 2019 10:43
by waaren
Dear dzVents and Lua script users.
Lua version changed in domoticz V4.11439 from version 5.2 to 5.3
You can check what version is in use in your domoticz version with
Code: Select all
domoticz.log('Lua version in use by domoticz ' .. domoticz.settings.domoticzVersion .. ' : ' .. _G._VERSION,domoticz.LOG_FORCE) -- in dzVents scripts
print('Lua version in use by domoticz : ' .. _G._VERSION) -- in Lua scripts
Some of the potential
breaking changes:
math.max and math.min do no longer return a number when comparing strings. The now return the same type as the input parameters. Use tonumber to convert to a number if your script expects one.
deprecated functions: math.atan2, math.cosh, math.sinh, math.tanh, math.pow, math.frexp, and math.ldexp. You can replace math.pow(x,y) with x^y
Introduction of an integer subtype for numbers with as side effect that a conversion of a float to a string now adds a .0 suffix to
the result if it looks like an integer. (For instance, the float 2.0 will be printed as 2.0, not as 2 )
Some possible work-arounds if this change is causing problems for you are:
Easiest: use math.floor -- returns the integral part of any number
Code: Select all
print (math.floor(6/1.999999999999)) -- >> 3
print (math.floor(6/2.000000000001)) -- >> 2
Modest: use math.tointeger -- returns an integer when convertible to an integer, Otherwise it returns nil.
Code: Select all
print (math.tointeger(5/2)) -- >> nil
print (math.tointeger(6/1.999999999999999)) -- >> nil
print (math.tointeger(6/1.9999999999999999)) -- >> 3
Complex: use math.modf -- returns the integral- and the fractional part of x in a table key [1] is the integer part, key[2] is the float part
Code: Select all
print( ({ math.modf(5/2)})[1]) -- >> 2
print( ({ math.modf(5/2)})[2]) -- >> 0.5
If you need more background on Lua 5.3 have a look at
the official manual
Re: Update of Lua in domoticz imminent with potential effects on Lua and dzVents scripts
Posted: Monday 04 November 2019 22:11
by kevster
Thanks for pointing this change out. I hit it on 4.11464 regarding lua scripts using the power function. Minor change fixed it.
Keep meaning to update the Wiki with my versions and solution but page at
https://www.domoticz.com/wiki/Lua_-_Oil_Tank_Monitor now has the bug.
Re: Update of Lua in domoticz imminent with potential effects on Lua and dzVents scripts
Posted: Monday 04 November 2019 22:28
by waaren
Later domoticz /dzVents versions do prevent a breaking error, using a home made math.pow function but with a deprecate warning urging to update script.
Re: Update of Lua in domoticz imminent with potential effects on Lua and dzVents scripts
Posted: Sunday 17 November 2019 22:48
by DutchHans
The virtual lux sensor and realtime solar script (lua version) has the bug aswell. Has somebody found a solution?. My altitude, azimuth and radiation work...but luxinfo is giving huge amounts...please help.
Regards Hans
Re: Update of Lua in domoticz imminent with potential effects on Lua and dzVents scripts
Posted: Sunday 17 November 2019 22:57
by waaren
DutchHans wrote: ↑Sunday 17 November 2019 22:48
The virtual lux sensor and realtime solar script (lua version) has the bug aswell. Has somebody found a solution?. My altitude, azimuth and radiation work...but luxinfo is giving huge amounts...please help.
Regards Hans
Can you share the script and the loglines with the error messages ?
Re: Update of Lua in domoticz imminent with potential effects on Lua and dzVents scripts
Posted: Sunday 17 November 2019 23:06
by DutchHans
Good evening, i will do it tomorrow morning.
Regards, Hans
Re: Update of Lua in domoticz imminent with potential effects on Lua and dzVents scripts
Posted: Monday 18 November 2019 8:14
by DutchHans
Here you go:
This script worked perfectly before the update to Lua 5.3
:
Code: Select all
--[[ Virtual Lux sensor and other real-time solar data
~/domoticz/scripts/lua/script_time_SolarSensor.lua
-- Autors ----------------------------------------------------------------
V1.0 - Sébastien Joly - Great original work
V1.1 - Neutrino - Adaptation to Domoticz
V1.2 - Jmleglise - An acceptable approximation of the lux below 1° altitude for Dawn and dusk + translation + several changes to be more userfriendly.
V1.3 - Jmleglise - keep the time of black night in lasptUpdate
V1.4 - use the API instead of updateDevice to update the data of the virtual sensor to be able of using devicechanged['Lux'] in our scripts. (Due to a bug in Domoticz that doesn't catch the devicechanged event of the virtual sensor)
]]--
-- Variables to customize ------------------------------------------------
local localhost = '192.xxx.xxx.xxx:8080' -- Set your port. (Not the universal IP).
local city = "xxx" -- Your city for Wunderground API
local countryCode = "DE" -- Your country code for Wunderground API
local idxLux ='490' -- Your virtual Lux Device ID
local idxSolarAzimuth ='1307' -- Your virtual Azimuth Device ID
local idxSolarAltitude ='1308' -- Your virtual Solar Altitude Device ID
local idxUserVarOcta='6' -- Your user variable ID , named octa
local wuAPIkey = "xxxxxxxxxxxxxx" -- Your Weather Underground API Key
local latitude = xxx -- your home
local longitude = xxx -- your home
local altitude = xxx -- Your home altitude : run once in debug = 1 to found your altitude in Log and write it here
local WMOID = 'xxx' -- Your nearest SYNOP Station for ogimet (to get Cloud layer). Run once with debug=1 to get it in the log. (or, better, choose it there : http://www.ogimet.com/gsynop_nav.phtml.en )
local DEBUG = 0 -- 0 , 1 for domoticz log , 2 for file log
-- and customize the URL of api.wunderground around line 104 according to your country.
-- Below , edit at your own risk ------------------------------------------
function leapYear(year)
return year%4==0 and (year%100~=0 or year%400==0)
end
function split(s, delimiter)
result = {};
for match in (s..delimiter):gmatch("(.-)"..delimiter) do
table.insert(result, match);
end
return result;
end
function round(num, dec)
if num == 0 then
return 0
else
local mult = 10^(dec or 0)
return math.floor(num * mult + 0.5) / mult
end
end
commandArray = {}
--time = os.date("*t")
--if ((time.min % 5)==0) then -- Run every 5 minutes. Check the wundergroud API limitation before changing this
json = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")() -- For Linux
--json = (loadfile "D:\\Domoticz\\scripts\\lua\\json.lua")() -- For Windows
local arbitraryTwilightLux=6.32 -- W/m² egal 800 Lux (the theoritical value is 4.74 but I have more accurate result with 6.32...)
local constantSolarRadiation = 1361 -- Solar Constant W/m²
if (uservariables['octa'] == nil) then print("Error : Did you create the Uservariable octa ?") end
-- API Wunderground
--local config=assert(io.popen('curl --connect-timeout 10 http://api.wunderground.com/api/'..wuAPIkey..'/conditions/q/'..countryCode..'/'..city..'.json'))
--local location = config:read('*all')
--config:close()
--local jsonLocation = json:decode(location)
--if( DEBUG == 1) then
-- local latitude = jsonLocation.current_observation.display_location.latitude
-- local longitude = jsonLocation.current_observation.display_location.longitude
-- local altitude = jsonLocation.current_observation.display_location.elevation
-- print('Lat: '..latitude..'Long: '..longitude..'Alt: '..altitude)
--end
--relativePressure = jsonLocation.current_observation.pressure_mb -- if you have an another way to get the Pressure, (local barometer ...) then you may optimize the script and avoid the call to api.wunderground)
relativePressure = uservariables['AirPressure']
----------------------------------
local year = os.date("%Y")
local numOfDay = os.date("%j")
if leapYear(year) == true then
nbDaysInYear = 366 -- How many days in the year ?
else
nbDaysInYear = 365
end
angularSpeed = 360/365.25
local Declinaison = math.deg(math.asin(0.3978 * math.sin(math.rad(angularSpeed) *(numOfDay - (81 - 2 * math.sin((math.rad(angularSpeed) * (numOfDay - 2))))))))
timeDecimal = (os.date("!%H") + os.date("!%M") / 60) -- Coordinated Universal Time (UTC)
solarHour = timeDecimal + (4 * longitude / 60 ) -- The solar Hour
hourlyAngle = 15 * ( 12 - solarHour ) -- hourly Angle of the sun
sunAltitude = math.deg(math.asin(math.sin(math.rad(latitude))* math.sin(math.rad(Declinaison)) + math.cos(math.rad(latitude)) * math.cos(math.rad(Declinaison)) * math.cos(math.rad(hourlyAngle))))-- the height of the sun in degree, compared with the horizon
local azimuth = math.acos((math.sin(math.rad(Declinaison)) - math.sin(math.rad(latitude)) * math.sin(math.rad(sunAltitude))) / (math.cos(math.rad(latitude)) * math.cos(math.rad(sunAltitude) ))) * 180 / math.pi -- deviation of the sun from the North, in degree
local sinAzimuth = (math.cos(math.rad(Declinaison)) * math.sin(math.rad(hourlyAngle))) / math.cos(math.rad(sunAltitude))
if(sinAzimuth<0) then azimuth=360-azimuth end
sunstrokeDuration = math.deg(2/15 * math.acos(- math.tan(math.rad(latitude)) * math.tan(math.rad(Declinaison)))) -- duration of sunstroke in the day . Not used in this calculation.
RadiationAtm = constantSolarRadiation * (1 +0.034 * math.cos( math.rad( 360 * numOfDay / nbDaysInYear ))) -- Sun radiation (in W/m²) in the entrance of atmosphere.
-- Coefficient of mitigation M
absolutePressure = relativePressure - round((altitude/ 8.3),1) -- hPa
sinusSunAltitude = math.sin(math.rad(sunAltitude))
M0 = math.sqrt(1229 + math.pow(614 * sinusSunAltitude,2)) - 614 * sinusSunAltitude
M = M0 * relativePressure/absolutePressure
if (DEBUG == 1) then
print('<b style="color:Blue"============== SUN LOG ==================</b>')
print(os.date("%Y-%m-%d %H:%M:%S", os.time()))
print(city .. ", latitude:" .. latitude .. ", longitude:" .. longitude)
print("Home altitude = " .. tostring(altitude) .. " m")
print("number Of Day = " .. numOfDay)
if nbDaysInYear==366 then
print(year .." is a leap year !")
else
print(year.." is not a leap year")
end
print("Angular Speed = " .. angularSpeed .. " per day")
print("Declinaison = " .. Declinaison .. "°")
print("Universel Coordinated Time (UTC)".. timeDecimal .." H.dd")
print("Solar Hour ".. solarHour .." H.dd")
print("Altitude of the sun = " .. sunAltitude .. "°")
print("Angular hourly = ".. hourlyAngle .. "°")
print("Azimuth of the sun = " .. azimuth .. "°")
print("Duration of the sunstroke of the day = " .. round(sunstrokeDuration,2) .." H.dd") -- not used
print("Radiation max in atmosphere = " .. round(RadiationAtm,2) .. " W/m²")
print("Local relative pressure = " .. relativePressure .. " hPa")
print("Absolute pressure in atmosphere = " .. absolutePressure .. " hPa")
print("Coefficient of mitigation M = " .. M .." M0:"..M0)
end
-- Get SYNOP message from Ogimet web site
hourUTCminus1 = os.date("!%H")-1
if string.len(hourUTCminus1) == 1 then
hourUTCminus1 = "0" .. hourUTCminus1
end
UTC = os.date("%Y%m%d").. hourUTCminus1.."00" -- os.date("!%M")
local jsonResultOgimet = '/var/tmp/OgimetJson.json' -- Temporary file to store the servers response
local fetchIntervalMins = 5 -- (Integer) (Minutes, Range 5-60) How often the data shall be retrieved
local callUrl = false
if (os.date('*t').min % fetchIntervalMins) == 0 then
callUrl = true
elseif ((os.date('*t').min -1) % fetchIntervalMins) ~= 0 then
return end if callUrl then
local urlOgimet ='http://www.ogimet.com/cgi-bin/getsynop?block='..WMOID..'&begin='..UTC..''
--print('Ogimet URL used: '..urlOgimet)
os.execute('curl -s --connect-timeout 5 "'..urlOgimet..'" > '..jsonResultOgimet..'&')
return -- Nothing more to do for now, we'll be back in a minute to read the data!
end
local f = assert(io.open(jsonResultOgimet, "rb"))
local synop = f:read("*all")
--print(synop)
f:close()
if( DEBUG == 1) then print('ogimet:'..synop) end
if string.find(synop,"Status: 500") == nil
then
rslt = split(synop,",")
if rslt ~= nil then
CodeStation = rslt[1]
rslt = split(synop, " "..CodeStation.. " ")
if rslt[2] ~= nil then
Trame = string.gsub(rslt[2], "=", "")
Trame = CodeStation .." ".. Trame
rslt = split(Trame, " ")
Octa = string.sub(rslt[3], 1, 1) -- 3rd char is the cloud layer. 0=no cloud , 1-8= cloudy from 1 to 8 max , 9 =Fog , / = no data
end
if Octa == "/" or Octa==nil then -- not defined ? take the previous value
Octa = uservariables['octa']
elseif Octa == "9" then
Octa = 8
end
end
else
Octa = uservariables['octa']
end
-- os.execute('curl --connect-timeout 10 -s "http://192.168.188.58:8080/json.htm?type=command¶m=updateuservariable&idx='..idxUserVarOcta..'&vname=octa&vtype=0&vvalue='..tostring(Octa)..'"&')
commandArray[#commandArray + 1] = {['Variable:octa'] = tostring(Octa)}
Kc=1-0.75*math.pow(Octa/8,3.4) -- Factor of mitigation for the cloud layer
if sunAltitude > 1 then -- Below 1° of Altitude , the formulae reach their limit of precision.
directRadiation = RadiationAtm * math.pow(0.6,M) * sinusSunAltitude
scatteredRadiation = RadiationAtm * (0.271 - 0.294 * math.pow(0.6,M)) * sinusSunAltitude
totalRadiation = scatteredRadiation + directRadiation
Lux = totalRadiation / 0.0079 -- Radiation in Lux. 1 Lux = 0,0079 W/m²
weightedLux = Lux * Kc -- radiation of the Sun with the cloud layer
elseif sunAltitude <= 1 and sunAltitude >= -7 then -- apply theoretical Lux of twilight
directRadiation = 0
scatteredRadiation = 0
arbitraryTwilightLux=arbitraryTwilightLux-(1-sunAltitude)/8*arbitraryTwilightLux
totalRadiation = scatteredRadiation + directRadiation + arbitraryTwilightLux
Lux = totalRadiation / 0.0079 -- Radiation in Lux. 1 Lux = 0,0079 W/m²
weightedLux = Lux * Kc -- radiation of the Sun with the cloud layer
elseif sunAltitude < -7 then -- no management of nautical and astronomical twilight...
directRadiation = 0
scatteredRadiation = 0
totalRadiation = 0
Lux = 0
weightedLux = 0 -- should be around 3,2 Lux for the nautic twilight. Nevertheless.
end
if (DEBUG == 1) then
print("Station SYNOP = " .. WMOID)
print( Octa .. " Octa")
print("Kc = " .. Kc)
print("Direct Radiation = ".. round(directRadiation,2) .." W/m²")
print("Scattered Radiation = ".. round(scatteredRadiation,2) .." W/m²")
print("Total radiation = " .. round(totalRadiation,2) .." W/m²")
print("Total Radiation in lux = ".. round(Lux,2).." Lux")
print("and at last, Total weighted lux = ".. round(weightedLux,2).." Lux")
end
if tonumber(otherdevices_svalues['Lux'])+round(weightedLux,0)>0 -- No update if Lux is already 0. So lastUpdate of the Lux sensor will keep the time when Lux has reached 0. (Kind of timeofday['SunsetInMinutes'])
then
commandArray[#commandArray + 1] = {['UpdateDevice'] = idxLux..'|0|'..tostring(round(weightedLux,0))} -- THis form is not recommended. due to limitation of the eventsystem of Domoticz
--commandArray[#commandArray + 1]={['OpenURL']="http://"..localhost.."/json.htm?type=command¶m=udevice&idx="..idxLux.."&nvalue=0&svalue="..tostring(round(weightedLux,0)) }
end
commandArray[#commandArray + 1] = {['UpdateDevice'] = idxSolarAzimuth..'|0|'..tostring(round(azimuth,0))}
--commandArray[#commandArray + 1]={['OpenURL']="http://"..localhost.."/json.htm?type=command¶m=udevice&idx="..idxSolarAzimuth.."&nvalue=0&svalue="..tostring(round(azimuth,0)) }
commandArray[#commandArray + 1] = {['UpdateDevice'] = idxSolarAltitude..'|0|'..tostring(round(sunAltitude,0))}
--commandArray[#commandArray + 1]={['OpenURL']="http://"..localhost.."/json.htm?type=command¶m=udevice&idx="..idxSolarAltitude.."&nvalue=0&svalue="..tostring(round(sunAltitude,0)) }
if (DEBUG == 2) then
logDebug=os.date("%Y-%m-%d %H:%M:%S",os.time())
logDebug=logDebug.." Azimuth:" .. azimuth .. " Height:" .. sunAltitude
logDebug=logDebug.." Octa:" .. Octa.." KC:".. Kc
logDebug=logDebug.." Direct:"..directRadiation.." inDirect:"..scatteredRadiation.." TotalRadiation:"..totalRadiation.." LuxCloud:".. round(weightedLux,2)
os.execute('echo '..logDebug..' >>logSun.txt') -- compatible Linux & Windows
end
--end
return commandArray
now it gives this error:
Code: Select all
2019-11-18 08:03:00.227 Error: EventSystem: in /home/pi/domoticz/scripts/lua/script_time_SolarSensor.lua: /home/pi/domoticz/scripts/lua/script_time_SolarSensor.lua:106: attempt to call a nil value (field 'pow')
I found out that math.pow(x,y) is depreciated in LUA 5.3 so changed it to x^y.
Azimuth and Altitude work correct but LUX gives huge amouts eg.: 9 223 372 036 854 776 000 lx
I have tried several things but can't figure out why...
Thanks for your help.
Regards, Hans
Re: Update of Lua in domoticz imminent with potential effects on Lua and dzVents scripts
Posted: Monday 18 November 2019 8:54
by waaren
DutchHans wrote: ↑Monday 18 November 2019 8:14
Code: Select all
2019-11-18 08:03:00.227 Error: EventSystem: in /home/pi/domoticz/scripts/lua/script_time_SolarSensor.lua: /home/pi/domoticz/scripts/lua/script_time_SolarSensor.lua:106: attempt to call a nil value (field 'pow')
Can you try with this and if still produce errors, execute after changing line 29 to
local DEBUG = 1
Code: Select all
--[[ Virtual Lux sensor and other real-time solar data
~/domoticz/scripts/lua/script_time_SolarSensor.lua
-- Autors ----------------------------------------------------------------
V1.0 - Sébastien Joly - Great original work
V1.1 - Neutrino - Adaptation to Domoticz
V1.2 - Jmleglise - An acceptable approximation of the lux below 1° altitude for Dawn and dusk + translation + several changes to be more userfriendly.
V1.3 - Jmleglise - keep the time of black night in lasptUpdate
V1.4 - use the API instead of updateDevice to update the data of the virtual sensor to be able of using devicechanged['Lux'] in our scripts. (Due to a bug in Domoticz that doesn't catch the devicechanged event of the virtual sensor)
V1.5 -- waaren - add local function math.pow as this function has been deprecated in Lua 5.3
]]--
-- Variables to customize ------------------------------------------------
local localhost = '192.xxx.xxx.xxx:8080' -- Set your port. (Not the universal IP).
local city = "xxx" -- Your city for Wunderground API
local countryCode = "DE" -- Your country code for Wunderground API
local idxLux ='490' -- Your virtual Lux Device ID
local idxSolarAzimuth ='1307' -- Your virtual Azimuth Device ID
local idxSolarAltitude ='1308' -- Your virtual Solar Altitude Device ID
local idxUserVarOcta='6' -- Your user variable ID , named octa
local wuAPIkey = "xxxxxxxxxxxxxx" -- Your Weather Underground API Key
local latitude = xxx -- your home
local longitude = xxx -- your home
local altitude = xxx -- Your home altitude : run once in debug = 1 to found your altitude in Log and write it here
local WMOID = 'xxx' -- Your nearest SYNOP Station for ogimet (to get Cloud layer). Run once with debug=1 to get it in the log. (or, better, choose it there : http://www.ogimet.com/gsynop_nav.phtml.en )
local DEBUG = 0 -- 0 , 1 for domoticz log , 2 for file log
-- and customize the URL of api.wunderground around line 104 according to your country.
-- Below , edit at your own risk ------------------------------------------
function math.pow(x, y)
-- Function math.pow(x, y) has been deprecated in Lua 5.3. Please consider changing code to x^y
return x^y
end
function leapYear(year)
return year%4==0 and (year%100~=0 or year%400==0)
end
function split(s, delimiter)
result = {};
for match in (s..delimiter):gmatch("(.-)"..delimiter) do
table.insert(result, match);
end
return result;
end
function round(num, dec)
if num == 0 then
return 0
else
local mult = 10^(dec or 0)
return math.floor(num * mult + 0.5) / mult
end
end
commandArray = {}
--time = os.date("*t")
--if ((time.min % 5)==0) then -- Run every 5 minutes. Check the wundergroud API limitation before changing this
json = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")() -- For Linux
--json = (loadfile "D:\\Domoticz\\scripts\\lua\\json.lua")() -- For Windows
local arbitraryTwilightLux=6.32 -- W/m² egal 800 Lux (the theoritical value is 4.74 but I have more accurate result with 6.32...)
local constantSolarRadiation = 1361 -- Solar Constant W/m²
if (uservariables['octa'] == nil) then print("Error : Did you create the Uservariable octa ?") end
-- API Wunderground
--local config=assert(io.popen('curl --connect-timeout 10 http://api.wunderground.com/api/'..wuAPIkey..'/conditions/q/'..countryCode..'/'..city..'.json'))
--local location = config:read('*all')
--config:close()
--local jsonLocation = json:decode(location)
--if( DEBUG == 1) then
-- local latitude = jsonLocation.current_observation.display_location.latitude
-- local longitude = jsonLocation.current_observation.display_location.longitude
-- local altitude = jsonLocation.current_observation.display_location.elevation
-- print('Lat: '..latitude..'Long: '..longitude..'Alt: '..altitude)
--end
--relativePressure = jsonLocation.current_observation.pressure_mb -- if you have an another way to get the Pressure, (local barometer ...) then you may optimize the script and avoid the call to api.wunderground)
relativePressure = uservariables['AirPressure']
----------------------------------
local year = os.date("%Y")
local numOfDay = os.date("%j")
if leapYear(year) == true then
nbDaysInYear = 366 -- How many days in the year ?
else
nbDaysInYear = 365
end
angularSpeed = 360/365.25
local Declinaison = math.deg(math.asin(0.3978 * math.sin(math.rad(angularSpeed) *(numOfDay - (81 - 2 * math.sin((math.rad(angularSpeed) * (numOfDay - 2))))))))
timeDecimal = (os.date("!%H") + os.date("!%M") / 60) -- Coordinated Universal Time (UTC)
solarHour = timeDecimal + (4 * longitude / 60 ) -- The solar Hour
hourlyAngle = 15 * ( 12 - solarHour ) -- hourly Angle of the sun
sunAltitude = math.deg(math.asin(math.sin(math.rad(latitude))* math.sin(math.rad(Declinaison)) + math.cos(math.rad(latitude)) * math.cos(math.rad(Declinaison)) * math.cos(math.rad(hourlyAngle))))-- the height of the sun in degree, compared with the horizon
local azimuth = math.acos((math.sin(math.rad(Declinaison)) - math.sin(math.rad(latitude)) * math.sin(math.rad(sunAltitude))) / (math.cos(math.rad(latitude)) * math.cos(math.rad(sunAltitude) ))) * 180 / math.pi -- deviation of the sun from the North, in degree
local sinAzimuth = (math.cos(math.rad(Declinaison)) * math.sin(math.rad(hourlyAngle))) / math.cos(math.rad(sunAltitude))
if(sinAzimuth<0) then azimuth=360-azimuth end
sunstrokeDuration = math.deg(2/15 * math.acos(- math.tan(math.rad(latitude)) * math.tan(math.rad(Declinaison)))) -- duration of sunstroke in the day . Not used in this calculation.
RadiationAtm = constantSolarRadiation * (1 +0.034 * math.cos( math.rad( 360 * numOfDay / nbDaysInYear ))) -- Sun radiation (in W/m²) in the entrance of atmosphere.
-- Coefficient of mitigation M
absolutePressure = relativePressure - round((altitude/ 8.3),1) -- hPa
sinusSunAltitude = math.sin(math.rad(sunAltitude))
M0 = math.sqrt(1229 + math.pow(614 * sinusSunAltitude,2)) - 614 * sinusSunAltitude
M = M0 * relativePressure/absolutePressure
if (DEBUG == 1) then
print('<b style="color:Blue"============== SUN LOG ==================</b>')
print(os.date("%Y-%m-%d %H:%M:%S", os.time()))
print(city .. ", latitude:" .. latitude .. ", longitude:" .. longitude)
print("Home altitude = " .. tostring(altitude) .. " m")
print("number Of Day = " .. numOfDay)
if nbDaysInYear==366 then
print(year .." is a leap year !")
else
print(year.." is not a leap year")
end
print("Angular Speed = " .. angularSpeed .. " per day")
print("Declinaison = " .. Declinaison .. "°")
print("Universel Coordinated Time (UTC)".. timeDecimal .." H.dd")
print("Solar Hour ".. solarHour .." H.dd")
print("Altitude of the sun = " .. sunAltitude .. "°")
print("Angular hourly = ".. hourlyAngle .. "°")
print("Azimuth of the sun = " .. azimuth .. "°")
print("Duration of the sunstroke of the day = " .. round(sunstrokeDuration,2) .." H.dd") -- not used
print("Radiation max in atmosphere = " .. round(RadiationAtm,2) .. " W/m²")
print("Local relative pressure = " .. relativePressure .. " hPa")
print("Absolute pressure in atmosphere = " .. absolutePressure .. " hPa")
print("Coefficient of mitigation M = " .. M .." M0:"..M0)
end
-- Get SYNOP message from Ogimet web site
hourUTCminus1 = os.date("!%H")-1
if string.len(hourUTCminus1) == 1 then
hourUTCminus1 = "0" .. hourUTCminus1
end
UTC = os.date("%Y%m%d").. hourUTCminus1.."00" -- os.date("!%M")
local jsonResultOgimet = '/var/tmp/OgimetJson.json' -- Temporary file to store the servers response
local fetchIntervalMins = 5 -- (Integer) (Minutes, Range 5-60) How often the data shall be retrieved
local callUrl = false
if (os.date('*t').min % fetchIntervalMins) == 0 then
callUrl = true
elseif ((os.date('*t').min -1) % fetchIntervalMins) ~= 0 then
return end if callUrl then
local urlOgimet ='http://www.ogimet.com/cgi-bin/getsynop?block='..WMOID..'&begin='..UTC..''
--print('Ogimet URL used: '..urlOgimet)
os.execute('curl -s --connect-timeout 5 "'..urlOgimet..'" > '..jsonResultOgimet..'&')
return -- Nothing more to do for now, we'll be back in a minute to read the data!
end
local f = assert(io.open(jsonResultOgimet, "rb"))
local synop = f:read("*all")
--print(synop)
f:close()
if( DEBUG == 1) then print('ogimet:'..synop) end
if string.find(synop,"Status: 500") == nil
then
rslt = split(synop,",")
if rslt ~= nil then
CodeStation = rslt[1]
rslt = split(synop, " "..CodeStation.. " ")
if rslt[2] ~= nil then
Trame = string.gsub(rslt[2], "=", "")
Trame = CodeStation .." ".. Trame
rslt = split(Trame, " ")
Octa = string.sub(rslt[3], 1, 1) -- 3rd char is the cloud layer. 0=no cloud , 1-8= cloudy from 1 to 8 max , 9 =Fog , / = no data
end
if Octa == "/" or Octa==nil then -- not defined ? take the previous value
Octa = uservariables['octa']
elseif Octa == "9" then
Octa = 8
end
end
else
Octa = uservariables['octa']
end
-- os.execute('curl --connect-timeout 10 -s "http://192.168.188.58:8080/json.htm?type=command¶m=updateuservariable&idx='..idxUserVarOcta..'&vname=octa&vtype=0&vvalue='..tostring(Octa)..'"&')
commandArray[#commandArray + 1] = {['Variable:octa'] = tostring(Octa)}
Kc=1-0.75*math.pow(Octa/8,3.4) -- Factor of mitigation for the cloud layer
if sunAltitude > 1 then -- Below 1° of Altitude , the formulae reach their limit of precision.
directRadiation = RadiationAtm * math.pow(0.6,M) * sinusSunAltitude
scatteredRadiation = RadiationAtm * (0.271 - 0.294 * math.pow(0.6,M)) * sinusSunAltitude
totalRadiation = scatteredRadiation + directRadiation
Lux = totalRadiation / 0.0079 -- Radiation in Lux. 1 Lux = 0,0079 W/m²
weightedLux = Lux * Kc -- radiation of the Sun with the cloud layer
elseif sunAltitude <= 1 and sunAltitude >= -7 then -- apply theoretical Lux of twilight
directRadiation = 0
scatteredRadiation = 0
arbitraryTwilightLux=arbitraryTwilightLux-(1-sunAltitude)/8*arbitraryTwilightLux
totalRadiation = scatteredRadiation + directRadiation + arbitraryTwilightLux
Lux = totalRadiation / 0.0079 -- Radiation in Lux. 1 Lux = 0,0079 W/m²
weightedLux = Lux * Kc -- radiation of the Sun with the cloud layer
elseif sunAltitude < -7 then -- no management of nautical and astronomical twilight...
directRadiation = 0
scatteredRadiation = 0
totalRadiation = 0
Lux = 0
weightedLux = 0 -- should be around 3,2 Lux for the nautic twilight. Nevertheless.
end
if (DEBUG == 1) then
print("Station SYNOP = " .. WMOID)
print( Octa .. " Octa")
print("Kc = " .. Kc)
print("Direct Radiation = ".. round(directRadiation,2) .." W/m²")
print("Scattered Radiation = ".. round(scatteredRadiation,2) .." W/m²")
print("Total radiation = " .. round(totalRadiation,2) .." W/m²")
print("Total Radiation in lux = ".. round(Lux,2).." Lux")
print("and at last, Total weighted lux = ".. round(weightedLux,2).." Lux")
end
if tonumber(otherdevices_svalues['Lux'])+round(weightedLux,0)>0 -- No update if Lux is already 0. So lastUpdate of the Lux sensor will keep the time when Lux has reached 0. (Kind of timeofday['SunsetInMinutes'])
then
commandArray[#commandArray + 1] = {['UpdateDevice'] = idxLux..'|0|'..tostring(round(weightedLux,0))} -- THis form is not recommended. due to limitation of the eventsystem of Domoticz
--commandArray[#commandArray + 1]={['OpenURL']="http://"..localhost.."/json.htm?type=command¶m=udevice&idx="..idxLux.."&nvalue=0&svalue="..tostring(round(weightedLux,0)) }
end
commandArray[#commandArray + 1] = {['UpdateDevice'] = idxSolarAzimuth..'|0|'..tostring(round(azimuth,0))}
--commandArray[#commandArray + 1]={['OpenURL']="http://"..localhost.."/json.htm?type=command¶m=udevice&idx="..idxSolarAzimuth.."&nvalue=0&svalue="..tostring(round(azimuth,0)) }
commandArray[#commandArray + 1] = {['UpdateDevice'] = idxSolarAltitude..'|0|'..tostring(round(sunAltitude,0))}
--commandArray[#commandArray + 1]={['OpenURL']="http://"..localhost.."/json.htm?type=command¶m=udevice&idx="..idxSolarAltitude.."&nvalue=0&svalue="..tostring(round(sunAltitude,0)) }
if (DEBUG == 2) then
logDebug=os.date("%Y-%m-%d %H:%M:%S",os.time())
logDebug=logDebug.." Azimuth:" .. azimuth .. " Height:" .. sunAltitude
logDebug=logDebug.." Octa:" .. Octa.." KC:".. Kc
logDebug=logDebug.." Direct:"..directRadiation.." inDirect:"..scatteredRadiation.." TotalRadiation:"..totalRadiation.." LuxCloud:".. round(weightedLux,2)
os.execute('echo '..logDebug..' >>logSun.txt') -- compatible Linux & Windows
end
--end
return commandArray
Re: Update of Lua in domoticz imminent with potential effects on Lua and dzVents scripts
Posted: Monday 18 November 2019 9:56
by DutchHans
this error occurs now:
Code: Select all
2019-11-18 09:55:00.858 Error: EventSystem: in /home/pi/domoticz/scripts/lua/script_time_SolarSensor.lua: /home/pi/domoticz/scripts/lua/script_time_SolarSensor.lua:34: '(' expected near '.'
Re: Update of Lua in domoticz imminent with potential effects on Lua and dzVents scripts
Posted: Monday 18 November 2019 10:08
by DutchHans
deleted the "local" ...seems to be working now.
Thanks a lot.
Hans
Re: Update of Lua in domoticz imminent with potential effects on Lua and dzVents scripts
Posted: Thursday 30 January 2020 19:35
by EddyG
I switched from the latest stable to the lastest beta.
Now I got these LUA errors.
Code: Select all
2020-01-30 19:34:40.850 Error: dzVents: Error: (2.5.7) ...i/domoticz/scripts/dzVents/scripts/electricity usage.lua:25: module 'socket.http' not found:
2020-01-30 19:34:40.850 no field package.preload['socket.http']
2020-01-30 19:34:40.850 no file '/usr/local/share/lua/5.3/socket/http.lua'
2020-01-30 19:34:40.850 no file '/usr/local/share/lua/5.3/socket/http/init.lua'
2020-01-30 19:34:40.850 no file '/usr/local/lib/lua/5.3/socket/http.lua'
2020-01-30 19:34:40.850 no file '/usr/local/lib/lua/5.3/socket/http/init.lua'
2020-01-30 19:34:40.850 no file './socket/http.lua'
2020-01-30 19:34:40.850 no file './socket/http/init.lua'
2020-01-30 19:34:40.850 no file '/home/pi/domoticz/scripts/dzVents/socket/http.lua'
2020-01-30 19:34:40.850 no file '/home/pi/domoticz/dzVents/runtime/socket/http.lua'
2020-01-30 19:34:40.850 no file '/home/pi/domoticz/dzVents/runtime/device-adapters/socket/http.lua'
2020-01-30 19:34:40.850 no file '/home/pi/domoticz/scripts/dzVents/dzVents/socket/http.lua'
2020-01-30 19:34:40.850 no file '/home/pi/domoticz/scripts/dzVents/scripts/socket/http.lua'
2020-01-30 19:34:40.850 no file '/home/pi/domoticz/scripts/dzVents/../lua/socket/http.lua'
2020-01-30 19:34:40.850 no file '/home/pi/domoticz/scripts/dzVents/scripts/modules/socket/http.lua'
2020-01-30 19:34:40.850 no file '/home/pi/domoticz/scripts/dzVents/socket/http.lua'
2020-01-30 19:34:40.850 no file '/home/pi/domoticz/scripts/dzVents/generated_scripts/socket/http.lua'
2020-01-30 19:34:40.850 no file '/home/pi/domoticz/scripts/dzVents/data/socket/http.lua'
2020-01-30 19:34:40.850 no file '/home/pi/domoticz/scripts/dzVents/modules/socket/http.lua'
2020-01-30 19:34:40.850 no file '/home/pi/domoticz/scripts/dzVents/socket/http.lua'
2020-01-30 19:34:40.850 no file '/home/pi/domoticz/scripts/dzVents/socket/http.lua'
2020-01-30 19:34:40.850 no file '/home/pi/domoticz/scripts/lua/socket/http.lua'
2020-01-30 19:34:40.850 no file '/usr/local/lib/lua/5.3/socket/http.so'
2020-01-30 19:34:40.850 no file '/usr/local/lib/lua/5.3/loadall.so'
2020-01-30 19:34:40.850 no file './socket/http.so'
2020-01-30 19:34:40.850 no file '/usr/local/lib/lua/5.3/socket.so'
2020-01-30 19:34:40.850 no file '/usr/local/lib/lua/5.3/loadall.so'
2020-01-30 19:34:40.850 no file './socket.so'
What do I need to install to get 5.3 running?
Re: Update of Lua in domoticz imminent with potential effects on Lua and dzVents scripts
Posted: Thursday 30 January 2020 23:33
by waaren
EddyG wrote: ↑Thursday 30 January 2020 19:35
I switched from the latest stable to the lastest beta.
Now I got these LUA errors.
Code: Select all
2020-01-30 19:34:40.850 Error: dzVents: Error: (2.5.7) ...i/domoticz/scripts/dzVents/scripts/electricity usage.lua:25: module 'socket.http' not found:
What do I need to install to get 5.3 running?
the file socket.http is not included in domoticz, dzVents or Lua. Probably your dzVents script use this external library. If you share the script I will have a look if it really needs this or that it can use native domoticz / dzVents commands.
Also have a look at
this post where is explained how to install lua-socket ( sudo apt-get install lua-socket ) and how to make sure your script can find it.
Re: Update of Lua to version 5.3 in domoticz V4.11439. with potential effects on Lua and dzVents scripts
Posted: Friday 31 January 2020 8:55
by EddyG
It is this part of the script which uses that lib
Code: Select all
b, c, h = http.request(PVoutputURL .. PVoutputApi .. "&sid=".. PVoutputSystemID .. "&d=" .. os.date("%Y%m%d") .$
Is a http request to upload my P1-meter output to pvoutput.org
I only need b as a return value, which should be "OK 200: Added Status" from pvoutput.org
Re: Update of Lua to version 5.3 in domoticz V4.11439. with potential effects on Lua and dzVents scripts
Posted: Friday 31 January 2020 9:15
by waaren
EddyG wrote: ↑Friday 31 January 2020 8:55
It is this part of the script which uses that lib
Code: Select all
b, c, h = http.request(PVoutputURL .. PVoutputApi .. "&sid=".. PVoutputSystemID .. "&d=" .. os.date("%Y%m%d") .$
Is a http request to upload my P1-meter output to pvoutput.org
I only need b as a return value, which should be "OK 200: Added Status" from pvoutput.org
Please share the complete script. If needed you can obscure user-id / password. I don't need those
Re: Update of Lua to version 5.3 in domoticz V4.11439. with potential effects on Lua and dzVents scripts
Posted: Friday 31 January 2020 9:31
by waaren
EddyG wrote: ↑Friday 31 January 2020 8:55
Is a http request to upload my P1-meter output to pvoutput.org
I only need b as a return value, which should be "OK 200: Added Status" from pvoutput.org
Maybe this example can already put you on the right track.
I use this script to send my energy data to pvoutput every 5 minutes. I stored my user-id / password in a domoticz uservariable.
Code: Select all
local scriptVar = 'PVOutput'
return {
on = {
timer = { 'every 5 minutes'},
httpResponses = { scriptVar },
},
logging = {
level = domoticz.LOG_DEBUG, -- set to error when all OK
marker = "pvOutput"
},
execute = function(dz, item)
local function post2PVOutput(PVSettings, postData)
-- dz.utils.dumpTable(PVSettings, 'PVSettings > ')
-- dz.log('postData: ' .. postData,dz.LOG_FORCE)
dz.openURL({
url = PVSettings.url,
method = 'POST',
headers = {
['X-Pvoutput-Apikey'] = PVSettings.api,
['X-Pvoutput-SystemId'] = PVSettings.id
},
callback = scriptVar,
postData = postData
})
end
local function makepostData()
local P1 = dz.devices('Power')
local Youless = dz.devices('Youless')
local temperature = dz.devices('temperatuur Rotterdam')
local voltage = dz.devices('Synology UPS - UPS AC Input')
local round = dz.utils.round
local postdDataAsString =
'd=' .. os.date("%Y%m%d") ..
'&t=' .. os.date("%H:%M") ..
'&v1=' .. P1.return1 + P1.return2 ..
'&v2=' .. P1.usageDelivered ..
'&v3=' .. P1.usage1 + P1.usage2 ..
'&v4=' .. P1.usage ..
'&v5=' .. round(temperature.temperature,1) ..
'&v6=' .. round(voltage.sValue,1) ..
'&c1=1'
--[[
v1 - energy generation
v2 - power generation W from
v3 - energy consumption
v4 - power consumption
v5 - temperature
v6 - voltage
'&c1= .. c1
'&n= .. n
Donation mode only parms
'&delay=' .. Delay
'&v7=' .. WaterConsumption
'&v8=' .. InverterFrequency
'&v11=' .. InverterTemp
'&v12=' .. GasConsumption
]] --
return postdDataAsString
end
if item.isHTTPResponse then
dz.log("Return from PVOutput ==>> " .. item.data,dz.LOG_FORCE)
else
PVSettings =
{
url = 'HTTPS://pvoutput.org/service/r2/addstatus.jsp',
api = dz.variables('PVoutput_API').value,
id = dz.variables('PVoutput_ID').value,
}
post2PVOutput(PVSettings, makepostData())
end
end
}
Re: Update of Lua to version 5.3 in domoticz V4.11439. with potential effects on Lua and dzVents scripts
Posted: Friday 31 January 2020 10:01
by EddyG
Tnx, I converted my script to openURL, but I will look into your script because it looks more simple then my script.

Re: Update of Lua to version 5.3 in domoticz V4.11439. with potential effects on Lua and dzVents scripts
Posted: Wednesday 25 March 2020 11:54
by hansonexperience
EddyG wrote: ↑Friday 31 January 2020 10:01
Tnx, I converted my script to openURL, but I will look into your script because it looks more simple then my script.
Hi I have the same issue. How did you convert your script to openURL? Could you share your script so I can use it? I have the same script.
Re: Update of Lua to version 5.3 in domoticz V4.11439. with potential effects on Lua and dzVents scripts
Posted: Wednesday 25 March 2020 13:12
by hansonexperience
waaren wrote: ↑Friday 31 January 2020 9:31
EddyG wrote: ↑Friday 31 January 2020 8:55
Is a http request to upload my P1-meter output to pvoutput.org
I only need b as a return value, which should be "OK 200: Added Status" from pvoutput.org
Maybe this example can already put you on the right track.
I use this script to send my energy data to pvoutput every 5 minutes. I stored my user-id / password in a domoticz uservariable.
Code: Select all
local scriptVar = 'PVOutput'
return {
on = {
timer = { 'every 5 minutes'},
httpResponses = { scriptVar },
},
logging = {
level = domoticz.LOG_DEBUG, -- set to error when all OK
marker = "pvOutput"
},
execute = function(dz, item)
local function post2PVOutput(PVSettings, postData)
-- dz.utils.dumpTable(PVSettings, 'PVSettings > ')
-- dz.log('postData: ' .. postData,dz.LOG_FORCE)
dz.openURL({
url = PVSettings.url,
method = 'POST',
headers = {
['X-Pvoutput-Apikey'] = PVSettings.api,
['X-Pvoutput-SystemId'] = PVSettings.id
},
callback = scriptVar,
postData = postData
})
end
local function makepostData()
local P1 = dz.devices('Power')
local Youless = dz.devices('Youless')
local temperature = dz.devices('temperatuur Rotterdam')
local voltage = dz.devices('Synology UPS - UPS AC Input')
local round = dz.utils.round
local postdDataAsString =
'd=' .. os.date("%Y%m%d") ..
'&t=' .. os.date("%H:%M") ..
'&v1=' .. P1.return1 + P1.return2 ..
'&v2=' .. P1.usageDelivered ..
'&v3=' .. P1.usage1 + P1.usage2 ..
'&v4=' .. P1.usage ..
'&v5=' .. round(temperature.temperature,1) ..
'&v6=' .. round(voltage.sValue,1) ..
'&c1=1'
--[[
v1 - energy generation
v2 - power generation W from
v3 - energy consumption
v4 - power consumption
v5 - temperature
v6 - voltage
'&c1= .. c1
'&n= .. n
Donation mode only parms
'&delay=' .. Delay
'&v7=' .. WaterConsumption
'&v8=' .. InverterFrequency
'&v11=' .. InverterTemp
'&v12=' .. GasConsumption
]] --
return postdDataAsString
end
if item.isHTTPResponse then
dz.log("Return from PVOutput ==>> " .. item.data,dz.LOG_FORCE)
else
PVSettings =
{
url = 'HTTPS://pvoutput.org/service/r2/addstatus.jsp',
api = dz.variables('PVoutput_API').value,
id = dz.variables('PVoutput_ID').value,
}
post2PVOutput(PVSettings, makepostData())
end
end
}
Seems like a great script. I am using lua script now and want to use this script in dzvents. Never did that. I have solar power in a device coming in how can I change the script so that this also uploaded?
And were exactly do I have to store the api and password?
Re: Update of Lua to version 5.3 in domoticz V4.11439. with potential effects on Lua and dzVents scripts
Posted: Wednesday 25 March 2020 13:51
by waaren
hansonexperience wrote: ↑Wednesday 25 March 2020 13:12
I am using lua script now and want to use this script in dzVents. Never did that. I have solar power in a device coming in how can I change the script so that this also uploaded?
And were exactly do I have to store the api and password?
When not yet familiar with dzVents please start with reading
Get started Before implementing (~ 5 minutes). Special attention please for "In Domoticz go to Setup > Settings > Other and in the section EventSystem make sure the checkbox 'dzVents enabled' is checked. Also make sure that in the Security section in the settings you allow 127.0.0.1 to not need a password. dzVents uses that port to send certain commands to Domoticz. Finally make sure you have set your current location in Setup > Settings > System > Location, otherwise there is no way to determine nighttime/daytime state."
The solar power can be entered in parm v1 (Where I use P1.return1 + P1.return2)
The password and API are to be entered in the domoticz uservariables
PVoutput_API and
PVoutput_ID (both string types)
Re: Update of Lua to version 5.3 in domoticz V4.11439. with potential effects on Lua and dzVents scripts
Posted: Wednesday 25 March 2020 16:05
by hansonexperience
waaren wrote: ↑Wednesday 25 March 2020 13:51
hansonexperience wrote: ↑Wednesday 25 March 2020 13:12
I am using lua script now and want to use this script in dzVents. Never did that. I have solar power in a device coming in how can I change the script so that this also uploaded?
And were exactly do I have to store the api and password?
When not yet familiar with dzVents please start with reading
Get started Before implementing (~ 5 minutes). Special attention please for "In Domoticz go to Setup > Settings > Other and in the section EventSystem make sure the checkbox 'dzVents enabled' is checked. Also make sure that in the Security section in the settings you allow 127.0.0.1 to not need a password. dzVents uses that port to send certain commands to Domoticz. Finally make sure you have set your current location in Setup > Settings > System > Location, otherwise there is no way to determine nighttime/daytime state."
The solar power can be entered in parm v1 (Where I use P1.return1 + P1.return2)
The password and API are to be entered in the domoticz uservariables
PVoutput_API and
PVoutput_ID (both string types)
Great!
Could you please help me out. I have these devices as seen on the picture now which were fine for uploading to pvoutput.
Zonnepanelen=solarpanels (youless)
Power=P1 (youless)
Elektra=calculation (zonnepanelen-power)
Gas=P1 (youless) Where do I have to enter them in the dzevent script?
I let temperature coming in pvoutput from wunderground (filled by my meteobridge nanosd). No voltage.

- Devices setup in domoticz
- Schermafbeelding 2020-03-25 om 15.52.55.png (224.72 KiB) Viewed 2458 times