Page 12 of 13

Re: Real-time solar data : azimuth, Altitude, Lux sensor...

Posted: Friday 13 April 2018 9:51
by angelus1753
If anyone's interested, I've updated the script to use the userVariable (Octa) as a backup for when ogimet is not updating it's api. I reverted back the JSON calls and removed it's dependancy.
The other big thing is that I took out all links to Weather Underground and am reading the Weather Underground device.

Code: Select all

    --[[      Virtual Lux sensor and other real-time solar data

    ~/domoticz/var/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 - No update of the Lux data when <=0 to get the sunset and sunrise with lastUpdate
    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 - Marco Pietersen - Reverted use of API, introduced WU dependency
    ]]--

    -- Variables to customize ------------------------------------------------
       local latitude = 52.134028          -- your home
       local longitude = 5.420183          -- your home
       local altitude = 27                 -- Your home altitude (get from Weather Underground or other source)
       local wu_deviceName='Outside Temperature' -- Your Weather Underground device name that shows the Barometer value
       local idxLux ='16'                   -- Your virtual Lux Device ID
       local idxSolarAzimuth ='7'          -- Your virtual Azimuth Device ID
       local idxSolarAltitude ='8'         -- Your virtual Solar Altitude Device ID
       local idxUserVarOcta='1'            -- Your user variable ID , named octa
       local WMOID = '06260'               -- Your nearest SYNOP Station for ogimet. Very important !
       local DEBUG = 0			           -- 0 , 1 for domoticz log , 2 for file log

    -- 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. 

       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
        sWeatherTemp, sWeatherHumidity, sHumFeelsLike, sWeatherPressure = otherdevices_svalues[wu_deviceName]:match("([^;]+);([^;]+);([^;]+);([^;]+);([^;]+)")
        sWeatherTemp = tonumber(sWeatherTemp)
        sWeatherHumidity = tonumber(sWeatherHumidity)
        relativePressure = tonumber(sWeatherPressure)
        if (DEBUG == 1) then print('WU Script Parsed Temp=' .. sWeatherTemp .. ' Humidity=' .. sWeatherHumidity .. ' Pressure=' .. relativePressure) end

       ----------------------------------
       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("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")
       if (DEBUG == 1) then
          --local WMOID = jsonLocation.current_observation.display_location.wmo
       end
       
       cmd='curl "http://www.ogimet.com/cgi-bin/getsynop?block='..WMOID..'&begin='..UTC..'"'
       if(DEBUG == 1) then print(cmd) end
       local ogimet=assert(io.popen(cmd))
       local synop = ogimet:read('*all')
       ogimet:close()
          
       if synop ~= nil
       then   
       	  rslt = split(synop,",")
          CodeStation = rslt[1]
          rslt = split(synop, " "..CodeStation.. " ")
          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
          
    		if(DEBUG == 1) then 
    			print('ogimet:'..synop ) 
    			print('ogimet Octa: '..Octa )     			    			
    		end   		
    	  
          if Octa == "/" then Octa = uservariables['octa'] end -- not defined ? take the previous value
          if Octa == "9" then Octa = 8 end
       else
          Octa = uservariables['octa']
       	  print('SolarSensor did not receive ogimet data. Reverting to last known value:'..Octa)
       end

       --os.execute('curl "http://127.0.0.1:8081/json.htm?type=command&param=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
	end
	commandArray[#commandArray + 1] = {['UpdateDevice'] = idxSolarAzimuth..'|0|'..tostring(round(azimuth,0))} 
	commandArray[#commandArray + 1] = {['UpdateDevice'] = idxSolarAltitude..'|0|'..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: Real-time solar data : azimuth, Altitude, Lux sensor...

Posted: Saturday 05 May 2018 19:11
by HiGhLaNdeR
Hi, I'm getting this error:

2018-05-05 18:05:00.134 LUA: WU Script Parsed Temp=23 Humidity=30 Pressure=1014
2018-05-05 18:05:00.135 LUA: <b style="color:Blue"============== SUN LOG ==================</b>
2018-05-05 18:05:00.135 LUA: 2018-05-05 18:05:00
2018-05-05 18:05:00.135 LUA: latitude:xxxxxxxxxxxxxxx, longitude:xxxxxxxxxxxxxx
2018-05-05 18:05:00.135 LUA: Home altitude = xxxxxxx m
2018-05-05 18:05:00.135 LUA: number Of Day = 125
2018-05-05 18:05:00.135 LUA: 2018 is not a leap year
2018-05-05 18:05:00.135 LUA: Angular Speed = 0.98562628336756 per day
2018-05-05 18:05:00.135 LUA: Declinaison = 16.352601850669�
2018-05-05 18:05:00.135 LUA: Universel Coordinated Time (UTC)17.083333333333 H.dd
2018-05-05 18:05:00.135 LUA: Solar Hour 16.538450713493 H.dd
2018-05-05 18:05:00.135 LUA: Altitude of the sun = 27.058752913389�
2018-05-05 18:05:00.135 LUA: Angular hourly = -68.076760702399�
2018-05-05 18:05:00.135 LUA: Azimuth of the sun = 268.31940724932�
2018-05-05 18:05:00.135 LUA: Duration of the sunstroke of the day = 14 H.dd
2018-05-05 18:05:00.136 LUA: Radiation max in atmosphere = 1335.6 W/m�
2018-05-05 18:05:00.136 LUA: Local relative pressure = 1014 hPa
2018-05-05 18:05:00.136 LUA: Absolute pressure in atmosphere = 882.4 hPa
2018-05-05 18:05:00.136 LUA: Coefficient of mitigation M = 2.5182908804761 M0:2.1914594407615
2018-05-05 18:05:00.136 LUA: curl "http://www.ogimet.com/cgi-bin/getsynop? ... 1805051600"
2018-05-05 18:05:00.416 LUA: ogimet:08545,2018,05,05,16,00,AAXX 05161 08545 26/// /3208 10198 20077 30073 40154 58005 333 60005==<br>
2018-05-05 18:05:00.416 LUA: ogimet Octa: /
2018-05-05 18:05:00.416 LUA: Station SYNOP = 08545
2018-05-05 18:05:00.416 LUA: 0 Octa
2018-05-05 18:05:00.416 LUA: Kc = 1
2018-05-05 18:05:00.416 LUA: Direct Radiation = 167.85 W/m�
2018-05-05 18:05:00.417 LUA: Scattered Radiation = 115.3 W/m�
2018-05-05 18:05:00.417 LUA: Total radiation = 283.15 W/m�
2018-05-05 18:05:00.417 LUA: Total Radiation in lux = 35842.12 Lux
2018-05-05 18:05:00.417 LUA: and at last, Total weighted lux = 35842.12 Lux
2018-05-05 18:05:00.417 Error: EventSystem: in /home/pi/domoticz/scripts/lua/script_time_SolarSensor.lua: /home/pi/domoticz/scripts/lua/script_time_SolarSensor.lua:196: attempt to perform arithmetic on a nil value
2018-05-05 18:05:00.618 EventSystem: Script event triggered: /home/pi/domoticz/scripts/lua/script_time_SolarSensor.lua


Any clue what can be wrong?
Thanks.

Re: Real-time solar data : azimuth, Altitude, Lux sensor...

Posted: Saturday 05 May 2018 19:42
by HiGhLaNdeR
changed the line 196 to:
if tonumber(otherdevices_svalues['Lux Outside'])+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$

My lux name from the script is "Lux Outside".

Script started working.

Re: Real-time solar data : azimuth, Altitude, Lux sensor...

Posted: Monday 07 May 2018 21:27
by phoenixblue
Is there also an option to get any forcast for the solar radiation?

Re: Real-time solar data : azimuth, Altitude, Lux sensor...

Posted: Friday 01 June 2018 22:24
by Derik
Dear all..
Since may 30 is do have no working script any more..
I get a error:

Code: Select all

2018-06-01 22:20:05.882 Error: EventSystem: in Lua: Solarsensor: [string " --[[ Virtual Lux sensor and other real-..."]:172: bad argument #1 to 'gsub' (string expected, got nil)
I think i changed not thing...
line 172:

Code: Select all

          Trame = string.gsub(rslt[2], "=", "") 
So please i hope there is someone ...
Thanks

Re: Real-time solar data : azimuth, Altitude, Lux sensor...

Posted: Tuesday 12 June 2018 0:57
by HiGhLaNdeR
My synop station disapeared... Had to check website (http://www.ogimet.com/gsynop_nav.phtml) for a new station!
I'm sure your problem is the same.
Go check your station.

Regards.

Re: Real-time solar data : azimuth, Altitude, Lux sensor...

Posted: Tuesday 12 June 2018 23:53
by markk
latis wrote: Tuesday 16 February 2016 8:55 I fixed it, it was my position which was erroneous. After changing that, everything works. Now lets hope domoticz can get an addition of dummy solar radiation. :)
Hi. I have this same error. What position did you change to correct it?

Re: Real-time solar data : azimuth, Altitude, Lux sensor...

Posted: Wednesday 13 June 2018 14:58
by markk
markk wrote: Tuesday 12 June 2018 23:53
latis wrote: Tuesday 16 February 2016 8:55 I fixed it, it was my position which was erroneous. After changing that, everything works. Now lets hope domoticz can get an addition of dummy solar radiation. :)
Hi. I have this same error. What position did you change to correct it?
I managed to solve my own problem. I had inserted my WU station ID into the "local city" section instead of just the local city :oops:

Re: Real-time solar data : azimuth, Altitude, Lux sensor...

Posted: Sunday 29 July 2018 22:52
by Nelissuh
Hello,

I would like to use this script do switch my pump to heat my swimming pool by solar heating. Now I am not able to get an WU API Key :oops: Apparently they stopped to provide them for free.

Is there a way to bypass the API key? Is there another source to get the data needed for the script?

Thanks is advance!

Re: Real-time solar data : azimuth, Altitude, Lux sensor...

Posted: Thursday 02 August 2018 22:35
by pascal
hello,
Lua script is working properly, DzEvent script not really, virtual sensors are not updated, and there is not any error reported. Strange
Any idea? :roll:
Thanks

Re: Real-time solar data : azimuth, Altitude, Lux sensor...

Posted: Sunday 02 September 2018 23:38
by ouiouiblog
Hello,

I have a problem using the script. It runs well, but gave me completely false results for the last 2 days .

I use it to simulate a real PV on my roof that is linked to a battery. If I look at solar sensor, the battery should be 50% charged. If I look at the battery, it is fully charged.

For the last 2 days, solar sensor shows cloudy days with 20K lux max. In real life it was fully sunny.

Image

I checked latitude and longitude, I checked WMOID, all is fine. I don't understand where the problem is. On other days, I had normal curves (with high peaks that get to 50-60K lux), but for the last 2 days, I just have "flat" curves that peaks to 20K.

Edit : it looks like synops datas are not available for these days. In fact SYNOPS datas are not very reliable for nebulosity. I found something better here using darksky viewtopic.php?f=61&t=22090

Re: Real-time solar data : azimuth, Altitude, Lux sensor...

Posted: Wednesday 24 October 2018 11:08
by damosta
I have a problem with the script. I would apreciate if somebody could help me, because I am a newbie in LUA scripts.
I added some lines for solar radiation to the script. It works for several hours, but then I get this error message:
Error: EventSystem: in solar: [string " --[[ Virtual Lux sensor and other rea..."]:140: bad argument #1 to 'gsub' (string expected, got nil)
My scripts is as follow:

Code: Select all

  --[[      Virtual Lux sensor and other real-time solar data

    ~/domoticz/var/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 - No update of the Lux data when <=0 to get the sunset and sunrise with lastUpdate
    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 - Marco Pietersen - Reverted use of API, introduced WU dependency
    ]]--

    -- Variables to customize ------------------------------------------------
       local latitude = 40.428501               -- your home
       local longitude = -3.665874              -- your home
       local altitude = 680                     -- Your home altitude (get from Weather Underground or other source)
       local wu_deviceName='THB'                -- Your Weather Underground device name that shows the Barometer value
       local idxLux ='38'                       -- Your virtual Lux Device ID
       local idxSolarAzimuth ='39'              -- Your virtual Azimuth Device ID
       local idxSolarAltitude ='40'             -- Your virtual Solar Altitude Device ID
       local idxSolarScatteredRadiation ='45'   -- Sensor de radiación difusa
       local idxSolarDirectRadiation ='46'      -- Sensor de radiación directa
       local idxSolarTotalRadiation='47'        -- Sensor de radiación total
       local idxUserVarOcta='/'                 -- Your user variable ID , named octa
       local WMOID = '08224'                    -- Your nearest SYNOP Station for ogimet. Very important !
       local DEBUG = 1			                -- 0 , 1 for domoticz log , 2 for file log

    -- 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. 

       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
        sWeatherTemp, sWeatherHumidity, sHumFeelsLike, sWeatherPressure = otherdevices_svalues[wu_deviceName]:match("([^;]+);([^;]+);([^;]+);([^;]+);([^;]+)")
        sWeatherTemp = tonumber(sWeatherTemp)
        sWeatherHumidity = tonumber(sWeatherHumidity)
        relativePressure = tonumber(sWeatherPressure)
        if (DEBUG == 1) then print('WU Script Parsed Temp=' .. sWeatherTemp .. ' Humidity=' .. sWeatherHumidity .. ' Pressure=' .. relativePressure) end

       ----------------------------------
       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("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")
       if (DEBUG == 1) then
          --local WMOID = jsonLocation.current_observation.display_location.wmo
       end
       
       cmd='curl "http://www.ogimet.com/cgi-bin/getsynop?block='..WMOID..'&begin='..UTC..'"'
       if(DEBUG == 1) then print(cmd) end
       local ogimet=assert(io.popen(cmd))
       local synop = ogimet:read('*all')
       ogimet:close()
          
       if synop ~= nil
       then   
       	  rslt = split(synop,",")
          CodeStation = rslt[1]
          rslt = split(synop, " "..CodeStation.. " ")
          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
          
    		if(DEBUG == 1) then 
    			print('ogimet:'..synop ) 
    			print('ogimet Octa: '..Octa )     			    			
    		end   		
    	  
          if Octa == "/" then Octa = uservariables['octa'] end -- not defined ? take the previous value
          if Octa == "9" then Octa = 8 end
       else
          Octa = uservariables['octa']
       	  print('SolarSensor did not receive ogimet data. Reverting to last known value:'..Octa)
       end

       --os.execute('curl "http://127.0.0.1:8081/json.htm?type=command&param=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
	end
	commandArray[#commandArray + 1] = {['UpdateDevice'] = idxSolarAzimuth..'|0|'..tostring(round(azimuth,2))} 
	commandArray[#commandArray + 1] = {['UpdateDevice'] = idxSolarAltitude..'|0|'..tostring(round(sunAltitude,2))}
	commandArray[#commandArray + 1] = {['UpdateDevice'] = idxSolarDirectRadiation..'|0|'..tostring(round(directRadiation,2))}
	commandArray[#commandArray + 1] = {['UpdateDevice'] = idxSolarScatteredRadiation..'|0|'..tostring(round(scatteredRadiation,2))}
	commandArray[#commandArray + 1] = {['UpdateDevice'] = idxSolarTotalRadiation..'|0|'..tostring(round(totalRadiation,2))}

    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 

And this is the error log:

Code: Select all

 2018-10-24 10:30:15.178 Status: LUA: Error : Did you create the Uservariable octa ?
2018-10-24 10:30:15.179 Status: LUA: WU Script Parsed Temp=11.9 Humidity=72 Pressure=1026
2018-10-24 10:30:15.179 Status: LUA: <b style="color:Blue"============== SUN LOG ==================</b>
2018-10-24 10:30:15.179 Status: LUA: 2018-10-24 10:30:15
2018-10-24 10:30:15.179 Status: LUA: latitude:40.428501, longitude:-3.665874
2018-10-24 10:30:15.180 Status: LUA: Home altitude = 680 m
2018-10-24 10:30:15.180 Status: LUA: number Of Day = 297
2018-10-24 10:30:15.180 Status: LUA: 2018 is not a leap year
2018-10-24 10:30:15.180 Status: LUA: Angular Speed = 0.98562628336756 per day
2018-10-24 10:30:15.180 Status: LUA: Declinaison = -11.840713991364°
2018-10-24 10:30:15.180 Status: LUA: Universel Coordinated Time (UTC)8.5 H.dd
2018-10-24 10:30:15.180 Status: LUA: Solar Hour 8.2556084 H.dd
2018-10-24 10:30:15.180 Status: LUA: Altitude of the sun = 16.364842469331°
2018-10-24 10:30:15.180 Status: LUA: Angular hourly = 56.165874°
2018-10-24 10:30:15.180 Status: LUA: Azimuth of the sun = 122.08025037701°
2018-10-24 10:30:15.180 Status: LUA: Duration of the sunstroke of the day = 10.63 H.dd
2018-10-24 10:30:15.180 Status: LUA: Radiation max in atmosphere = 1379.03 W/m²
2018-10-24 10:30:15.180 Status: LUA: Local relative pressure = 1026 hPa
2018-10-24 10:30:15.181 Status: LUA: Absolute pressure in atmosphere = 944.1 hPa
2018-10-24 10:30:15.181 Status: LUA: Coefficient of mitigation M = 3.8214061417113 M0:3.5163640725045
2018-10-24 10:30:15.181 Status: LUA: curl "http://www.ogimet.com/cgi-bin/getsynop?block=08224&begin=201810240700"
2018-10-24 10:30:15.360 Error: EventSystem: in solar: [string " --[[ Virtual Lux sensor and other rea..."]:140: bad argument #1 to 'gsub' (string expected, got nil)
2018-10-24 10:30:33.158 Status: Incoming connection from: 192.168.0.10
2018-10-24 10:30:33.170 Status: LUA: Error : Did you create the Uservariable octa ?
2018-10-24 10:30:33.171 Status: LUA: WU Script Parsed Temp=11.9 Humidity=72 Pressure=1026
2018-10-24 10:30:33.171 Status: LUA: <b style="color:Blue"============== SUN LOG ==================</b>
2018-10-24 10:30:33.171 Status: LUA: 2018-10-24 10:30:33
2018-10-24 10:30:33.171 Status: LUA: latitude:40.428501, longitude:-3.665874
2018-10-24 10:30:33.171 Status: LUA: Home altitude = 680 m
2018-10-24 10:30:33.171 Status: LUA: number Of Day = 297
2018-10-24 10:30:33.171 Status: LUA: 2018 is not a leap year
2018-10-24 10:30:33.171 Status: LUA: Angular Speed = 0.98562628336756 per day
2018-10-24 10:30:33.171 Status: LUA: Declinaison = -11.840713991364°
2018-10-24 10:30:33.171 Status: LUA: Universel Coordinated Time (UTC)8.5 H.dd
2018-10-24 10:30:33.171 Status: LUA: Solar Hour 8.2556084 H.dd
2018-10-24 10:30:33.171 Status: LUA: Altitude of the sun = 16.364842469331°
2018-10-24 10:30:33.171 Status: LUA: Angular hourly = 56.165874°
2018-10-24 10:30:33.171 Status: LUA: Azimuth of the sun = 122.08025037701°
2018-10-24 10:30:33.171 Status: LUA: Duration of the sunstroke of the day = 10.63 H.dd
2018-10-24 10:30:33.172 Status: LUA: Radiation max in atmosphere = 1379.03 W/m²
2018-10-24 10:30:33.172 Status: LUA: Local relative pressure = 1026 hPa
2018-10-24 10:30:33.172 Status: LUA: Absolute pressure in atmosphere = 944.1 hPa
2018-10-24 10:30:33.172 Status: LUA: Coefficient of mitigation M = 3.8214061417113 M0:3.5163640725045
2018-10-24 10:30:33.172 Status: LUA: curl "http://www.ogimet.com/cgi-bin/getsynop?block=08224&begin=201810240700"
2018-10-24 10:30:33.340 Status: LUA: Error : Did you create the Uservariable octa ?
2018-10-24 10:30:33.340 Status: LUA: WU Script Parsed Temp=11.9 Humidity=72 Pressure=1026
2018-10-24 10:30:33.341 Status: LUA: <b style="color:Blue"============== SUN LOG ==================</b>
2018-10-24 10:30:33.341 Status: LUA: 2018-10-24 10:30:33
2018-10-24 10:30:33.341 Status: LUA: latitude:40.428501, longitude:-3.665874
2018-10-24 10:30:33.341 Status: LUA: Home altitude = 680 m
2018-10-24 10:30:33.341 Status: LUA: number Of Day = 297
2018-10-24 10:30:33.341 Status: LUA: 2018 is not a leap year
2018-10-24 10:30:33.341 Status: LUA: Angular Speed = 0.98562628336756 per day
2018-10-24 10:30:33.341 Status: LUA: Declinaison = -11.840713991364°
2018-10-24 10:30:33.341 Status: LUA: Universel Coordinated Time (UTC)8.5 H.dd
2018-10-24 10:30:33.341 Status: LUA: Solar Hour 8.2556084 H.dd
2018-10-24 10:30:33.341 Status: LUA: Altitude of the sun = 16.364842469331°
2018-10-24 10:30:33.341 Status: LUA: Angular hourly = 56.165874°
2018-10-24 10:30:33.341 Status: LUA: Azimuth of the sun = 122.08025037701°
2018-10-24 10:30:33.341 Status: LUA: Duration of the sunstroke of the day = 10.63 H.dd
2018-10-24 10:30:33.341 Status: LUA: Radiation max in atmosphere = 1379.03 W/m²
2018-10-24 10:30:33.341 Status: LUA: Local relative pressure = 1026 hPa
2018-10-24 10:30:33.341 Status: LUA: Absolute pressure in atmosphere = 944.1 hPa
2018-10-24 10:30:33.342 Status: LUA: Coefficient of mitigation M = 3.8214061417113 M0:3.5163640725045
2018-10-24 10:30:33.342 Status: LUA: curl "http://www.ogimet.com/cgi-bin/getsynop?block=08224&begin=201810240700"
2018-10-24 10:30:33.329 Error: EventSystem: in solar: [string " --[[ Virtual Lux sensor and other rea..."]:140: bad argument #1 to 'gsub' (string expected, got nil)
2018-10-24 10:30:45.164 Status: LUA: Error : Did you create the Uservariable octa ?
2018-10-24 10:30:45.165 Status: LUA: WU Script Parsed Temp=11.9 Humidity=72 Pressure=1026
2018-10-24 10:30:45.165 Status: LUA: <b style="color:Blue"============== SUN LOG ==================</b>
2018-10-24 10:30:45.165 Status: LUA: 2018-10-24 10:30:45
2018-10-24 10:30:45.165 Status: LUA: latitude:40.428501, longitude:-3.665874
2018-10-24 10:30:45.165 Status: LUA: Home altitude = 680 m
2018-10-24 10:30:45.165 Status: LUA: number Of Day = 297
2018-10-24 10:30:45.165 Status: LUA: 2018 is not a leap year
2018-10-24 10:30:45.165 Status: LUA: Angular Speed = 0.98562628336756 per day
2018-10-24 10:30:45.165 Status: LUA: Declinaison = -11.840713991364°
2018-10-24 10:30:45.165 Status: LUA: Universel Coordinated Time (UTC)8.5 H.dd
2018-10-24 10:30:45.165 Status: LUA: Solar Hour 8.2556084 H.dd
2018-10-24 10:30:45.165 Status: LUA: Altitude of the sun = 16.364842469331°
2018-10-24 10:30:45.165 Status: LUA: Angular hourly = 56.165874°
2018-10-24 10:30:45.165 Status: LUA: Azimuth of the sun = 122.08025037701°
2018-10-24 10:30:45.165 Status: LUA: Duration of the sunstroke of the day = 10.63 H.dd
2018-10-24 10:30:45.166 Status: LUA: Radiation max in atmosphere = 1379.03 W/m²
2018-10-24 10:30:45.166 Status: LUA: Local relative pressure = 1026 hPa
2018-10-24 10:30:45.166 Status: LUA: Absolute pressure in atmosphere = 944.1 hPa
2018-10-24 10:30:45.166 Status: LUA: Coefficient of mitigation M = 3.8214061417113 M0:3.5163640725045
2018-10-24 10:30:45.166 Status: LUA: curl "http://www.ogimet.com/cgi-bin/getsynop?block=08224&begin=201810240700"
2018-10-24 10:30:45.339 Status: LUA: Error : Did you create the Uservariable octa ?
2018-10-24 10:30:45.339 Status: LUA: WU Script Parsed Temp=11.9 Humidity=72 Pressure=1026
2018-10-24 10:30:45.339 Status: LUA: <b style="color:Blue"============== SUN LOG ==================</b>
2018-10-24 10:30:45.339 Status: LUA: 2018-10-24 10:30:45
2018-10-24 10:30:45.339 Status: LUA: latitude:40.428501, longitude:-3.665874
2018-10-24 10:30:45.339 Status: LUA: Home altitude = 680 m
2018-10-24 10:30:45.339 Status: LUA: number Of Day = 297
2018-10-24 10:30:45.340 Status: LUA: 2018 is not a leap year
2018-10-24 10:30:45.340 Status: LUA: Angular Speed = 0.98562628336756 per day
2018-10-24 10:30:45.340 Status: LUA: Declinaison = -11.840713991364°
2018-10-24 10:30:45.340 Status: LUA: Universel Coordinated Time (UTC)8.5 H.dd
2018-10-24 10:30:45.340 Status: LUA: Solar Hour 8.2556084 H.dd
2018-10-24 10:30:45.340 Status: LUA: Altitude of the sun = 16.364842469331°
2018-10-24 10:30:45.340 Status: LUA: Angular hourly = 56.165874°
2018-10-24 10:30:45.340 Status: LUA: Azimuth of the sun = 122.08025037701°
2018-10-24 10:30:45.340 Status: LUA: Duration of the sunstroke of the day = 10.63 H.dd
2018-10-24 10:30:45.340 Status: LUA: Radiation max in atmosphere = 1379.03 W/m²
2018-10-24 10:30:45.340 Status: LUA: Local relative pressure = 1026 hPa
2018-10-24 10:30:45.340 Status: LUA: Absolute pressure in atmosphere = 944.1 hPa
2018-10-24 10:30:45.340 Status: LUA: Coefficient of mitigation M = 3.8214061417113 M0:3.5163640725045
2018-10-24 10:30:45.340 Status: LUA: curl "http://www.ogimet.com/cgi-bin/getsynop?block=08224&begin=201810240700"
2018-10-24 10:30:45.325 Error: EventSystem: in solar: [string " --[[ Virtual Lux sensor and other rea..."]:140: bad argument #1 to 'gsub' (string expected, got nil) 

Sometimes rebooting fixes the problem, other times I erase the script and I create it again an it works for several hours. It's a quite erratic behaviour.
Last night stopped working, and this morning began to work for a few hours. Now it is not working again.

I am wondering if it could it be something related with the ogimet service?
At the moment of writting this post if i go to https://www.ogimet.com/cgi-bin/getsynop ... 1810240800 the web page is blank.
But if i go to https://www.ogimet.com/cgi-bin/getsynop ... 1810230800 it gives data.

Any help will be appreciated. Thanks! ;)

Re: Real-time solar data : azimuth, Altitude, Lux sensor...

Posted: Wednesday 24 October 2018 14:41
by damosta
Solved. It was an issue with the Station ID.
The one I chosed was not reporting hourly.

Re: Real-time solar data : azimuth, Altitude, Lux sensor...

Posted: Tuesday 13 November 2018 22:30
by RapTile
Did anyone updated this script to use dark sky instead of WU?

I would like to have a virtual lux sensor for my hue ambiance bulbs

TIA

Re: Real-time solar data : azimuth, Altitude, Lux sensor...

Posted: Wednesday 14 November 2018 16:01
by RapTile
RapTile wrote: Tuesday 13 November 2018 22:30 Did anyone updated this script to use dark sky instead of WU?

I would like to have a virtual lux sensor for my hue ambiance bulbs

TIA
This has been done:
viewtopic.php?f=72&t=19220&sid=5e62c0ad ... &start=100

Re: Real-time solar data : azimuth, Altitude, Lux sensor...

Posted: Monday 25 March 2019 9:05
by Derik
Someone make this script working again?
Wu is stopped..
or is there a other option?

Re: Real-time solar data : azimuth, Altitude, Lux sensor...

Posted: Monday 25 March 2019 10:42
by Toulon7559
This old message may offer some help:
- don't make online calls for WU-info, but (if not yet included in your script)
#1. use your local online baro-read-out (in Domoticz or otherwise)
#2. geo-position is static, therefore find & insert as static values
#3. (because WMOID is also static) look once in the list and insert WMOID as a constant value.

;-) Least dependency on external resources for information!
Various script-versions later than the quoted message follow that line.

Re: Real-time solar data : azimuth, Altitude, Lux sensor...

Posted: Tuesday 26 March 2019 21:53
by multinet
Hello Toulon7559

Could you please share your script without WU ?

Thanks a lot
Multinet

Re: Real-time solar data : azimuth, Altitude, Lux sensor...

Posted: Friday 29 March 2019 16:07
by yack1
Hey, Toulon7559

Could you please share your script without WU ?

Thanks a lot
yack1

Re: Real-time solar data : azimuth, Altitude, Lux sensor...

Posted: Saturday 30 March 2019 11:07
by multinet
I found the last version of the script on GitHub running well using dark sky