After reading this post http://www.domoticz.com/forum/viewtopic.php?f=23&t=6451. I choose to share a script I just write.
I've write this script using info from here http://www.plevenon-meteo.info/techniqu ... ement.html.
It gives you sun position and theoretical sun radiation. This could help you to close or open blinds, know how cloudy is the sky if you have pyranometer, and what ever you may imagine.
I'm actually testing it. Any comments, suggestions, corrections are welcome.
I did not succeed retrieving longitude and latitude in lua. If you have any idea, let me know.
To make it work you need to modify latitude, longitude.
If you use altitude correction you need to modify barometer device and altitude.
Modify the end of the script to fill your needs.
Code: Select all
--Script lua sun v0.01
--Make from info found http://www.plevenon-meteo.info/technique/theorie/enso/ensoleillement.html
commandArray = {}
---------------------------------------------------------------
--Variables
---------------------------------------------------------------
-- Debug Option
debug = true -- true or false
-- Position variables of your location - To edit
longitude = X.XXXX -- degrees
latitude = X.XXXX -- degrees
-- Calculation with altitude (you need a barometer !)
CalculationWithAltitude = true -- true or false
altitude = XXX -- meters
Barometer = 'Baromètre' -- hPa -- Your barometer must report relative pression (value from sensor with altitude correction)
-- Solar Variables
SolarConstantW = 1361 -- W/m²
SolarConstantLux = 200000 -- Lux
---------------------------------------------------------------
--Calculations code
---------------------------------------------------------------
function round(num, idp)
local mult = 10^(idp or 0)
return math.floor(num * mult + 0.5) / mult
end
if ( debug == true ) then
print ("------------SUN_START------------")
end
-- Calculation of day number
DayNumber = os.date("%j")
if ( debug == true ) then
print ("Today is day number "..DayNumber)
end
-- Calculation of solar declination
SolarDeclination = 23.45 * math.sin(math.rad(360 * ( 284 + DayNumber ) / 365 ))
if ( debug == true ) then
print ("Solar declination is "..SolarDeclination.." degrees")
end
--Calculation of decimal UTC time
DecimalTime = os.date("!%H") + os.date("!%M") / 60
if ( debug == true ) then
print ("Decimal UTC time is "..DecimalTime.." hour")
end
-- Solar Time
SolarTime = DecimalTime + (4 * longitude / 60 )
if ( debug == true ) then
print ("Solar time is "..SolarTime.." hour")
end
-- Calculation of hour angle
HourAngle = 15 * ( 12 - SolarTime )
if ( debug == true ) then
print ("Hour angle is "..HourAngle.." degrees")
end
-- Calculation of solar tilt
SolarTilt = math.deg(math.asin(math.sin(math.rad(latitude)) * math.sin(math.rad(SolarDeclination)) + math.cos(math.rad(latitude)) * math.cos(math.rad(SolarDeclination)) * math.cos(math.rad(HourAngle))))
if ( debug == true ) then
print ("Solar tilt is "..SolarTilt.." degrees")
end
-- Calculation of solar flux
SolarFlux = SolarConstantW * (1 +0.034 * math.cos( math.rad( 360 * DayNumber / 365 )))
if ( debug == true ) then
print ("Solar flux is "..SolarFlux.." W/m²")
end
-- Calculation of solar tilt sinus
SinusSolarTilt = math.sin(math.rad(SolarTilt))
-- Calculation of M0
M0 = math.sqrt(1229 + math.pow(614 * SinusSolarTilt,2)) - 614 * SinusSolarTilt
if ( debug == true ) then
print ("M0 equal "..M0)
end
-- Calculation of M
if (CalculationWithAltitude == true) then
sBaroTemp, sBaroPressure, sUnknow1, sUnknow2 = otherdevices_svalues[Barometer]:match("([^;]+);([^;]+);([^;]+);([^;]+)")
P = tonumber(sBaroPressure) -- hPa
P0 = P - round((altitude / 8.3),1) -- hPa
if ( debug == true ) then
print ("Relative pression is "..P.." hPa")
print ("Absolute pression is "..P0.." hPa")
end
M = M0 * P / P0
else
M = M0
end
if ( debug == true ) then
print ("M equal "..M)
end
-- Calculation of direct radiation
DirectRadiation = SolarFlux * math.pow(0.6,M) * SinusSolarTilt
if ( debug == true ) then
print ("Direct radiation is "..DirectRadiation.." W/m²")
end
-- Calculation of diffuse radiation
DiffuseRadiation = SolarFlux * (0.271 - 0.294 * math.pow(0.6,M)) * SinusSolarTilt
if ( debug == true ) then
print ("Diffuse radiation is "..DiffuseRadiation.." W/m²")
end
-- Calculation of total radiation in W/m²
if (SolarTilt > 3) then
if ( debug == true ) then
print ("Solar tilt is over 3 degrees")
end
TotalRadiationW = DirectRadiation + DiffuseRadiation
else
if ( debug == true ) then
print ("Solar tilt is equal or under 3 degrees")
end
TotalRadiationW = 0
end
if ( debug == true ) then
print ("Total radiation is "..round(TotalRadiationW,2).." W/m²")
end
-- Calculation of total radiation in Lux
TotalRadiationLux = SolarConstantLux / SolarConstantW * TotalRadiationW
if ( debug == true ) then
print ("Total radiation is "..round(TotalRadiationLux).." Lux")
end
---------------------------------------------------------------
--Start of your code
--List of variables from calculations :
-- SolarDeclination : Solar declination in degrees
-- SolarTime : Solar time in hour
-- HourAngle : Hour angle in degrees
-- SolarTilt : Solar tilt in degrees
-- SolarFlux : Solar flux in W/m²
-- P : Relative pression in hPa ; Only with CalculationWithAltitude = true
-- P0 : Absolute pression in hPa ; Only with CalculationWithAltitude = true
-- DirectRadiation : Direct radiation in W/m²
-- DiffuseRadiation : Diffuse radiation in W/m²
-- TotalRadiationW : Total radiation in W/m²
-- TotalRadiationLux : Total radiation in Lux
---------------------------------------------------------------
idxRadiationCounter =
if (idxRadiationCounter ~= nil) then
commandArray['UpdateDevice'] = idxRadiationCounter .. "|0|" .. TotalRadiationLux
if ( debug == true ) then
print ("Radiation counter updated")
end
else
if ( debug == true ) then
print ("Radiation counter not set")
end
end
---------------------------------------------------------------
--End of your code
---------------------------------------------------------------
if ( debug == true ) then
print ("-------------SUN_END-------------")
end
return commandArray