first commit
This commit is contained in:
238
lua/old/soleil.lua
Executable file
238
lua/old/soleil.lua
Executable file
@@ -0,0 +1,238 @@
|
||||
--Variables à éditer--------------
|
||||
local Ville = "pws:ILAGACIL2" --Ville de référence
|
||||
local idxLux = '320' --Capteur virtuel de Luminosité
|
||||
local idxOcta = '5' -- idx de la variable Utilisateur
|
||||
local wuAPIkey = "48a08328a93a18a1"
|
||||
local DEBUG = 'OUI'
|
||||
|
||||
--import des fontions pour lire le JSON
|
||||
json = (loadfile "/opt/domoticz/scripts/lua/JSON.lua")()
|
||||
|
||||
-- Fonction déterminant si année bissextile
|
||||
function AnneeBissextile(annee)
|
||||
return annee%4==0 and (annee%100~=0 or annee%400==0)
|
||||
end
|
||||
|
||||
---------------------------------
|
||||
-- Fonction spliter
|
||||
function split(s, delimiter)
|
||||
result = {};
|
||||
for match in (s..delimiter):gmatch("(.-)"..delimiter) do
|
||||
table.insert(result, match);
|
||||
end
|
||||
return result;
|
||||
end
|
||||
|
||||
|
||||
---------------------------------
|
||||
-- Fonction Arrondir
|
||||
function arrondir(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
|
||||
|
||||
---------------------------------
|
||||
-- Procedure principale
|
||||
---------------------------------
|
||||
|
||||
---------------------------------
|
||||
-- Meteo API Wunderground
|
||||
local config=assert(io.popen('curl http://api.wunderground.com/api/'..wuAPIkey..'/conditions/q/FR/'..Ville..'.json'))
|
||||
local location = config:read('*all')
|
||||
config:close()
|
||||
local jsonLocation = json:decode(location)
|
||||
|
||||
local Latitude = jsonLocation.current_observation.display_location.latitude
|
||||
local Longitude = jsonLocation.current_observation.display_location.longitude
|
||||
local Altitude = jsonLocation.current_observation.display_location.elevation
|
||||
PressionRelative = jsonLocation.current_observation.pressure_mb
|
||||
|
||||
----------------------------------
|
||||
local An = os.date("%Y")
|
||||
local NiemeJourDeLAnnee = os.date("%j")
|
||||
---------------------------------
|
||||
DateHeure = os.date("%Y-%m-%d %H:%M:%S", os.time())
|
||||
-- Début debug
|
||||
if( DEBUG == 'OUI') then
|
||||
print("=====================================")
|
||||
print(os.date("%Y-%m-%d %H:%M:%S", os.time()))
|
||||
print(Ville .. ", " .. Latitude .. ", " .. Longitude)
|
||||
print("Altitude = " .. tostring(Altitude) .. " m")
|
||||
print("NiemeJourDeLAnnee = " .. NiemeJourDeLAnnee)
|
||||
end
|
||||
---------------------------------
|
||||
--calcul de l'année bissextile
|
||||
if AnneeBissextile(An) == true then
|
||||
if( DEBUG == 'OUI') then
|
||||
print( An .. " est bissextile.")
|
||||
end
|
||||
JourDansLAnnee = 366
|
||||
else
|
||||
if( DEBUG == 'OUI') then
|
||||
print( An .. " n'est pas bissextile.")
|
||||
end
|
||||
JourDansLAnnee = 365
|
||||
end
|
||||
---------------------------------
|
||||
-- Vitesse angulaire = Combien de degrés par jour
|
||||
VitesseAngulaire = 360/365.25 ----JourDansLAnnee -- ou approximativement 365.25
|
||||
if( DEBUG == 'OUI') then
|
||||
print("Vitesse angulaire = " .. VitesseAngulaire .. " par jour")
|
||||
end
|
||||
---------------------------------
|
||||
-- Formule Declinaison = ArcSin(0,3978 x Sin(Va x (j - (81 - 2 x Sin(Va� x (j - 2))))))
|
||||
local Declinaison = math.deg(math.asin(0.3978 * math.sin(math.rad(VitesseAngulaire) *(NiemeJourDeLAnnee - (81 - 2 * math.sin((math.rad(VitesseAngulaire) * (NiemeJourDeLAnnee - 2))))))))
|
||||
if( DEBUG == 'OUI') then
|
||||
print("La déclinaison = " .. Declinaison .. "°")
|
||||
end
|
||||
---------------------------------
|
||||
-- Temps universel décimal (UTC)
|
||||
TempsDecimal = (os.date("!%H") + os.date("!%M") / 60)
|
||||
if( DEBUG == 'OUI') then
|
||||
print("Temps universel decimal (UTC)".. TempsDecimal .." H.dd")
|
||||
end
|
||||
---------------------------------
|
||||
-- Temps solaire
|
||||
HeureSolaire = TempsDecimal + (4 * Longitude / 60 )
|
||||
if( DEBUG == 'OUI') then
|
||||
print("Temps solaire ".. HeureSolaire .." H.dd")
|
||||
end
|
||||
---------------------------------
|
||||
-- Angle horaire du soleil
|
||||
AngleHoraire = 15 * ( 12 - HeureSolaire )
|
||||
if( DEBUG == 'OUI') then
|
||||
print("Angle Horaire = ".. AngleHoraire .. "°")
|
||||
end
|
||||
---------------------------------
|
||||
-- La hauteur du soleil (Elévation ou altitude)
|
||||
HauteurSoleil = 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(AngleHoraire))))
|
||||
if( DEBUG == 'OUI') then
|
||||
print("Hauteur du soleil = " .. HauteurSoleil .. "°")
|
||||
end
|
||||
local Azimut = math.acos((math.sin(math.rad(Declinaison)) - math.sin(math.rad(Latitude)) * math.sin(math.rad(HauteurSoleil))) / (math.cos(math.rad(Latitude)) * math.cos(math.rad(HauteurSoleil) ))) * 180 / math.pi
|
||||
local SinAzimut = (math.cos(math.rad(Declinaison)) * math.sin(math.rad(AngleHoraire))) / math.cos(math.rad(HauteurSoleil))
|
||||
if(SinAzimut<0) then
|
||||
Azimut=360-Azimut
|
||||
end
|
||||
if( DEBUG == 'OUI') then
|
||||
print("Azimut du soleil = " .. Azimut .. "°")
|
||||
end
|
||||
---------------------------------
|
||||
-- La durée d'insolation journalière - non stockée en VG
|
||||
DureeInsolation = math.deg(2/15 * math.acos(- math.tan(math.rad(Latitude)) * math.tan(math.rad(Declinaison))))
|
||||
DureeInsolation = arrondir(DureeInsolation,2)
|
||||
if( DEBUG == 'OUI') then
|
||||
print("La durée d'insolation journalière = " .. DureeInsolation .." H.dd")
|
||||
end
|
||||
---------------------------------
|
||||
-- Constantes Solaire
|
||||
ConstanteRatiationSolaire = 1361 -- W/m²
|
||||
ConstanteRadiationLux = 200000 -- Lux
|
||||
---------------------------------
|
||||
-- Rayonnement solaire (en W/m²) présent à l'entrée de l'atmosphère.
|
||||
RadiationAtm = ConstanteRatiationSolaire * (1 +0.034 * math.cos( math.rad( 360 * NiemeJourDeLAnnee / JourDansLAnnee )))
|
||||
if( DEBUG == 'OUI') then
|
||||
print("Radiation max en atmosphère = " .. arrondir(RadiationAtm,2) .. " W/m²")
|
||||
end
|
||||
---------------------------------
|
||||
-- Coefficient d'attenuation M
|
||||
PressionAbsolue = PressionRelative - arrondir((Altitude/ 8.3),1) -- hPa
|
||||
SinusHauteurSoleil = math.sin(math.rad(HauteurSoleil))
|
||||
M0 = math.sqrt(1229 + math.pow(614 * SinusHauteurSoleil,2)) - 614 * SinusHauteurSoleil
|
||||
M = M0 * PressionRelative/PressionAbsolue
|
||||
if( DEBUG == 'OUI') then
|
||||
print("Pression relative locale = " .. PressionRelative .. " hPa")
|
||||
print("Pression absolue atmosphère = " .. PressionAbsolue .. " hPa")
|
||||
print("Coefficient d'attenuation = " .. M )
|
||||
end
|
||||
---------------------------------
|
||||
-- Récupérer message SYNOP sur le site Ogimet
|
||||
heureUTCmoins1 = os.date("!%H")-1
|
||||
if string.len(heureUTCmoins1) == 1 then
|
||||
heureUTCmoins1 = "0" .. heureUTCmoins1
|
||||
end
|
||||
UTC = os.date("%Y%m%d").. heureUTCmoins1.."00" -- os.date("!%M")
|
||||
local WMOID = jsonLocation.current_observation.display_location.wmo
|
||||
print("WMOID="..WMOID)
|
||||
local ogimet=assert(io.popen('curl "http://www.ogimet.com/cgi-bin/getsynop?block='..WMOID..'&begin='..UTC..'"'))
|
||||
local synop = ogimet:read('*all')
|
||||
ogimet:close()
|
||||
rslt = split(synop,",")
|
||||
CodeStation = rslt[1]
|
||||
rslt = split(synop, " "..CodeStation.. " ")
|
||||
Trame = string.gsub(rslt[2], "=", "")
|
||||
Trame = CodeStation .." ".. Trame
|
||||
rslt = split(Trame, " ")
|
||||
if( DEBUG == 'OUI') then
|
||||
print("Horodatage UTC = " .. UTC)
|
||||
print("Station SYNOP = " .. WMOID)
|
||||
end
|
||||
---------------------------------
|
||||
-- Récupérer le premier caractere du 3eme mot = Nebulosité en Octa
|
||||
Octa = string.sub(rslt[3], 1, 1)
|
||||
--print(rslt[3])
|
||||
-- 0 Pas de couverture nuageuse
|
||||
-- 1-8 Huitième
|
||||
-- 9 Brouillard
|
||||
-- / Couverture indiscernable
|
||||
-- cas particulier si valeur indéterminé un slash est renvoyé.
|
||||
if Octa == "/" then
|
||||
-- si la couverture est indiscernable, on reprend l'ancienne valeur
|
||||
-- cela evite les violentes cassures dans la courbe
|
||||
--Octa = uservariables['octa']
|
||||
Octa = arg[1]
|
||||
elseif Octa == "9" then
|
||||
Octa = 8
|
||||
end
|
||||
if( DEBUG == 'OUI') then
|
||||
print( Octa .. " Octa")
|
||||
end
|
||||
-- stockage de la variable octa
|
||||
--commandArray['Variable:octa']=tostring(Octa)
|
||||
os.execute('/usr/bin/curl "http://127.0.0.1:8080/json.htm?type=command¶m=updateuservariable&idx='..idxOcta..'&vname=octa&vtype=0&vvalue='..tostring(Octa)..'"')
|
||||
|
||||
|
||||
---------------------------------
|
||||
-- Facteur d'atténuation des couches nuageuses Kc
|
||||
-- Kc=1-(0.75*((OCTA)**(3.4))
|
||||
Kc=1-0.75*(math.pow(Octa/8,3.4))
|
||||
if( DEBUG == 'OUI') then
|
||||
print("Kc = " .. Kc)
|
||||
end
|
||||
---------------------------------
|
||||
-- Au lever/coucher du soleil, on atteind les limites de précisions de ces calculs.
|
||||
-- J'interrompts donc le calcul de radiation dès 1°.
|
||||
if HauteurSoleil > 1 then
|
||||
-- Radiation directe
|
||||
RadiationDirecte = RadiationAtm * math.pow(0.6,M) * SinusHauteurSoleil
|
||||
-- Radiation Diffuse
|
||||
RadiationDiffuse = RadiationAtm * (0.271 - 0.294 * math.pow(0.6,M)) * SinusHauteurSoleil
|
||||
-- Radiation totale
|
||||
RadiationTotale = RadiationDiffuse + RadiationDirecte
|
||||
-- Radiation en Lux : -- 1 Lux = 0,0079 W/m²
|
||||
Lux = RadiationTotale / 0.0079
|
||||
--Lux = ConstanteRadiationLux / ConstanteRatiationSolaire * RadiationTotale
|
||||
-- Le rayonnement solaire avec ciel nuageux
|
||||
RTOTC = RadiationTotale * Kc
|
||||
-- Radiation en Lux pondéré
|
||||
-- LuxPondere = ConstanteRadiationLux / ConstanteRatiationSolaire * RTOTC
|
||||
LuxPondere = RTOTC / 0.0079
|
||||
print("Radiation totale en lux pondéré = ".. arrondir(LuxPondere,2).." Lux")
|
||||
if( DEBUG == 'OUI') then
|
||||
print("RadiationDirecte = ".. arrondir(RadiationDirecte,2) .." W/m²")
|
||||
print("Radiation Diffuse = ".. arrondir(RadiationDiffuse,2) .." W/m²")
|
||||
print("Radiation totale = " .. arrondir(RadiationTotale,2) .." W/m²")
|
||||
print("Radiation totale en lux = ".. arrondir(Lux,2).." Lux")
|
||||
print("Le rayonnement solaire avec pondération = " .. arrondir(RTOTC,2))
|
||||
end
|
||||
else
|
||||
--le soleil est trop bas
|
||||
RTOTC = 0
|
||||
LuxPondere = 0
|
||||
end
|
||||
--mise à jour du dispositif
|
||||
os.execute('/usr/bin/curl "http://127.0.0.1:8080/json.htm?type=command¶m=udevice&idx='..idxLux..'&svalue="'..tostring(LuxPondere)..' -s -o /dev/null')
|
||||
Reference in New Issue
Block a user