Page 1 of 1

Sun position in lua

Posted: Friday 05 June 2015 19:11
by arnaudth
Hi everybody,
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

Re: Sun position in lua

Posted: Friday 05 June 2015 19:57
by simonrg
arnaudth wrote:I did not succeed retrieving longitude and latitude in lua. If you have any idea, let me know.
Nice script.

You get lattitude and longitude from this json call:

Code: Select all

curl 'http://localhost:8080/json.htm?type=command&param=getconfig'

Re: Sun position in lua

Posted: Friday 05 June 2015 20:10
by arnaudth
Thanx, I remember I tried this, but not working in my domoticz V2.2284
I got :
{
status: "ERR"
}

Re: Sun position in lua

Posted: Friday 05 June 2015 20:28
by simonrg
arnaudth wrote:Thanx, I remember I tried this, but not working in my domoticz V2.2284
I got :
{
status: "ERR"
}
No it won't because it wasn't introduced until about 2.25xx, however I remember back in 2.2284 then every device replied with its lattitude and longitude.

This was consolidated into getconfig - see this forum thread - http://www.domoticz.com/forum/viewtopic ... 90&p=43559

Re: Sun position in lua

Posted: Friday 05 June 2015 20:31
by arnaudth
Thanx, however I'll wait for a stable release and then update my script.

Re: Sun position in lua

Posted: Thursday 07 April 2016 22:49
by assenzuid
I get below error

2016-04-07 22:48:00.343 LUA: ------------SUN_START------------
2016-04-07 22:48:00.343 LUA: Today is day number 098
2016-04-07 22:48:00.343 LUA: Solar declination is 6.7649130510503 degrees
2016-04-07 22:48:00.344 LUA: Decimal UTC time is 20.8 hour
2016-04-07 22:48:00.344 LUA: Solar time is 24.332648133333 hour
2016-04-07 22:48:00.344 LUA: Hour angle is -184.989722 degrees
2016-04-07 22:48:00.345 LUA: Solar tilt is -75.802997406671 degrees
2016-04-07 22:48:00.345 LUA: Solar flux is 1355.6352423383 W/m²
2016-04-07 22:48:00.345 LUA: M0 equal 1191.5260975059
2016-04-07 22:48:00.345 Error: EventSystem: in Sun Position: [string "--Script lua sun v0.01 ..."]:94: attempt to index field '?' (a nil value)