dzVents version of the Solar Data Script

oredin
Posts: 6
Joined: Saturday 27 October 2018 13:01
Target OS: -
Domoticz version:
Contact:

Re: dzVents version of the Solar Data Script

Post by oredin » Friday 16 November 2018 15:58

RapTile wrote:
Friday 16 November 2018 13:17
You did an awesome job, thanks!
But, there is something wrong with the script or i made a mistake myself implementing it.

Currently it is cloudy in the netherlands and the current indicated Lux value 13370.

The Lux wiki tells me that a clouded day is around 1000 Lux.
So 1337 Lux should be very cloudy ;-)

I think the "0" in the end should not exist or i made a mistake with the script and idx values but i've checked them three times so far so i don't know how i could do something wrong..
Hi,

I've checked the script. So far, it seems to me that the translation from okta to cloud coverage in percent seems good in the script.

I've looked further into the notion of okta (sky nebulosity) and cloud coverage from the intial article on domotique-info.fr. From what I've read, the two notions aren't the same things and can differ. That's why the initial contributor (Sebastien Joly) used the okta for his algorithm. The problem seems to be getting a real sky nebulosity value from a web API.

That being said, I've check the French version of the Lux wiki and it states that an overcast sky can be between 500 and 25 000 lux :? Looking at your last screenshot, 18k lux for 58% of cloud coverage could be good :D

I'll try to find a source for the real okta value for my position and check if the result are similar with the cloud coverage of Dark Sky. The only other solution would be to get an actual brightness sensor to compare the value computed by the script.

Unfortunately, for now, I don't have a real answer for your question except that the script is working fine as it is on your DZ. The only problem could be the lux calculation but it's not your fault ;)

I'll keep in touch if I get any further info on the problem.

RapTile
Posts: 64
Joined: Saturday 10 March 2018 3:01
Target OS: Raspberry Pi
Domoticz version:
Contact:

Re: dzVents version of the Solar Data Script

Post by RapTile » Friday 16 November 2018 16:53

hestia wrote:
Friday 16 November 2018 15:55
<..>
device "CloudCover" => General Custom Sensor /!\ not a % device
after in the axis of the custom sensor you put what you want, there is no unit for the cloud sensor
That's weird.
On github (https://github.com/russandol-sarl/dz-solarData) it shows:

Code: Select all

dxCloudCover : Create a virtual device "Percentage" and get its id if you want to see the computed value of the script
is this documentation incorrect or is the script?

RapTile
Posts: 64
Joined: Saturday 10 March 2018 3:01
Target OS: Raspberry Pi
Domoticz version:
Contact:

Re: dzVents version of the Solar Data Script

Post by RapTile » Friday 16 November 2018 17:05

oredin wrote:
Friday 16 November 2018 15:58
<..>
Hi,

I've checked the script. So far, it seems to me that the translation from okta to cloud coverage in percent seems good in the script.

I've looked further into the notion of okta (sky nebulosity) and cloud coverage from the intial article on domotique-info.fr. From what I've read, the two notions aren't the same things and can differ. That's why the initial contributor (Sebastien Joly) used the okta for his algorithm. The problem seems to be getting a real sky nebulosity value from a web API.

That being said, I've check the French version of the Lux wiki and it states that an overcast sky can be between 500 and 25 000 lux :? Looking at your last screenshot, 18k lux for 58% of cloud coverage could be good :D

I'll try to find a source for the real okta value for my position and check if the result are similar with the cloud coverage of Dark Sky. The only other solution would be to get an actual brightness sensor to compare the value computed by the script.

Unfortunately, for now, I don't have a real answer for your question except that the script is working fine as it is on your DZ. The only problem could be the lux calculation but it's not your fault ;)

I'll keep in touch if I get any further info on the problem.
Thanks for your investigation and reply :)

The dutch explanation and the english version seems to be a bit different as well. It depends on the interpretation so that's hard for me to understand :D

But i hope that everything is working fine!

oredin
Posts: 6
Joined: Saturday 27 October 2018 13:01
Target OS: -
Domoticz version:
Contact:

Re: dzVents version of the Solar Data Script

Post by oredin » Friday 16 November 2018 17:24

RapTile wrote:
Friday 16 November 2018 16:53
hestia wrote:
Friday 16 November 2018 15:55
<..>
device "CloudCover" => General Custom Sensor /!\ not a % device
after in the axis of the custom sensor you put what you want, there is no unit for the cloud sensor
That's weird.
On github (https://github.com/russandol-sarl/dz-solarData) it shows:

Code: Select all

dxCloudCover : Create a virtual device "Percentage" and get its id if you want to see the computed value of the script
is this documentation incorrect or is the script?
My script uses a percentage sensor BUT hestia's script uses a custom sensor ! They're not the same.

hestia
Posts: 24
Joined: Tuesday 26 December 2017 0:06
Target OS: Raspberry Pi
Domoticz version: 4.9700
Location: Paris
Contact:

Re: dzVents version of the Solar Data Script

Post by hestia » Friday 16 November 2018 17:31

RapTile wrote:
Friday 16 November 2018 16:53
hestia wrote:
Friday 16 November 2018 15:55
<..>
device "CloudCover" => General Custom Sensor /!\ not a % device
after in the axis of the custom sensor you put what you want, there is no unit for the cloud sensor
That's weird.
On github (https://github.com/russandol-sarl/dz-solarData) it shows:

Code: Select all

dxCloudCover : Create a virtual device "Percentage" and get its id if you want to see the computed value of the script
is this documentation incorrect or is the script?
I think I understand
there are 2 scritps not already aligned!
mine is for the weather and the solar one.
If you want to use my script to give you input for the solar one, perhaps you need to change one of them a little.
If you want to keep the sensor with % you need to change my script with

dz.devices(dev_cloudCover).updateCustomSensor(triggerObject.json.currently.cloudCover)
to
dz.devices(dev_cloudCover).updatePercentage(triggerObject.json.currently.cloudCover)

I didn't test it yet!

Or to change the other script!

bramv
Posts: 3
Joined: Wednesday 27 June 2018 23:53
Target OS: Raspberry Pi
Domoticz version: 4.10228
Location: Netherlands
Contact:

Re: dzVents version of the Solar Data Script

Post by bramv » Wednesday 28 November 2018 1:23

The WeatherUnderground API will stop working at the and of the year and new API keys are not available.
Therefore I wanted to use the OpenWeatherMap data. Domoticz already has an interface with that so it should be easy to use that.

I've changed the DzVents version of the script to use an Domoticz sensor for percentage clouds and barometer.

With this script you can use the OpenWeatherMap data or data from a local weather station sensor.
Just fill in the idx of the sensors and it works.

Are there people interested in testing the script?

RapTile
Posts: 64
Joined: Saturday 10 March 2018 3:01
Target OS: Raspberry Pi
Domoticz version:
Contact:

Re: dzVents version of the Solar Data Script

Post by RapTile » Thursday 29 November 2018 12:59

bramv wrote:
Wednesday 28 November 2018 1:23
The WeatherUnderground API will stop working at the and of the year and new API keys are not available.
Therefore I wanted to use the OpenWeatherMap data. Domoticz already has an interface with that so it should be easy to use that.

I've changed the DzVents version of the script to use an Domoticz sensor for percentage clouds and barometer.

With this script you can use the OpenWeatherMap data or data from a local weather station sensor.
Just fill in the idx of the sensors and it works.

Are there people interested in testing the script?
I've send u a pm

bramv
Posts: 3
Joined: Wednesday 27 June 2018 23:53
Target OS: Raspberry Pi
Domoticz version: 4.10228
Location: Netherlands
Contact:

Re: dzVents version of the Solar Data Script

Post by bramv » Saturday 08 December 2018 21:17

Sorry raptile. I can't reply to your p.m. yet because I'm too new on the forum.

Here is my version of the script so you can use the openweahtermaps and your own sensors.
I use the cloud information from the open wheathermaps and the baro pressure from my zigbee sensor.

Code: Select all

--[[
	Prerequisits
	==================================
	Requires Domoticz v3.8551 or later
	Platform dependent, requires Linux

	CHANGE LOG: See http://www.domoticz.com/forum/viewtopic.php?t=19220 

Virtual Lux sensor and other real-time solar data

-- Authors  ----------------------------------------------------------------
	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 - xces - UTC time calculation.
	V2.0 - BakSeeDaa - Converted to dzVents and changed quite many things.
	v3.0 - Bram Vreugdenhil Converted from Weather underground api calls to data of domoticz devices so you can use OpenWeathermaps sensors or own sensors
]]--

-- Input devices . You can use Openweathermap devices for it. Just add "Open Weather Map" in the hardware setup.
local idxCloudCover = 78      -- (Integer) Device ID of device holding cloudcoverage
local idxBarometer  = 75      -- (Integer) Device ID of device barometric presusure

-- Variables to customize (can be nil )------------------------------------------
local idxSolarAzimuth  = 1997 -- (Integer) Virtual Azimuth Device ID
local idxSolarAltitude = 1998 -- (Integer) Your virtual Solar Altitude Device ID
local idxRadiation     = 1999 -- (Integer) Domoticz virtual Radiation device ID
local idxLux           = 1996 -- (Integer) Domoticz virtual Lux device ID

local logToFile = false		  -- (Boolean) Set to true if you also wish to log to a file. It might get big by time. 
local tmpLogFile = '/tmp/logSun.txt'-- Logging to a file if specified 
local fetchIntervalMins = 5	  -- (Integer) (Minutes, Range 5-60) How often Wunderground API is called 


local latitude  = 51.9891087	-- Latitude. (Decimal number) Decimal Degrees. E.g. something like 51.748485
local longitude = 4.1554187000	-- Longitude. (Decimal number) Decimal Degrees. E.g.something like 5.629728.
local altitude  = 1         	-- Altitude. (Integer) Meters above sea level.

-- Please don't make any changes below this line (Except for setting logging level)

local scriptVersion = '3'

return {
	active = true,
	logging = {
		--level = domoticz.LOG_DEBUG, -- Uncomment to override the dzVents global logging setting
		marker = 'SOLAR '..scriptVersion
	},
	on = {
		timer = {'every 5 minutes'}
	},
	data = {
		lastOkta = {initial=0},
		lastOgimetTime = {initial='198001010000'}
	},
	execute = function(domoticz, device)

		local function leapYear(year)   
			return year%4==0 and (year%100~=0 or year%400==0)
		end

		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²

		local relativePressure = domoticz.devices(idxBarometer).barometer

		local year = os.date('%Y')
		local numOfDay = os.date('%j')
		local nbDaysInYear = (leapYear(year) and 366 or 365)

		local angularSpeed = 360/365.25
		local declination = math.deg(math.asin(0.3978 * math.sin(math.rad(angularSpeed) *(numOfDay - (81 - 2 * math.sin((math.rad(angularSpeed) * (numOfDay - 2))))))))
		local timeDecimal = (os.date('!%H') + os.date('!%M') / 60) -- Coordinated Universal Time  (UTC)
		local solarHour = timeDecimal + (4 * longitude / 60 )    -- The solar Hour
		local hourlyAngle = 15 * ( 12 - solarHour )          -- hourly Angle of the sun
		local sunAltitude = math.deg(math.asin(math.sin(math.rad(latitude))* math.sin(math.rad(declination)) + math.cos(math.rad(latitude)) * math.cos(math.rad(declination)) * math.cos(math.rad(hourlyAngle))))-- the height of the sun in degree, compared with the horizon

		local azimuth = math.acos((math.sin(math.rad(declination)) - 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(declination)) * math.sin(math.rad(hourlyAngle))) / math.cos(math.rad(sunAltitude))
		if(sinAzimuth<0) then azimuth=360-azimuth end
		local sunstrokeDuration = math.deg(2/15 * math.acos(- math.tan(math.rad(latitude)) * math.tan(math.rad(declination)))) -- duration of sunstroke in the day . Not used in this calculation.
		local 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
		local absolutePressure = relativePressure - domoticz.utils.round((altitude/ 8.3),1) -- hPa
		local sinusSunAltitude = math.sin(math.rad(sunAltitude))
		local M0 = math.sqrt(1229 + math.pow(614 * sinusSunAltitude,2)) - 614 * sinusSunAltitude
		local M = M0 * relativePressure/absolutePressure

		domoticz.log('', domoticz.LOG_INFO)
		domoticz.log('==============  SUN  LOG ==================', domoticz.LOG_INFO)
		--domoticz.log(city .. ', latitude: ' .. latitude .. ', longitude: ' .. longitude, domoticz.LOG_INFO)
		--domoticz.log('Home altitude = ' .. tostring(altitude) .. ' m', domoticz.LOG_DEBUG)
		domoticz.log('Angular Speed = ' .. angularSpeed .. ' per day', domoticz.LOG_DEBUG)
		domoticz.log('Declination = ' .. declination .. '°', domoticz.LOG_DEBUG)
		domoticz.log('Universal Coordinated Time (UTC) '.. timeDecimal ..' H.dd', domoticz.LOG_DEBUG)
		domoticz.log('Solar Hour '.. solarHour ..' H.dd', domoticz.LOG_DEBUG)
		domoticz.log('Altitude of the sun = ' .. sunAltitude .. '°', domoticz.LOG_INFO)
		domoticz.log('Angular hourly = '.. hourlyAngle .. '°', domoticz.LOG_DEBUG)
		domoticz.log('Azimuth of the sun = ' .. azimuth .. '°', domoticz.LOG_INFO)
		domoticz.log('Duration of the sun stroke of the day = ' .. domoticz.utils.round(sunstrokeDuration,2) ..' H.dd', domoticz.LOG_DEBUG)
		domoticz.log('Radiation max in atmosphere = ' .. domoticz.utils.round(RadiationAtm,2) .. ' W/m²', domoticz.LOG_DEBUG)
		domoticz.log('Local relative pressure = ' .. relativePressure .. ' hPa', domoticz.LOG_DEBUG)
		domoticz.log('Absolute pressure in atmosphere = ' .. absolutePressure .. ' hPa', domoticz.LOG_DEBUG)
		domoticz.log('Coefficient of mitigation M = ' .. M ..' M0 = '..M0, domoticz.LOG_DEBUG)

		-- In meteorology, an okta is a unit of measurement used to describe the amount of cloud cover
		-- at any given location such as a weather station. Sky conditions are estimated in terms of how many
		-- eighths of the sky are covered in cloud, ranging from 0 oktas (completely clear sky) through to 8 oktas
		-- (completely overcast). In addition, in the synop code there is an extra cloud cover indicator '9'
		-- indicating that the sky is totally obscured (i.e. hidden from view),
		-- usually due to dense fog or heavy snow.

        Cloudpercentage = domoticz.devices(idxCloudCover).percentage
		
		okta = Cloudpercentage/12.5
		
		local Kc = 1-0.75*math.pow(okta/8,3.4)  -- Factor of mitigation for the cloud layer

		local directRadiation, scatteredRadiation, totalRadiation, Lux, weightedLux
		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

        totalRadiation=totalRadiation*Kc
        
		domoticz.log('Okta = '..okta.. ' Cloud coverage = ' ..Cloudpercentage .. '%', domoticz.LOG_INFO)
		domoticz.log('Kc = ' .. Kc, domoticz.LOG_DEBUG)
		domoticz.log('Direct Radiation = '.. domoticz.utils.round(directRadiation,2) ..' W/m²', domoticz.LOG_INFO)
		domoticz.log('Scattered Radiation = '.. domoticz.utils.round(scatteredRadiation,2) ..' W/m²', domoticz.LOG_DEBUG)
		domoticz.log('Total radiation = ' .. domoticz.utils.round(totalRadiation,2) ..' W/m²', domoticz.LOG_INFO)
		domoticz.log('Total Radiation in lux = '.. domoticz.utils.round(Lux,2)..' Lux', domoticz.LOG_DEBUG)
		domoticz.log('Total weighted lux  = '.. domoticz.utils.round(weightedLux,2)..' Lux', domoticz.LOG_INFO)

		-- 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'])
		if idxLux and domoticz.devices(idxLux).lux + domoticz.utils.round(weightedLux, 0) > 0 then
			domoticz.devices(idxLux).updateLux(domoticz.utils.round(weightedLux,0))
		end
		if(idxSolarAzimuth) then
		   domoticz.devices(idxSolarAzimuth).updateCustomSensor(domoticz.utils.round(azimuth,0))
		end   
		if(idxSolarAltitude) then
		   domoticz.devices(idxSolarAltitude).updateCustomSensor(domoticz.utils.round(sunAltitude,0))
		end
		-- No update if radiation is already 0. See LUX
		if idxRadiation and (domoticz.devices(idxRadiation).rawData[1] + domoticz.utils.round(totalRadiation, 2) > 0) then 
		    domoticz.devices(idxRadiation).updateCustomSensor(domoticz.utils.round(totalRadiation,2))
		end
		if logToFile then
			local logDebug = os.date('%Y-%m-%d %H:%M:%S',os.time())
			logDebug=logDebug..' Azimuth:' .. azimuth .. ' Height:' .. sunAltitude
			logDebug=logDebug..' Okta:' .. okta..'  KC:'.. Kc
			logDebug=logDebug..' Direct:'..directRadiation..' inDirect:'..scatteredRadiation..' TotalRadiation:'..totalRadiation..' LuxCloud:'.. domoticz.utils.round(weightedLux,2)
			os.execute('echo '..logDebug..' >>'..tmpLogFile)  -- compatible Linux & Windows
		end
	end
}

Post Reply

Who is online

Users browsing this forum: No registered users and 0 guests