Page 1 of 2

Cloud cover from darksky

Posted: Wednesday 07 February 2018 19:43
by aleph0
Hi All,

I made a script to grab a few more information from darksky than the darksky hardware plugin of domoticz:
- Cloud cover
- Visibility
- UV Index
- Atmospheric pressure
- Tomorrow forecast, min and max temperature (useful to warn one day in advance of adverse weather)

It's pretty straitforward and can be customized easily with more or less information. Forecast widget is of type "text"

Script LUA Time

Code: Select all

--[[ Script to get some values from darksky API
]]--

local dev_Patm ="Pression atmosphérique"    -- Atmospheric pressure
local dev_UV   ="Index UV"                  -- UV Index
local dev_Vis  ="Visibilité"                -- Visibility
local dev_Cloud="Couverture nuageuse"       -- Cloud layer
local dev_Tmin ="Température min J+1"       -- Tomorrow temperature min forecast
local dev_Tmax ="Température max J+1"       -- Tomorrow temperature max forecast
local dev_Prev ="Previsions J+1"            -- Forecast d+1

local api_key="your_api_key" -- darksky secret key
local coord="45.0,4.0"                 -- latitude,longitude

local debug=0

function UpdateDev(device,nvalue,svalues)
    --Met à jour un device numérique Domoticz
    commandArray[#commandArray+1] = {['UpdateDevice'] = otherdevices_idx[device]..'|'..tostring(nvalue)..'|'..tostring(svalues)}
end

function os.capture(cmd, raw)
    local f = assert(io.popen(cmd, 'r'))
    local s = assert(f:read('*a'))
    f:close()
    if raw then return s end
    s = string.gsub(s, '^%s+', '')
    s = string.gsub(s, '%s+$', '')
    s = string.gsub(s, '[\n\r]+', ' ')
    return s
end

commandArray = {}
time = os.date("*t")

if  ((time.min+2)%5)==0  then -- Run every 5 minutes
    -- Querying Darksky
    json = (loadfile "/opt/domoticz/scripts/lua/JSON.lua")()  -- For Linux
    result=os.capture('curl -s "https://api.darksky.net/forecast/'..api_key..'/'..coord..'?lang=fr&units=ca&exclude=hourly,flags"')
    --print(result)
    
    -- Reading values from json
    local jsonValeur = json:decode(result)
    val_Patm =jsonValeur.currently.pressure
    val_UV   =jsonValeur.currently.uvIndex
    val_Vis  =jsonValeur.currently.visibility
    val_Cloud=jsonValeur.currently.cloudCover*100
    val_Tmin =round(jsonValeur.daily.data[1].temperatureLow,1)
    val_Tmax =round(jsonValeur.daily.data[1].temperatureHigh,1)
    icon     =jsonValeur.daily.data[1].icon
    summary  =jsonValeur.daily.data[1].summary
    
    -- Converting darksky icon into domoticz forecast code
    if icon=="clear-day" or icon=="clear-night"                     then prev=1 --Sunny
    elseif icon=="rain" or icon=="snow" or rain=="sleet"            then prev=6 --Cloudy/Rain
    elseif icon=="wind" or icon=="fog"                              then prev=0 --Stable
    elseif icon=="cloudy"                                           then prev=2 --Cloudy
    elseif icon=="partly-cloudy-day" or icon=="partly-cloudy-night" then prev=3 --Unstable
    else                                                                 prev=5 --Unknown
    end
    
    forecast=summary.."<br>Min : "..val_Tmin.."°C Max : "..val_Tmax.."°C"
    
    if debug==1 then
        print("Pression : "..val_Patm)
        print("Index UV : "..val_UV)
        print("Visibilité : "..val_Vis)
        print("Couverture nuageuse : "..val_Cloud)
        print("Température min J+1 : "..val_Tmin)
        print("Température max J+1 : "..val_Tmax)
        print("Icon : "..icon.." "..prev)
        print("Summary : "..summary)
        print("Prévisions : "..forecast)
    end
    
    -- Updating domoticz devices
    UpdateDev(dev_Patm,0,val_Patm..";"..prev)
    UpdateDev(dev_UV,0,val_UV..";0")
    UpdateDev(dev_Vis,0,val_Vis)
    UpdateDev(dev_Cloud,0,val_Cloud)
    UpdateDev(dev_Tmin,0,val_Tmin)
    UpdateDev(dev_Tmax,0,val_Tmax)
    
    if otherdevices_svalues[dev_Prev] ~= forecast then UpdateDev(dev_Prev,0,forecast) end
end

return commandArray
Additionnaly, in the solar sensor script of JM Leglise, I replaced the "octa" information with this cloud layer to get more frequent and accurate update.

Comments welcome !

Re: Cloud cover from darksky

Posted: Thursday 08 February 2018 0:20
by Marci
Worked great once I’d polyfilled os.capture by adding the following at line 3...

Code: Select all

function os.capture(cmd, raw)
    local f = assert(io.popen(cmd, 'r'))
    local s = assert(f:read('*a'))
    f:close()
    if raw then return s end
    s = string.gsub(s, '^%s+', '')
    s = string.gsub(s, '%s+$', '')
    s = string.gsub(s, '[\n\r]+', ' ')
    return s
end
...thanks muchly!

Re: Cloud cover from darksky

Posted: Thursday 08 February 2018 8:55
by aleph0
Oops, you're right, I forgot this one ! Post updated !!

Re: Cloud cover from darksky

Posted: Thursday 08 February 2018 13:00
by EdwinK
Is there anything else i need to do? create devices or so to get this to work

Re: Cloud cover from darksky

Posted: Thursday 08 February 2018 13:43
by aleph0
Yes, you need to create devices beforehand, register on darksky to get an api key and paste it in the script in the api_key variable

Re: Cloud cover from darksky

Posted: Tuesday 10 April 2018 9:28
by angelus1753
I'm making my first steps in Domoticz (and LUA for that matter) and I was wondering how to marry your script with the Lux script from Leglise. Perhaps you can show your script?

Re: Cloud cover from darksky

Posted: Tuesday 01 May 2018 11:13
by hairynoggin
what are the names of the dummy switches?

also I get an error: Error: EventSystem: in cloud script: [string "--[[ Script to get some values from darksky A..."]:38: attempt to call a nil value

can anyone with knowledge let me know what is going wrong?

thanks in advance

Re: Cloud cover from darksky

Posted: Saturday 11 August 2018 0:27
by Holland
Thanks aleph0.

Mine starts to bark at line 48 and 49, the round function.
2018-08-11 00:23:01.323 Error: EventSystem: in /home/pi/domoticz/scripts/lua/script_time_weather_darksky.lua: .../pi/domoticz/scripts/lua/script_time_weather_darksky.lua:48: attempt to call global 'round' (a nil value)
I tried including the round function, but to no prevail.

Some directions would be helpful

Re: Cloud cover from darksky

Posted: Sunday 12 August 2018 21:17
by JCLB
I think that the function os.capture doesn't collect the array daily.data[x] for some reason.
same problem occurs with icon =jsonValeur.daily.data1.icon and summary =jsonValeur.daily.data1.summary

Re: Cloud cover from darksky

Posted: Monday 13 August 2018 9:20
by aleph0
Hello,

I forgot to include the round function in the script :-( Here it is, corrected

Code: Select all

--[[ Script to get some values from darksky API
]]--

local dev_Patm ="Pression atmosphérique"    -- Atmospheric pressure
local dev_UV   ="Index UV"                  -- UV Index
local dev_Vis  ="Visibilité"                -- Visibility
local dev_Cloud="Couverture nuageuse"       -- Cloud layer
local dev_Tmin ="Température min J+1"       -- Tomorrow temperature min forecast
local dev_Tmax ="Température max J+1"       -- Tomorrow temperature max forecast
local dev_Prev ="Previsions J+1"            -- Forecast d+1

local api_key="your_api_key" -- darksky secret key
local coord="45.0,4.0"                 -- latitude,longitude

local debug=0

function UpdateDev(device,nvalue,svalues)
    --Met à jour un device numérique Domoticz
    commandArray[#commandArray+1] = {['UpdateDevice'] = otherdevices_idx[device]..'|'..tostring(nvalue)..'|'..tostring(svalues)}
end

function os.capture(cmd, raw)
    local f = assert(io.popen(cmd, 'r'))
    local s = assert(f:read('*a'))
    f:close()
    if raw then return s end
    s = string.gsub(s, '^%s+', '')
    s = string.gsub(s, '%s+$', '')
    s = string.gsub(s, '[\n\r]+', ' ')
    return s
end

function round(num, dec)
    if num == 0 then
        return 0
    else
        local mult = 10^(dec or 0)
        return math.floor(num * mult + 0.5) / mult
    end
end

commandArray = {}
time = os.date("*t")

if  ((time.min+2)%5)==0  then -- Run every 5 minutes
    -- Querying Darksky
    json = (loadfile "/opt/domoticz/scripts/lua/JSON.lua")()  -- For Linux
    result=os.capture('curl -s "https://api.darksky.net/forecast/'..api_key..'/'..coord..'?lang=fr&units=ca&exclude=hourly,flags"')
    --print(result)
    
    -- Reading values from json
    local jsonValeur = json:decode(result)
    val_Patm =jsonValeur.currently.pressure
    val_UV   =jsonValeur.currently.uvIndex
    val_Vis  =jsonValeur.currently.visibility
    val_Cloud=jsonValeur.currently.cloudCover*100
    val_Tmin =round(jsonValeur.daily.data[1].temperatureLow,1)
    val_Tmax =round(jsonValeur.daily.data[1].temperatureHigh,1)
    icon     =jsonValeur.daily.data[1].icon
    summary  =jsonValeur.daily.data[1].summary
    
    -- Converting darksky icon into domoticz forecast code
    if icon=="clear-day" or icon=="clear-night"                     then prev=1 --Sunny
    elseif icon=="rain" or icon=="snow" or rain=="sleet"            then prev=6 --Cloudy/Rain
    elseif icon=="wind" or icon=="fog"                              then prev=0 --Stable
    elseif icon=="cloudy"                                           then prev=2 --Cloudy
    elseif icon=="partly-cloudy-day" or icon=="partly-cloudy-night" then prev=3 --Unstable
    else                                                                 prev=5 --Unknown
    end
    
    forecast=summary.."<br>Min : "..val_Tmin.."°C Max : "..val_Tmax.."°C"
    
    if debug==1 then
        print("Pression : "..val_Patm)
        print("Index UV : "..val_UV)
        print("Visibilité : "..val_Vis)
        print("Couverture nuageuse : "..val_Cloud)
        print("Température min J+1 : "..val_Tmin)
        print("Température max J+1 : "..val_Tmax)
        print("Icon : "..icon.." "..prev)
        print("Summary : "..summary)
        print("Prévisions : "..forecast)
    end
    
    -- Updating domoticz devices
    UpdateDev(dev_Patm,0,val_Patm..";"..prev)
    UpdateDev(dev_UV,0,val_UV..";0")
    UpdateDev(dev_Vis,0,val_Vis)
    UpdateDev(dev_Cloud,0,val_Cloud)
    UpdateDev(dev_Tmin,0,val_Tmin)
    UpdateDev(dev_Tmax,0,val_Tmax)
    
    if otherdevices_svalues[dev_Prev] ~= forecast then UpdateDev(dev_Prev,0,forecast) end
end

return commandArray

Re: Cloud cover from darksky

Posted: Monday 13 August 2018 11:13
by Holland
Thanks for your quick reply. I have included the round function.

But now errors at line 19. See below. Did you encounter that one before?

For the rest it works nicely, as variables have darksky values. It's just the last part, writing the data to the created devices.

Code: Select all

commandArray[#commandArray+1] = {['UpdateDevice'] = otherdevices_idx[device]..'|'..tostring(nvalue)..'|'..tostring(svalues)}

Code: Select all

2018-08-13 10:58:01.107 Error: EventSystem: in /home/pi/domoticz/scripts/lua/script_time_weather_darksky.lua: .../pi/domoticz/scripts/lua/script_time_weather_darksky.lua:19: attempt to concatenate field '?' (a nil value)

Re: Cloud cover from darksky

Posted: Monday 13 August 2018 11:23
by aleph0
Holland wrote: Monday 13 August 2018 11:13 But now errors at line 19. See below. Did you encounter that one before?
No, it works fine here !
Can you set local debug=1 at line 15 so that we can track which update fails ?

Re: Cloud cover from darksky

Posted: Monday 13 August 2018 11:45
by Holland
See below;

2018-08-13 11:43:01.022 Status: LUA: {"latitude":52.0,"longitude":4.0,"timezone":"Europe/Amsterdam","currently":{"time":1534153380,"summary":"Bruine","icon":"rain","precipIntensity":0.3937,"precipProbability":0.37,"precipType":"rain","temperature":21.13,"apparentTemperature":21.22,"dewPoint":16.27,"humidity":0.74,"pressure":1005.18,"windSpeed":17.14,"windGust":20.44,"windBearing":215,"cloudCover":0.54,"uvIndex":3,"visibility":11.31,"ozone":327.49},"daily":{"summary":"Pluie faible aujourd’hui et jeudi, avec des températures maximales atteignant 27°C jeudi.","icon":"rain","data":[{"time":1534111200,"summary":"Pluie faible dans la matinée et l’après-midi.","icon":"rain","sunriseTime":1534134101,"sunsetTime":1534187507,"moonPhase":0.08,"precipIntensity":0.3378,"precipIntensityMax":1.2751,"precipIntensityMaxTime":1534140000,"precipProbability":0.88,"precipType":"rain","temperatureHigh":21.97,"temperatureHighTime":1534165200,"temperatureLow":16.61,"temperatureLowTime":1534212000,"apparentTemperatureHigh":22.02,"apparentTemperatureHighTime":1534165200,"apparentTemperatureLow":16.76,"apparentTemperatureLowTime":1534212000,"dewPoint":15.71,"humidity":0.78,"pressure":1006.23,"windSpeed":7.39,"windGust":27.89,"windGustTime":1534183200,"windBearing":250,"cloudCover":0.89,"uvIndex":3,"uvIndexTime":1534154400,"visibility":14.47,"ozone":322.8,"temperatureMin":17.61,"temperatureMinTime":1534194000,"temperatureMax":21.97,"temperatureMaxTime":1534165200,"apparentTemperatureMin":17.71,"apparentTemperatureMinTime":1534194000,"apparentTemperatureMax":22.02,"apparentTemperatureMaxTime":1534165200},{"time":1534197600,"summary":"Nuages épars dans la matinée.","icon":"partly-cloudy-day","sunriseTime":1534220600,"sunsetTime":1534273787,"moonPhase":0.11,"precipIntensity":0.0254,"precipIntensityMax":0.094,"precipIntensityMaxTime":1534204800,"precipProbability":0.31,"precipType":"rain","temperatureHigh":22.59,"temperatureHighTime":1534251600,"temperatureLow":16.4,"temperatureLowTime":1534298400,"apparentTemperatureHigh":22.59,"apparentTemperatureHighTime":1534251600,"apparentTemperatureLow":16.56,"apparentTemperatureLowTime":1534298400,"dewPoint":15.05,"humidity":0.78,"pressure":1012.39,"windSpeed":14.58,"windGust":26.17,"windGustTime":1534226400,"windBearing":289,"cloudCover":0.31,"uvIndex":5,"uvIndexTime":1534244400,"visibility":16.09,"ozone":315.08,"temperatureMin":16.61,"temperatureMinTime":1534212000,"temperatureMax":22.59,"temperatureMaxTime":1534251600,"apparentTemperatureMin":16.76,"apparentTemperatureMinTime":1534212000,"apparentTemperatureMax":22.59,"apparentTemperatureMaxTime":1534251600},{"time":1534284000,"summary":"Nuages épars dans la matinée.","icon":"partly-cloudy-night","sunriseTime":1534307099,"sunsetTime":1534360066,"moonPhase":0.15,"precipIntensity":0.0025,"precipIntensityMax":0.0102,"precipIntensityMaxTime":1534334400,"precipProbability":0.07,"precipType":"rain","temperatureHigh":25.21,"temperatureHighTime":1534334400,"temperatureLow":16.67,"temperatureLowTime":1534392000,"apparentTemperatureHigh":25.21,"apparentTemperatureHighTime":1534334400,"apparentTemperatureLow":16.71,"apparentTemperatureLowTime":1534392000,"dewPoint":15.51,"humidity":0.74,"pressure":1016.71,"windSpeed":12.76,"windGust":22.98,"windGustTime":1534352400,"windBearing":235,"cloudCover":0.16,"uvIndex":5,"uvIndexTime":1534330800,"visibility":16.09,"ozone":307.17,"temperatureMin":16.4,"temperatureMinTime":1534298400,"temperatureMax":25.21,"temperatureMaxTime":1534334400,"apparentTemperatureMin":16.56,"apparentTemperatureMinTime":1534298400,"apparentTemperatureMax":25.21,"apparentTemperatureMaxTime":1534334400},{"time":1534370400,"summary":"Nuageux durant toute la journée.","icon":"partly-cloudy-day","sunriseTime":1534393599,"sunsetTime":1534446344,"moonPhase":0.18,"precipIntensity":0.1651,"precipIntensityMax":0.8077,"precipIntensityMaxTime":1534431600,"precipProbability":0.7,"precipType":"rain","temperatureHigh":26.98,"temperatureHighTime":1534420800,"temperatureLow":14.06,"temperatureLowTime":1534474800,"apparentTemperatureHigh":27.16,"apparentTemperatureHighTime":1534420800,"apparentTemperatureLow":14.06,"apparentTemperatureLowTime":1534474800,"dewPoint":14.96,"humidity":0.72,"pressure":1013.74,"windSpeed":10.8,"windGust":29.29,"windGustTime":1534399200,"windBearing":231,"cloudCover":0.49,"uvIndex":4,"uvIndexTime":1534417200,"visibility":16.09,"ozone":309.52,"temperatureMin":16.67,"temperatureMinTime":1534392000,"temperatureMax":26.98,"temperatureMaxTime":1534420800,"apparentTemperatureMin":16.71,"apparentTemperatureMinTime":1534392000,"apparentTemperatureMax":27.16,"apparentTemperatureMaxTime":1534420800},{"time":1534456800,"summary":"Nuages épars débutant dans la soirée.","icon":"partly-cloudy-night","sunriseTime":1534480098,"sunsetTime":1534532620,"moonPhase":0.22,"precipIntensity":0.0686,"precipIntensityMax":0.5258,"precipIntensityMaxTime":1534456800,"precipProbability":0.68,"precipType":"rain","temperatureHigh":21.31,"temperatureHighTime":1534510800,"temperatureLow":16.29,"temperatureLowTime":1534546800,"apparentTemperatureHigh":21.31,"apparentTemperatureHighTime":1534510800,"apparentTemperatureLow":16.29,"apparentTemperatureLowTime":1534546800,"dewPoint":11.56,"humidity":0.68,"pressure":1017.36,"windSpeed":12.05,"windGust":26.73,"windGustTime":1534467600,"windBearing":275,"cloudCover":0.42,"uvIndex":5,"uvIndexTime":1534503600,"visibility":16.09,"ozone":323.09,"temperatureMin":14.06,"temperatureMinTime":1534474800,"temperatureMax":21.31,"temperatureMaxTime":1534510800,"apparentTemperatureMin":14.06,"apparentTemperatureMinTime":1534474800,"apparentTemperatureMax":21.31,"apparentTemperatureMaxTime":1534510800},{"time":1534543200,"summary":"Nuageux durant toute la journée.","icon":"partly-cloudy-day","sunriseTime":1534566598,"sunsetTime":1534618895,"moonPhase":0.25,"precipIntensity":0.1067,"precipIntensityMax":0.16,"precipIntensityMaxTime":1534618800,"precipProbability":0.25,"precipType":"rain","temperatureHigh":21.54,"temperatureHighTime":1534608000,"temperatureLow":17.08,"temperatureLowTime":1534654800,"apparentTemperatureHigh":21.66,"apparentTemperatureHighTime":153460
2018-08-13 11:43:01.035 Status: LUA: Pression : 1005.18
2018-08-13 11:43:01.035 Status: LUA: Index UV : 3
2018-08-13 11:43:01.035 Status: LUA: Visibilité : 11.31
2018-08-13 11:43:01.035 Status: LUA: Couverture nuageuse : 54
2018-08-13 11:43:01.035 Status: LUA: Température min J+1 : 16.6
2018-08-13 11:43:01.035 Status: LUA: Température max J+1 : 22
2018-08-13 11:43:01.035 Status: LUA: Icon : rain 6
2018-08-13 11:43:01.035 Status: LUA: Summary : Pluie faible dans la matinée et l’après-midi.
2018-08-13 11:43:01.035 Status: LUA: Prévisions : Pluie faible dans la matinée et l’après-midi.
2018-08-13 11:43:01.035 Min : 16.6°C Max : 22°C

Re: Cloud cover from darksky

Posted: Monday 13 August 2018 11:56
by aleph0
Ok... it doesn't help much as everything is read correctly from darksky...

update the function "UpdateDev" with some printouts to see what it tries to do :

Code: Select all

function UpdateDev(device,nvalue,svalues)
    --Met à jour un device numérique Domoticz
    print(device,nvalue,svalues)
    commandArray[#commandArray+1] = {['UpdateDevice'] = otherdevices_idx[device]..'|'..tostring(nvalue)..'|'..tostring(svalues)}
end
Something unrelated, after you got it to work : in the line os.capture(blablabla) you can change lang=fr by lang=nl (or en or... see https://darksky.net/dev/docs for the full list) to get forecast in your own language

Re: Cloud cover from darksky

Posted: Monday 13 August 2018 12:09
by Holland
See below.

2018-08-13 12:08:01.239 Status: LUA: Pression atmosphérique
2018-08-13 12:08:01.239 Status: LUA: 0
2018-08-13 12:08:01.239 Status: LUA: 1005.14;6

And I adjusted the Darksky output to nl. Thanks !

Re: Cloud cover from darksky

Posted: Tuesday 14 August 2018 12:08
by aleph0
hmm... did you adjust all the local dev_... variables to match your domoticz device names ? I doubt you use french names for them ;-)

Re: Cloud cover from darksky

Posted: Tuesday 14 August 2018 21:58
by Holland
It's a tough one...

Actually I kept all variable names the same, simular to the devices.

Could there be a problem with the device type used? I don't know if that's critical

Re: Cloud cover from darksky

Posted: Friday 31 August 2018 18:16
by juanjogarciac
Great script.

There are a lot of possibilities in https://darksky.net/dev/docs.

One question. Is Icon a text device? Or is possible to use some graphical device?

Thank you !!

Juanjo

Re: Cloud cover from darksky

Posted: Friday 31 August 2018 19:41
by aleph0
Thanks :-)

Icon is only the text displayed next to "forecast" in the barometer widget. I didn't try to display an actual icon. If you want to do so, I suggest to have a look at the moon phase script: they can display an icon from a script. Then we need to adapt the method

Re: Cloud cover from darksky

Posted: Thursday 27 September 2018 1:06
by wergeld
I am also getting the error on running the following function:

Code: Select all

function UpdateDev(device,nvalue,svalues)
    print(device,nvalue,svalues)
    --Met à jour un device numérique Domoticz
    commandArray[#commandArray+1] = {['UpdateDevice'] = otherdevices_idx[device]..'|'..tostring(nvalue)..'|'..tostring(svalues)}
end
I have the following debug:
2018-09-26 18:58:37.578 Status: LUA: Pression : 1016.71
2018-09-26 18:58:37.579 Status: LUA: Index UV : 0
2018-09-26 18:58:37.579 Status: LUA: Visibilité : 10
2018-09-26 18:58:37.579 Status: LUA: Couverture nuageuse : 19
2018-09-26 18:58:37.579 Status: LUA: Température min J+1 : 75.4
2018-09-26 18:58:37.579 Status: LUA: Température max J+1 : 89.9
2018-09-26 18:58:37.579 Status: LUA: Icon : rain 6
2018-09-26 18:58:37.579 Status: LUA: Summary : Light rain in the evening.
2018-09-26 18:58:37.579 Status: LUA: Prévisions : Light rain in the evening.
2018-09-26 18:58:37.579 Min : 75.4°C Max : 89.9°C


2018-09-26 18:58:37.579 Status: LUA: Cloud Layer
2018-09-26 18:58:37.579 Status: LUA: 0
2018-09-26 18:58:37.579 Status: LUA: 19
I am not really sure what it is complaining about here.