dzVents version of the Solar Data Script  [SOLVED]

Moderator: leecollings

Locked
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: dzVents version of the Solar Data Script

Post by waaren »

roblom wrote: Sunday 02 June 2019 20:54 Is it just me or is this script not working anymore because the Wundergound stopped with the use of the API?
https://apicommunity.wunderground.com/w ... ground-api
Only real usage of the Wunderground api in this script is for local barometer pressure. You could use another local (domoticz) barometer or switch to darkSky.
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
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

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"
Somehow I hadn't updated the script, therefore the mentioned 'elseif sunAltitude <= 1 and sunAltitude >= -7 then -- apply theoretical Lux of twilight' was not in my script, causing 'nil' values when sunaltitude was indeed beteen 1 and -7. I finally got disgusted in the error messages and checked out my script file. It's OK now.

However, (although I didn't check it now) I believe the AND statement in an if/elseif should be between brackets:

Code: Select all

elseif (sunAltitude <= 1 and sunAltitude >= -7)
. I don't see that in the script of the first post.
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: dzVents version of the Solar Data Script

Post by waaren »

jake wrote: Sunday 27 October 2019 0:17 However, (although I didn't check it now) I believe the AND statement in an if/elseif should be between brackets:

Code: Select all

elseif (sunAltitude <= 1 and sunAltitude >= -7)
.
This is not the case. Only required use of brackets in a Lua if -, else - or elseif evaluation is to change default precedence (which is from left to right and standard calculation precedence )
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
HFman
Posts: 82
Joined: Thursday 02 March 2017 20:28
Target OS: Linux
Domoticz version: V4.1174
Location: Netherlands
Contact:

Re: dzVents version of the Solar Data Script

Post by HFman »

waaren wrote: Sunday 02 June 2019 21:16
roblom wrote: Sunday 02 June 2019 20:54 Is it just me or is this script not working anymore because the Wundergound stopped with the use of the API?
https://apicommunity.wunderground.com/w ... ground-api
Only real usage of the Wunderground api in this script is for local barometer pressure. You could use another local (domoticz) barometer or switch to darkSky.
But Darksky doesn't have Lux right ? This is the one i still miss at every alternative ...
Raspberry PI 3 - Opentherm Gateway + ESP8826 - EvoHome - ESPEasy CO2 + Fancontrol - RF-Link - zigbee2mqqt -
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: dzVents version of the Solar Data Script

Post by waaren »

HFman wrote: Sunday 27 October 2019 8:35 But Darksky doesn't have Lux right ? This is the one i still miss at every alternative ...
Probably because Lux is very depending on your exact location. One small cloud between your location and the sun has a very big influence.
The new Buienradar hardware type does offer Sun power in watts / m2. Would that help you ?
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
HFman
Posts: 82
Joined: Thursday 02 March 2017 20:28
Target OS: Linux
Domoticz version: V4.1174
Location: Netherlands
Contact:

Re: dzVents version of the Solar Data Script  [SOLVED]

Post by HFman »

Yeah... Great thanks that is excatly what i need !
Raspberry PI 3 - Opentherm Gateway + ESP8826 - EvoHome - ESPEasy CO2 + Fancontrol - RF-Link - zigbee2mqqt -
deennoo
Posts: 784
Joined: Wednesday 10 December 2014 13:06
Target OS: Linux
Domoticz version: beta
Location: Bordeaux France
Contact:

Re: dzVents version of the Solar Data Script

Post by deennoo »

oredin wrote: Monday 01 April 2019 10:19
Derik wrote: Sunday 31 March 2019 12:21
gimic wrote: Sunday 31 March 2019 12:18 i have it in Watt/m2
And how must i see this value??
Power watt /m²
Or what can i do with this value
Hi,

This value is only used as a step for the whole computation and to compute the Lux value.

If you want to know more about it, look for Solar irradiance.
Hello,

I'm facing a probleme : LUX Value Is crazy :

Code: Select all

UpdateMeter: Error converting sValue/sUsage! (IDX: 19493, sValue: '4937972264600400208183447097222515965420472634484228007257426547208404256159892098951988747359340880352772096', sUsage: '0', dType: 246, sType: 1)
Value to get this :

Code: Select all

2020-05-09 15:45:11.750 Status: dzVents: Info: solarData 2.4.1-DarkSky: ============== SUN LOG ==================
2020-05-09 15:45:11.750 Status: dzVents: Info: solarData 2.4.1-DarkSky: Martillac latitude: 44.712698, longitude: -0.543056
2020-05-09 15:45:11.750 Status: dzVents: Debug: solarData 2.4.1-DarkSky: Home altitude = 40 m
2020-05-09 15:45:11.750 Status: dzVents: Debug: solarData 2.4.1-DarkSky: Angular Speed = 0.98562628336756 per day
2020-05-09 15:45:11.750 Status: dzVents: Debug: solarData 2.4.1-DarkSky: Declination = 17.711758872199°
2020-05-09 15:45:11.750 Status: dzVents: Debug: solarData 2.4.1-DarkSky: Universal Coordinated Time (UTC) 13.75 H.dd
2020-05-09 15:45:11.750 Status: dzVents: Debug: solarData 2.4.1-DarkSky: Solar Hour 13.713796266667 H.dd
2020-05-09 15:45:11.750 Status: dzVents: Info: solarData 2.4.1-DarkSky: Altitude of the sun = 55.486909377782°
2020-05-09 15:45:11.750 Status: dzVents: Debug: solarData 2.4.1-DarkSky: Angular hourly = -25.706944°
2020-05-09 15:45:11.750 Status: dzVents: Info: solarData 2.4.1-DarkSky: Azimuth of the sun = 226.82624786338°
2020-05-09 15:45:11.750 Status: dzVents: Debug: solarData 2.4.1-DarkSky: Duration of the sun stroke of the day = 14.46 H.dd
2020-05-09 15:45:11.750 Status: dzVents: Debug: solarData 2.4.1-DarkSky: Radiation max in atmosphere = 1332.59 W/m²
2020-05-09 15:45:11.750 Status: dzVents: Debug: solarData 2.4.1-DarkSky: Local relative pressure = 999.90002441406 hPa
2020-05-09 15:45:11.750 Status: dzVents: Debug: solarData 2.4.1-DarkSky: Absolute pressure in atmosphere = 995.10002441406 hPa
2020-05-09 15:45:11.750 Status: dzVents: Debug: solarData 2.4.1-DarkSky: Coefficient of mitigation M = -467.60921288158 M0 = -465.36446423969
2020-05-09 15:45:11.750 Status: dzVents: Info: solarData 2.4.1-DarkSky:
2020-05-09 15:45:11.750 Status: dzVents: Debug: solarData 2.4.1-DarkSky: Using the newly fetched cloud cover value: 0.52 with UTC timestamp: 1589031911
2020-05-09 15:45:11.750 Status: dzVents: Info: solarData 2.4.1-DarkSky: Okta = 0.52
2020-05-09 15:45:11.750 Status: dzVents: Debug: solarData 2.4.1-DarkSky: Kc = 0.91881559132433
2020-05-09 15:45:11.750 Status: dzVents: Info: solarData 2.4.1-DarkSky: Direct Radiation = 6.0137127581757e+106 W/m²
2020-05-09 15:45:11.750 Status: dzVents: Debug: solarData 2.4.1-DarkSky: Scattered Radiation = -1.7680315509037e+106 W/m²
2020-05-09 15:45:11.750 Status: dzVents: Debug: solarData 2.4.1-DarkSky: Total radiation = 4.2456812072721e+106 W/m²
2020-05-09 15:45:11.750 Status: dzVents: Debug: solarData 2.4.1-DarkSky: Total Radiation in lux = 5.3742800092051e+108 Lux
2020-05-09 15:45:11.750 Status: dzVents: Info: solarData 2.4.1-DarkSky: Total weighted lux = 4.9379722646004e+108 Lux
2020-05-09 15:45:11.751 Status: dzVents: Debug: solarData 2.4.1-DarkSky: Processing device-adapter for Luminosite Exterieur: Lux device adapter
2020-05-09 15:45:11.751 Status: dzVents: Debug: solarData 2.4.1-DarkSky: Processing device-adapter for Azimute Soleil: Custom sensor device adapter
2020-05-09 15:45:11.751 Status: dzVents: Debug: solarData 2.4.1-DarkSky: Processing device-adapter for Elevation soleil: Custom sensor device adapter
2020-05-09 15:45:11.752 Status: dzVents: Debug: solarData 2.4.1-DarkSky: Processing device-adapter for Couverture Nuageuse: Percentage device adapter
I don't know what's happen

From Darksky API :

Code: Select all

{
latitude: 44.712698,
longitude: -0.543056,
timezone: "Europe/Paris",
currently: {
time: 1589032896,
summary: "Faibles Passages Nuageux",
icon: "partly-cloudy-day",
precipIntensity: 0.0075,
precipProbability: 0.03,
precipType: "rain",
temperature: 26.52,
apparentTemperature: 26.54,
dewPoint: 15.29,
humidity: 0.5,
pressure: 1007.8,
windSpeed: 12.36,
windGust: 16.14,
windBearing: 111,
cloudCover: 0.47,
uvIndex: 5,
visibility: 16.093,
ozone: 347.1
},
offset: 2
}
Domoticz stable 3.5877 for real & Domoticz beta for test
Rfxtrxe / RFLink / Milight / Yeelight / Tasmota / MQTT / BLE / Zigate
http://domo-attitude.fr
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 »

Hi,

I'll try to check the operations made to compute this value :o :shock:

It only appeared when you updated the script after my last correction this week-end ?

Regards
deennoo
Posts: 784
Joined: Wednesday 10 December 2014 13:06
Target OS: Linux
Domoticz version: beta
Location: Bordeaux France
Contact:

Re: dzVents version of the Solar Data Script

Post by deennoo »

oredin wrote: Monday 11 May 2020 12:01

It only appeared when you updated the script after my last correction this week-end ?

nope this kind of value come 4/3 mounth ago
Domoticz stable 3.5877 for real & Domoticz beta for test
Rfxtrxe / RFLink / Milight / Yeelight / Tasmota / MQTT / BLE / Zigate
http://domo-attitude.fr
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 »

Ok, I'll check it out this week end.

Regards
gawel31
Posts: 10
Joined: Friday 11 July 2014 17:18
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: dzVents version of the Solar Data Script

Post by gawel31 »

hi,
this DZvents script was working on my old raspberry. I changed my raspberry (raspberry pi 4 and new raspberry pi os) and now it doesn't work.
Logs:

Code: Select all

 2020-12-17 13:15:11.096 Status: dzVents: Info: solarData 2.4.1-DarkSky:
2020-12-17 13:15:11.096 Status: dzVents: Info: solarData 2.4.1-DarkSky: ============== SUN LOG ==================
2020-12-17 13:15:11.096 Status: dzVents: Info: solarData 2.4.1-DarkSky: Bayonnelatitude: 43.492949, longitude: -1.474841
2020-12-17 13:15:11.096 Status: dzVents: Info: solarData 2.4.1-DarkSky: Altitude of the sun = 23.077528353196�
2020-12-17 13:15:11.096 Status: dzVents: Info: solarData 2.4.1-DarkSky: Azimuth of the sun = 182.2697185954�
2020-12-17 13:15:11.096 Status: dzVents: Info: solarData 2.4.1-DarkSky:
2020-12-17 13:15:11.096 Status: dzVents: !Info: solarData 2.4.1-DarkSky: Function math.pow(x, y) has been deprecated in Lua 5.3. Please consider changing code to x^y
2020-12-17 13:15:11.096 Status: dzVents: !Info: solarData 2.4.1-DarkSky: Function math.pow(x, y) has been deprecated in Lua 5.3. Please consider changing code to x^y
2020-12-17 13:15:11.096 Status: dzVents: !Info: solarData 2.4.1-DarkSky: Function math.pow(x, y) has been deprecated in Lua 5.3. Please consider changing code to x^y
2020-12-17 13:15:11.096 Status: dzVents: Info: solarData 2.4.1-DarkSky: Okta = 0.68
2020-12-17 13:15:11.096 Status: dzVents: Info: solarData 2.4.1-DarkSky: Direct Radiation = 150.14 W/m�
2020-12-17 13:15:11.096 Status: dzVents: Info: solarData 2.4.1-DarkSky: Total weighted lux = 25789.56 Lux
2020-12-17 13:15:11.108 Status: dzVents: Info: solarData 2.4.1-DarkSky: ------ Finished solarData.lua 
So it seems to calculate...but i also have:

Code: Select all

 2020-12-17 12:45:11.308 Error: dzVents: Error: (3.0.2) solarData 2.4.1-DarkSky: An error occurred when calling event handler solarData
2020-12-17 12:45:11.308 Error: dzVents: Error: (3.0.2) solarData 2.4.1-DarkSky: /home/pi/domoticz/scripts/dzVents/scripts/solarData.lua:196: attempt to perform arithmetic on a nil value (field 'lux') 
an my devices doesn't update;
Do you know what is the problem?
thanks
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: dzVents version of the Solar Data Script

Post by waaren »

gawel31 wrote: Thursday 17 December 2020 13:31

Code: Select all

 2020-12-17 12:45:11.308 Error: dzVents: Error: (3.0.2) solarData 2.4.1-DarkSky: An error occurred when calling event handler solarData
2020-12-17 12:45:11.308 Error: dzVents: Error: (3.0.2) solarData 2.4.1-DarkSky: /home/pi/domoticz/scripts/dzVents/scripts/solarData.lua:196: attempt to perform arithmetic on a nil value (field 'lux') 
I looked at a couple of versions but do not see a version with the string lux in line 196
Can you share the script that generates this error?
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
gawel31
Posts: 10
Joined: Friday 11 July 2014 17:18
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: dzVents version of the Solar Data Script

Post by gawel31 »

here is the script:

Code: Select all

--[[
	Prerequisits
	==================================
	Requires Domoticz v3.8551 or later
	Platform independent

	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.
	V2.4.1-DarkSky - oredin - Use Dark Sky API instead of WU API
]]--

-- Variables to customize ------------------------------------------------
local city = 'Bayonne'					-- Only for log purpose
local countryCode = 'FR'							-- Only for log purpose
local idxSolarAzimuth = 199						-- (Integer) Virtual Azimuth Device ID
local idxSolarAltitude = 200					-- (Integer) Your virtual Solar Altitude Device ID
local dsAPIkey = ''		-- Dark Sky API Key
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 fetchIntervalDayMins = 15 -- Day time scraping interval. Never set this below 4 if you have a free WU API account.
local fetchIntervalNightMins = 30 -- Night time scraping interval. 

-- Optional Domoticz devices
local idxLux = 198 -- (Integer) Domoticz virtual Lux device ID
local idxCloudCover = 336 -- (Integer) Domoticz Cloud Cover (PERCENTAGE TYPE) sensor device ID
local idxPressure = nil -- (Integer) Your Pressure Device ID. if you don't have one, the pressure value will be retrieve from Dark Sky API

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


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

local scriptName = 'solarData'
local scriptVersion = '2.4.1-DarkSky'

return {
	active = true,
	logging = {
		-- level = domoticz.LOG_DEBUG, -- Uncomment to override the dzVents global logging setting
		marker = scriptName..' '..scriptVersion
	},
	on = {
		timer = {
			'every '..tostring(fetchIntervalDayMins)..' minutes at daytime',
			'every '..tostring(fetchIntervalNightMins)..' minutes at nighttime',
		},
		httpResponses = {
			scriptName..'DS',
		},
	},
	data = {
		lastOkta = {initial=0}
	},
	execute = function(domoticz, item)

		if item.isTimer then
			local url = 'https://api.darksky.net/forecast/'..dsAPIkey..'/'..latitude..','..longitude..'?exclude=minutely,hourly,daily,alerts,flags&lang=fr&units=ca'
			domoticz.log('Requesting new weather data from Dark Sky API...', domoticz.LOG_DEBUG)
			domoticz.log('URL used: '..url, domoticz.LOG_DEBUG)
			domoticz.openURL({url = url, method = 'GET', callback = scriptName..'DS'}).afterSec(10)
		end

		if not item.isHTTPResponse then return end
        	local response = item
        
		if response.trigger ~= scriptName..'DS' then return end
		domoticz.log('Dark Sky API json data has been received', domoticz.LOG_DEBUG)

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

		local dsAPIData = response.json
		if not dsAPIData then
			domoticz.log('Could not find any dsAPIData in the DS API response', domoticz.LOG_ERROR)
			return
		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²

		-- In case of that latitude, longitude and altitude has not been defined in the configuration,
		-- we simply use the values that is returned for the current observation location.
		-- Reading longitude, latitude and altitude from the observation_location instead of from 
		-- display_location. API documentation is not so clear about what display_location is.
		if not latitude then
		    domoticz.log('You must change the latitude value !', domoticz.LOG_ERROR)
		    return
		end
		if not longitude then
		    domoticz.log('You must change the longitude value !', domoticz.LOG_ERROR)
		    return
		end
		if not altitude then
		    domoticz.log('You must change the altitude value !', domoticz.LOG_ERROR)
		    return
		end

		local relativePressure = dsAPIData.currently.pressure -- if you have an another way to get the Pressure, (local barometer ...) then you may optimize the script
		if idxPressure and domoticz.devices(idxPressure).barometer then
		    relativePressure = domoticz.devices(idxPressure).barometer
		end

		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)
		domoticz.log('', domoticz.LOG_INFO)

		local okta = dsAPIData.currently.cloudCover
		-- We store the last fetched value here to be used as a backup value
		domoticz.log('Using the newly fetched cloud cover value: '..okta..' with UTC timestamp: '..dsAPIData.currently.time, domoticz.LOG_DEBUG)
		domoticz.data.lastOkta = okta

		local Kc = 1-0.75*math.pow(okta,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

		domoticz.log('Okta = '..okta, 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_DEBUG)
		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
		domoticz.devices(idxSolarAzimuth).updateCustomSensor(domoticz.utils.round(azimuth,0))
		domoticz.devices(idxSolarAltitude).updateCustomSensor(domoticz.utils.round(sunAltitude,0))
		local oktaPercent = domoticz.utils.round(okta*100)
		local fetchIntervalMins = (domoticz.time.matchesRule('at daytime') and fetchIntervalDayMins or fetchIntervalNightMins)
		if idxCloudCover and ((domoticz.devices(idxCloudCover).percentage ~= oktaPercent)
		or (domoticz.devices(idxCloudCover).lastUpdate.minutesAgo >= (60 - fetchIntervalMins))) then
			domoticz.devices(idxCloudCover).updatePercentage(oktaPercent)
		end 

		if logToFile then
			local logDebug = os.date('%Y-%m-%d %H:%M:%S',os.time())
			logDebug=logDebug..' Azimuth:' .. azimuth .. ' Height:' .. sunAltitude
			logDebug=logDebug..' cloud cover:' .. 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
}
Last edited by gawel31 on Thursday 17 December 2020 23:02, edited 1 time in total.
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: dzVents version of the Solar Data Script

Post by waaren »

gawel31 wrote: Thursday 17 December 2020 19:14 here is the script:
I suspect the device with id 198 is either not activated, -not a lux device or none existent.
If you replace the script with below one, it will give some extra details in the log on what is going wrong.

Code: Select all

--[[
	Prerequisits
	==================================
	Requires Domoticz v3.8551 or later
	Platform independent

	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.
	V2.4.1-DarkSky - oredin - Use Dark Sky API instead of WU API
]]--

-- Variables to customize ------------------------------------------------
local city = 'Bayonne'					-- Only for log purpose
local countryCode = 'FR'							-- Only for log purpose
local idxSolarAzimuth = 199						-- (Integer) Virtual Azimuth Device ID
local idxSolarAltitude = 200					-- (Integer) Your virtual Solar Altitude Device ID
local dsAPIkey = 'xxxxxxxxxxxxxxxxxxxx'		-- Dark Sky API Key
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 fetchIntervalDayMins = 15 -- Day time scraping interval. Never set this below 4 if you have a free WU API account.
local fetchIntervalNightMins = 30 -- Night time scraping interval. 

-- Optional Domoticz devices
local idxLux = 198 -- (Integer) Domoticz virtual Lux device ID
local idxCloudCover = 336 -- (Integer) Domoticz Cloud Cover (PERCENTAGE TYPE) sensor device ID
local idxPressure = nil -- (Integer) Your Pressure Device ID. if you don't have one, the pressure value will be retrieve from Dark Sky API

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


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

local scriptName = 'solarData'
local scriptVersion = '2.4.1-DarkSky'

return {
	active = true,
	logging = {
		-- level = domoticz.LOG_DEBUG, -- Uncomment to override the dzVents global logging setting
		marker = scriptName..' '..scriptVersion
	},
	on = {
		timer = {
			'every '..tostring(fetchIntervalDayMins)..' minutes at daytime',
			'every '..tostring(fetchIntervalNightMins)..' minutes at nighttime',
		},
		httpResponses = {
			scriptName..'DS',
		},
	},
	data = {
		lastOkta = {initial=0}
	},
	execute = function(domoticz, item)

		if item.isTimer then
			local url = 'https://api.darksky.net/forecast/'..dsAPIkey..'/'..latitude..','..longitude..'?exclude=minutely,hourly,daily,alerts,flags&lang=fr&units=ca'
			domoticz.log('Requesting new weather data from Dark Sky API...', domoticz.LOG_DEBUG)
			domoticz.log('URL used: '..url, domoticz.LOG_DEBUG)
			domoticz.openURL({url = url, method = 'GET', callback = scriptName..'DS'}).afterSec(10)
		end

		if not item.isHTTPResponse then return end
			local response = item
		
		if response.trigger ~= scriptName..'DS' then return end
		domoticz.log('Dark Sky API json data has been received', domoticz.LOG_DEBUG)

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

		local dsAPIData = response.json
		if not dsAPIData then
			domoticz.log('Could not find any dsAPIData in the DS API response', domoticz.LOG_ERROR)
			return
		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²

		-- In case of that latitude, longitude and altitude has not been defined in the configuration,
		-- we simply use the values that is returned for the current observation location.
		-- Reading longitude, latitude and altitude from the observation_location instead of from 
		-- display_location. API documentation is not so clear about what display_location is.
		if not latitude then
			domoticz.log('You must change the latitude value !', domoticz.LOG_ERROR)
			return
		end
		if not longitude then
			domoticz.log('You must change the longitude value !', domoticz.LOG_ERROR)
			return
		end
		if not altitude then
			domoticz.log('You must change the altitude value !', domoticz.LOG_ERROR)
			return
		end

		local relativePressure = dsAPIData.currently.pressure -- if you have an another way to get the Pressure, (local barometer ...) then you may optimize the script
		if idxPressure and domoticz.devices(idxPressure).barometer then
			relativePressure = domoticz.devices(idxPressure).barometer
		end

		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)
		domoticz.log('', domoticz.LOG_INFO)

		local okta = dsAPIData.currently.cloudCover
		-- We store the last fetched value here to be used as a backup value
		domoticz.log('Using the newly fetched cloud cover value: '..okta..' with UTC timestamp: '..dsAPIData.currently.time, domoticz.LOG_DEBUG)
		domoticz.data.lastOkta = okta

		local Kc = 1-0.75*math.pow(okta,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

		domoticz.log('Okta = '..okta, 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_DEBUG)
		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) then
			local myLux = domoticz.devices(idxLux)
			
			local logMessage = '\n'
			logMessage = logMessage .. '\nDevice: '  .. myLux.name 
			logMessage = logMessage .. '\ntype: '    .. myLux.deviceType
			logMessage = logMessage .. '\nsubtype: ' .. myLux.deviceSubType
			logMessage = logMessage .. '\nnvalue: '  .. myLux.nValue
			logMessage = logMessage .. '\nsvalue: '  .. myLux.sValue
			logMessage = logMessage .. '\nlux: '     .. tostring(myLux.lux)

			domoticz.log(logMessage, domoticz.LOG_FORCE)

			if myLux.lux then 
				if ( myLux.lux + domoticz.utils.round(weightedLux)) > 0 then
					myLux.updateLux(domoticz.utils.round(weightedLux)).silent()
				end
			else
				domoticz.log('Device with idx ' .. idxLux  .. ' is not a lux type device!', domoticz.LOG_ERROR)
			end
		else
			domoticz.log('Device with idx ' .. idxLux  .. ' does not exist or is not active!', domoticz.LOG_ERROR)
		end
		
		domoticz.devices(idxSolarAzimuth).updateCustomSensor(domoticz.utils.round(azimuth,0))
		domoticz.devices(idxSolarAltitude).updateCustomSensor(domoticz.utils.round(sunAltitude,0))
		local oktaPercent = domoticz.utils.round(okta*100)
		local fetchIntervalMins = (domoticz.time.matchesRule('at daytime') and fetchIntervalDayMins or fetchIntervalNightMins)
		if idxCloudCover and ((domoticz.devices(idxCloudCover).percentage ~= oktaPercent)
		or (domoticz.devices(idxCloudCover).lastUpdate.minutesAgo >= (60 - fetchIntervalMins))) then
			domoticz.devices(idxCloudCover).updatePercentage(oktaPercent)
		end 

		if logToFile then
			local logDebug = os.date('%Y-%m-%d %H:%M:%S',os.time())
			logDebug=logDebug..' Azimuth:' .. azimuth .. ' Height:' .. sunAltitude
			logDebug=logDebug..' cloud cover:' .. 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
}
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
gawel31
Posts: 10
Joined: Friday 11 July 2014 17:18
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: dzVents version of the Solar Data Script

Post by gawel31 »

It's OK! i made a mistake...my device was not a lux device.... Thanks a lot! ;)
jmleglise
Posts: 192
Joined: Monday 12 January 2015 23:27
Target OS: Raspberry Pi / ODroid
Domoticz version: 2022.1
Location: FRANCE
Contact:

Re: dzVents version of the Solar Data Script

Post by jmleglise »

░██████╗████████╗░█████╗░██████╗░
██╔════╝╚══██╔══╝██╔══██╗██╔══██╗
╚█████╗░░░░██║░░░██║░░██║██████╔╝
░╚═══██╗░░░██║░░░██║░░██║██╔═══╝░
██████╔╝░░░██║░░░╚█████╔╝██║░░░░░
╚═════╝░░░░╚═╝░░░░╚════╝░╚═╝░░░░░

Please stop using this old thread. The new one is here : https://domoticz.com/forum/viewtopic.php?f=72&t=35541
My script : https://github.com/jmleglise
RFXTRX433E: Blind Somfy RTS, Portal Somfy Evolvia, chacon IO, Oregon, PIR sensor PT2262
My Last project : Location de vacances a Ouistreham vue mer
KMTronic USB relay
Chinese Z-WAVE: Neo CoolCam
Locked

Who is online

Users browsing this forum: No registered users and 1 guest