dzVents version of the Solar Data Script  [SOLVED]

Moderator: leecollings

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

Re: dzVents version of the Solar Data Script

Post by oredin »

RapTile wrote: Friday 16 November 2018 12: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: 53
Joined: Saturday 10 March 2018 2:01
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: dzVents version of the Solar Data Script

Post by RapTile »

hestia wrote: Friday 16 November 2018 14: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: 53
Joined: Saturday 10 March 2018 2:01
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: dzVents version of the Solar Data Script

Post by RapTile »

oredin wrote: Friday 16 November 2018 14: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: 14
Joined: Saturday 27 October 2018 13:01
Target OS: -
Domoticz version:
Contact:

Re: dzVents version of the Solar Data Script

Post by oredin »

RapTile wrote: Friday 16 November 2018 15:53
hestia wrote: Friday 16 November 2018 14: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: 357
Joined: Monday 25 December 2017 23:06
Target OS: Raspberry Pi / ODroid
Domoticz version: 2022.1
Location: Paris
Contact:

Re: dzVents version of the Solar Data Script

Post by hestia »

RapTile wrote: Friday 16 November 2018 15:53
hestia wrote: Friday 16 November 2018 14: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: 17
Joined: Wednesday 27 June 2018 23:53
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: Netherlands/Westland
Contact:

Re: dzVents version of the Solar Data Script

Post by bramv »

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: 53
Joined: Saturday 10 March 2018 2:01
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: dzVents version of the Solar Data Script

Post by RapTile »

bramv wrote: Wednesday 28 November 2018 0: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: 17
Joined: Wednesday 27 June 2018 23:53
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: Netherlands/Westland
Contact:

Re: dzVents version of the Solar Data Script

Post by bramv »

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
}
User avatar
EdwinK
Posts: 1820
Joined: Sunday 22 January 2017 21:46
Target OS: Raspberry Pi / ODroid
Domoticz version: BETA
Location: Rhoon
Contact:

Re: dzVents version of the Solar Data Script

Post by EdwinK »

Thanks. Was kind of hoping someone would create this ;)
Running latest BETA on a Pi-3 | Toon® Thermostat (rooted) | Hue | Tuya | IKEA tradfri | Dashticz V3 on Lenovo Huawei Tablet | Conbee
jake
Posts: 742
Joined: Saturday 30 May 2015 22:40
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Contact:

Re: dzVents version of the Solar Data Script

Post by jake »

Thanks for the V3 script.

Question: I don't have the radiation sensor/device. Can I simply comment the definition of the local idxRadiation?

Remark:
Line 126 (elseif sunAltitude = -7) returns an error, this should be changed into (elseif sunAltitude == -7), a double ==
bramv
Posts: 17
Joined: Wednesday 27 June 2018 23:53
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: Netherlands/Westland
Contact:

Re: dzVents version of the Solar Data Script

Post by bramv »

@jake

If you don't need a calculated radiation you can set the idxRadiation to nil.

About the error: It's strange because I don't see the compare with -7

The code is:
Line:128
elseif sunAltitude <= 1 and sunAltitude >= -7 then -- apply theoretical Lux of twilight

Line 135: elseif sunAltitude < -7 then -- no management of nautical and astronomical twilight...
jake
Posts: 742
Joined: Saturday 30 May 2015 22:40
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Contact:

Re: dzVents version of the Solar Data Script

Post by jake »

bramv wrote:@jake

If you don't need a calculated radiation you can set the idxRadiation to nil.

About the error: It's strange because I don't see the compare with -7

The code is:
Line:128
elseif sunAltitude <= 1 and sunAltitude >= -7 then -- apply theoretical Lux of twilight

Line 135: elseif sunAltitude < -7 then -- no management of nautical and astronomical twilight...
Thanks.

The missing = is located in the radiation section of your script. I copied the below text from your message where you shared your script:

Code: Select all

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 = -7 then -- apply theoretical Lux of twilight
			directRadiation = 0
			scatteredRadiation = 0
bramv
Posts: 17
Joined: Wednesday 27 June 2018 23:53
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: Netherlands/Westland
Contact:

Re: dzVents version of the Solar Data Script

Post by bramv »

@jake

Very strange. You had the same problem on 4 august with the 2.4 version of the script.
Maybee it's related to you browser or something like that. I see the script correct on this site in both versions.

It should be
elseif sunAltitude <= 1 and sunAltitude >= -7 then -- apply theoretical Lux of twilight

So no == but >=

But if you loose a "greater then" character on this line maybee you loose some more and the script is not correct.

You also miss the part "sunAltitude <= 1 and"
Thugbear
Posts: 5
Joined: Wednesday 06 June 2018 14:08
Target OS: Raspberry Pi / ODroid
Domoticz version: 2022.1
Location: Netherlands
Contact:

Re: dzVents version of the Solar Data Script

Post by Thugbear »

I seem to have a really weird issue.

It is very cloudy here today, yet the cover is reported as 23%. My calculated LUX is 40.000 and above, which feels way to high for the location right now.

I'm suspecting something in the calculation is going wrong but I can't lay my fingers on it. I'm using the dzvents version of the script 2.4.1. What information is needed for troubleshooting, as I'm a little at a loss and the LUX reported is way too high to be useful at this moment.

Thanks in advance...

Additionally it seems to go wrong at exactly 12:00 midday as the LUX jumps from 12.000 to 40.000 and the clouds just got thicker. Perhaps that helps?

This is my result in the log:

Code: Select all

2019-03-06 14:40:00.207 Status: dzVents: Info: ------ Finished script_device_sensorBlitz 
2019-03-06 14:40:00.207 Status: dzVents: !Info: Meteo: *** Request url 
2019-03-06 14:40:00.208 Status: dzVents: Info: solarData 2.4.1-DarkSky: ------ Start internal script: script_real-time_solar_data_darksky:, trigger: every 5 minutes at daytime 
2019-03-06 14:40:00.242 Status: dzVents: Info: solarData 2.4.1-DarkSky: ------ Finished script_real-time_solar_data_darksky 
2019-03-06 14:40:00.345 Status: EventSystem: Script event triggered: /usr/local/domoticz/dzVents/runtime/dzVents.lua 
2019-03-06 14:40:01.318 Status: dzVents: Info: Handling httpResponse-events for: "getDarkSkyForecast 
2019-03-06 14:40:01.338 Status: dzVents: !Info: Meteo: *** Response... 
2019-03-06 14:40:01.357 Status: dzVents: !Info: Meteo: Meteo Dark Sky end OK 
2019-03-06 14:40:01.358 Status: EventSystem: Script event triggered: /usr/local/domoticz/dzVents/runtime/dzVents.lua 
2019-03-06 14:40:11.075 Status: dzVents: Info: Handling httpResponse-events for: "solarDataDS 
2019-03-06 14:40:11.075 Status: dzVents: Info: solarData 2.4.1-DarkSky: ------ Start internal script: script_real-time_solar_data_darksky: HTTPResponse: "solarDataDS" 
2019-03-06 14:40:11.079 Status: dzVents: Info: solarData 2.4.1-DarkSky: 
2019-03-06 14:40:11.079 Status: dzVents: Info: solarData 2.4.1-DarkSky: ============== SUN LOG ================== 
2019-03-06 14:40:11.079 Status: dzVents: Info: solarData 2.4.1-DarkSky: Amsterdamlatitude: 52.359128, longitude: 4.788396 
2019-03-06 14:40:11.079 Status: dzVents: Info: solarData 2.4.1-DarkSky: Altitude of the sun = 26.820081386604° 
2019-03-06 14:40:11.079 Status: dzVents: Info: solarData 2.4.1-DarkSky: Azimuth of the sun = 213.64790200762° 
2019-03-06 14:40:11.079 Status: dzVents: Info: solarData 2.4.1-DarkSky: 
2019-03-06 14:40:11.079 Status: dzVents: Info: solarData 2.4.1-DarkSky: Okta = 0.24 
2019-03-06 14:40:11.079 Status: dzVents: Info: solarData 2.4.1-DarkSky: Direct Radiation = 201.64 W/m² 
2019-03-06 14:40:11.079 Status: dzVents: Info: solarData 2.4.1-DarkSky: Total weighted lux = 39166.74 Lux 
2019-03-06 14:40:11.094 Status: dzVents: Info: solarData 2.4.1-DarkSky: ------ Finished script_real-time_solar_data_darksky 
2019-03-06 14:40:11.094 Status: EventSystem: Script event triggered: /usr/local/domoticz/dzVents/runtime/dzVents.lua 
jake
Posts: 742
Joined: Saturday 30 May 2015 22:40
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Contact:

Re: dzVents version of the Solar Data Script

Post by jake »

I checked my current values and it is 10k lux and 90 percent cloud, which in the NL unfortunately is true :(

Btw, I thought my script used the openweather.map data
oredin
Posts: 14
Joined: Saturday 27 October 2018 13:01
Target OS: -
Domoticz version:
Contact:

Re: dzVents version of the Solar Data Script

Post by oredin »

Thugbear wrote: Wednesday 06 March 2019 14:38 I seem to have a really weird issue.

It is very cloudy here today, yet the cover is reported as 23%. My calculated LUX is 40.000 and above, which feels way to high for the location right now.

I'm suspecting something in the calculation is going wrong but I can't lay my fingers on it. I'm using the dzvents version of the script 2.4.1. What information is needed for troubleshooting, as I'm a little at a loss and the LUX reported is way too high to be useful at this moment.

Thanks in advance...

Additionally it seems to go wrong at exactly 12:00 midday as the LUX jumps from 12.000 to 40.000 and the clouds just got thicker. Perhaps that helps?
Hi,

Seems you're using my script and not the one from bramv. I'll check the difference between mine and bramv's to see if there's any difference about the LUX. It could be that i've made an error when I adapted the script with the cloud coverage instead of the okta value.

@jake : You're using the bramv's version of the script, aren't you ?
jake
Posts: 742
Joined: Saturday 30 May 2015 22:40
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Contact:

Re: dzVents version of the Solar Data Script

Post by jake »


oredin wrote: @jake : You're using the bramv's version of the script, aren't you ?
I checked it when I got home and I indeed use the bramv v3 version of the script

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

Re: dzVents version of the Solar Data Script

Post by oredin »

jake wrote: Wednesday 06 March 2019 18:17 I checked it when I got home and I indeed use the bramv v3 version of the script
Thanks for the confirmation. I'll check the difference between bramv's calculation and mine since his seem more exact.
renerene
Posts: 316
Joined: Wednesday 03 August 2016 11:36
Target OS: -
Domoticz version:
Contact:

Re: dzVents version of the Solar Data Script

Post by renerene »

WeatherUnderground is not supported anymore. Can somebody update the script with a workaround?
hestia
Posts: 357
Joined: Monday 25 December 2017 23:06
Target OS: Raspberry Pi / ODroid
Domoticz version: 2022.1
Location: Paris
Contact:

Re: dzVents version of the Solar Data Script

Post by hestia »

renerene wrote: Sunday 10 March 2019 15:17 WeatherUnderground is not supported anymore. Can somebody update the script with a workaround?
I've writen a DzVents script to get values from DarkSky, with pressure and cloud cover => all put in dz device

viewtopic.php?f=72&t=19220&p=197873#p197666

and adapted the script to use values from the devices

Code: Select all

--[[
	Prerequisites
	==================================
	Requires Domoticz v3.8551 or later
	2 sensors with Cloud Cover and Pressure updated
	
	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.
	V2.4.1-DarkSky - oredin - Use Dark Sky API instead of WU API
	V x.x - SolarData_V0 by hestia - sources independent: use sensor with input values for CloudCover and Pressure
]]--

-- Variables to customize ------------------------------------------------
local idxSolarAzimuth = 337						-- (Integer) Virtual Azimuth Device ID
local idxSolarAltitude = 338					-- (Integer) Your virtual Solar Altitude Device ID

local fetchIntervalDayMins = 5 -- Day time scraping interval
local fetchIntervalNightMins = 30 -- Night time scraping interval

-- Domoticz devices to get data
-- local idxCloudCover = 309 -- (Integer) Domoticz Cloud Cover (custom sensor device ID)
local idxCloudCoverPerCent = 339 -- (Integer) Domoticz Cloud Cover (percentage device ID) => to choose the one you want
local idxPressure = 303 -- (Integer) Your Pressure Device ID

-- Domoticz devices to save result
local idxLux = 305 -- (Integer) Domoticz virtual Lux device ID
local idxSolarRadiation = 304 -- (Integer) Domoticz virtual Solar Radiation device ID

-- (You don't have to configure these if you accept the values returned by the weather observation station)
local latitude = 48.810521	-- Latitude. (Decimal number) Decimal Degrees. E.g. something like 51.748485
local longitude = 2.280379	-- Longitude. (Decimal number) Decimal Degrees. E.g.something like 5.629728.
local altitude = 100	-- Altitude. (Integer) Meters above sea level.

-- There is no simple conversion...it depends on the wavelength or color of the light
-- However, for the SUN, there is an approximate conversion of 0.0079
-- Lux.http://bccp.berkeley.edu/o/Academy/workshop_09/pdfs/InverseSquareLawPresentation.p
local LuxToWm2 = 0.0079

local scriptName = 'solarData'
local scriptVersion = '2.4.1-From dz'

return {
	active = true,
	logging = {
		level = domoticz.LOG_ERROR, -- Uncomment to override the dzVents global logging setting
		marker = scriptName..' '..scriptVersion
	},
	on = {
		-- devices = {206},   -- a switch for testing w/o waiting minutes
		timer = {
			'every '..tostring(fetchIntervalDayMins)..' minutes at daytime',
			'every '..tostring(fetchIntervalNightMins)..' minutes at nighttime',
		},
	},
	
	execute = function(domoticz, item)

    	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(idxPressure).barometer  -- from dz sensor updated with other script or a sensor
		
		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('latitude: ' .. latitude .. ', longitude: ' .. longitude, domoticz.LOG_INFO)
		domoticz.log('Home altitude = ' .. tostring(altitude) .. ' m', domoticz.LOG_INFO)
		domoticz.log('Angular Speed = ' .. angularSpeed .. ' per day', domoticz.LOG_INFO)
		domoticz.log('Declination = ' .. declination .. '°', domoticz.LOG_INFO)
		domoticz.log('Universal Coordinated Time (UTC) '.. timeDecimal ..' H.dd', domoticz.LOG_INFO)
		domoticz.log('Solar Hour '.. solarHour ..' H.dd', domoticz.LOG_INFO)
		domoticz.log('Altitude of the sun = ' .. sunAltitude .. '°', domoticz.LOG_INFO)
		domoticz.log('Angular hourly = '.. hourlyAngle .. '°', domoticz.LOG_INFO)
		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_INFO)
		domoticz.log('Radiation max in atmosphere = ' .. domoticz.utils.round(RadiationAtm,2) .. ' W/m²', domoticz.LOG_INFO)
		domoticz.log('Local relative pressure = ' .. relativePressure .. ' hPa', domoticz.LOG_INFO)
		domoticz.log('Absolute pressure in atmosphere = ' .. absolutePressure .. ' hPa', domoticz.LOG_INFO)
		domoticz.log('Coefficient of mitigation M = ' .. M ..' M0 = '..M0, domoticz.LOG_INFO)
		domoticz.log('', domoticz.LOG_INFO)

		local dz_cloudCover = 0
		if idxCloudCover ~= nill then
		     dz_cloudCover = domoticz.devices(idxCloudCover).state / 100
		    -- print('************* state: ' .. dz_cloudCover)
    	    elseif idxCloudCoverPerCent ~= nill then
    	         dz_cloudCover = domoticz.devices(idxCloudCoverPerCent).percentage / 100
    	        -- print('************ %%%%%%%%%%%%%%: ' .. dz_cloudCover)
        else domoticz.log('No cloudCover sensor !', domoticz.LOG_ERROR)
            -- print('********* no cloud cover !!!!!!!!!!!')
        end
            
		local okta = (dz_cloudCover * 8) -- octa is from 0 to 8 / cloud cover is from 0% to 100%
	--	print('okta: ' .. okta)
		local Kc = 1-0.75*math.pow(okta/8,3.4)  -- Factor of mitigation for the cloud layer
	--	print('Kc: ' .. Kc)

		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 / LuxToWm2  -- 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 / LuxToWm2  -- 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
        weightedLux = domoticz.utils.round(weightedLux,2)
        totalRadiation = domoticz.utils.round(totalRadiation,2)
        
		domoticz.log('CloudCover = '.. dz_cloudCover, domoticz.LOG_INFO)
		domoticz.log('Okta = '.. okta, domoticz.LOG_INFO)
		domoticz.log('Kc = ' .. Kc, domoticz.LOG_INFO)
		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_INFO)
		domoticz.log('Total radiation = ' .. totalRadiation ..' W/m²', domoticz.LOG_INFO)
		domoticz.log('Total Radiation in lux = '.. domoticz.utils.round(Lux,2)..' Lux', domoticz.LOG_INFO)
		domoticz.log('Total weighted lux  = '.. weightedLux..' 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 domoticz.devices(idxLux).lux + weightedLux > 0 then
			domoticz.devices(idxLux).updateLux(weightedLux)
		end
		domoticz.devices(idxSolarAzimuth).updateCustomSensor(domoticz.utils.round(azimuth,0))
		domoticz.devices(idxSolarAltitude).updateCustomSensor(domoticz.utils.round(sunAltitude,0))
		domoticz.devices(idxSolarRadiation).updateRadiation(totalRadiation)
	end
}
Lux values to be confirmed because there are different from a real sensor I have, but perhaps this sensor is not good !?
Hope this could help to get solar date independent from a weather provider... with some more validation
Locked

Who is online

Users browsing this forum: No registered users and 0 guests