logo

Weerlive api for Domoticz via dzVents

Wed June 26th 26 2019

With weather underground stopping api access and dark_sky being somehow less reliable, I wanted another option. I already have buienradar in Domoticz see Domoticz forum. I found weerlive.nl. The good thing is this is from KNMI (dutch weather office) and they are happy to share:

Deze API is bedoeld voor privégebruik en studiedoeleinden. Je mag deze gebruiken op iedere manier die je wil, als je een link terug maakt naar deze pagina (mag klein): iets als “KNMI Weergegevens via Weerlive.nl”

Create dzVents script at setup -> events, add the apikey from weerlive.nl api key, add the location you want to monitor and it should work.

-- KNMI weerlive.nl for domoticz
-- KNMI Weergegevens via Weerlive.nl
-- http://weerlive.nl/delen.php
-- add Domoticz forum link later
-- 2019-06-19 initial version

local apiKey = "enter your weerlive.nl apikey here"
local location = "enter your city or lat,lon here"

-- create below devices in Domoticz
-- creat dummy hardware device WEERLIVE and add:
local wind = 'weerlive wind'        -- wind
local baro = 'weerlive barometer'   -- Temp + Humidity + Baro
local text = 'weerlive'             -- text
local verw = 'weerlive verwachting' -- text
local vis  = 'weerlive visibility'  -- visibility
local twind = 'weerlive twind'      -- text
local alarm = 'weerlive alarm'      -- text

return {
    logging = { 
            -- level = domoticz.LOG_DEBUG -- comment when not in dev
        },
    on = {
        timer = { 'every 5 minutes' },
        httpResponses = { 'get_weerlive' },
    },
    execute = function(dz, item) 
        if item.isTimer then
            dz.log('weerlive started by trigger: ' .. item.trigger, dz.LOG_INFO)

            dz.openURL({
                url = 'http://weerlive.nl/api/json-data-10min.php?key=' .. apiKey .. '&locatie=' .. location,
                method='GET',
                callback='get_weerlive'
            })
        elseif item.isHTTPResponse then

            dz.log('HTTPResponse event was triggered by ' .. item.trigger, dz.LOG_INFO)

            if (not item.ok or not item.isJSON) then
                dz.log('buienRadar call failed', dz.log_ERROR)
                dz.log('responseOK: ' .. tostring(item.ok), dz.LOG_INFO)
                dz.log('statusCode: ' .. item.statusCode, dz.LOG_INFO)
                dz.log('statusText: ' .. item.statusText, dz.LOG_INFO)
                dz.log('json: ', dz.LOG_INFO)
                dz.log(item.json, dz.LOG_INFO)
                return
            end

            if ( not item.json["liveweer"] ) then
                dz.log('weerlive data missing liveweer', dz.LOG_ERROR)
                return
            end

            local wr = { "Noord", "NNO", "NO", "ONO", "Oost", "OZO", "ZO", "ZZO", 
                "Zuid", "ZZW", "ZW", "WZW", "West", "WNW", "NW", "NNW" }            
            function w2d(w)
                for i,v in pairs(wr) do
                    if v == w then
                        return(22.5*(i-1))
                    end
                end
            end          
            function w2e(w)
                local we = { "N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE",
                    "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW" }
                for i,v in pairs(wr) do
                    if v == w then
                        return we[i]
                    end
                end
            end


            local wl = item.json["liveweer"][1]
            dz.devices(wind).updateWind(w2d(wl["windr"]),w2e(wl["windr"]),
                wl['windms'],0,wl['temp'],wl['gtemp'])

            function lvstat(lv)
                lv = tonumber(lv)
                if lv < 35 then return dz.HUM_DRY
                elseif 35 < lv and lv < 45 then return dz.HUM_NORMAL
                elseif 45 < lv and lv < 55 then return dz.HUM_COMFORTABLE
                elseif 55 < lv and lv < 65 then return dz.HUM_NORMAL
                else return dz.HUM_WET
                end
            end
            -- dz.BARO_CLOUDY, dz.PARTLYCLOUDY, dz.BARO_STABLE, dz.BARO_SUNNY, 
            -- dz.BARO_THUNDERSTORM, dz.BARO_NOINFO, dz.BARO_UNSTABLE, 
            -- dz.BARO_RAIN
            function ic2fc(ic) 
                if ic == "zonnig" or ic =="helderenacht" then return dz.BARO_SUNNY
                elseif ic == "halfbewolkt" or ic == "mist" 
                    or ic == "nachtmist" then return dz.BARO_PARTLYCLOUDY
                elseif ic == "bewolkt" or ic == "zwaarbewolkt" 
                    or ic == "wolkennacht" then return dz.BARO_CLOUDY
                elseif ic == "regen" or ic == "buien" or ic == "hagel" 
                    or ic == "sneeuw" then return dz.BARO_RAIN
                elseif ic == "bliksem" then return dz.BARO_THUNDERSTORM
                else 
                    dz.log('unknown icon: ' .. ic, dz.LOG_ERROR)
                    return BARO_NOINFO
                end
            end
            dz.devices(baro).updateTempHumBaro(wl["temp"],wl["lv"], 
                lvstat(wl["lv"]), wl['luchtd'], ic2fc(wl['image']))

            local t = nil
            t = wl["samenv"]
            if dz.devices(text).text ~= t then 
                dz.devices(text).updateText(t)
            end
            t = wl["verw"]
            if dz.devices(verw).text ~= t then
                dz.devices(verw).updateText(t)
            end

            dz.devices(vis).updateVisibility(wl['zicht'])

            t = wl["windr"] .. ' ' .. wl["winds"] .. ' Bft'
            if dz.devices(twind).text ~= t then
                dz.devices(twind).updateText(t)
            end

            if wl["alarm"] == "0" then
                t = "no alarms"
            else
                t = wl['alarm'] .. ': ' .. wl['alarmtxt']
            end
            if dz.devices(alarm) ~= t then
                dz.devices(alarm).updateText(t)
            end



        end
    end
}