dzvents script to replace and augment native wunderground device

Moderator: leecollings

Post Reply
Number8
Posts: 374
Joined: Friday 23 May 2014 7:55
Target OS: Linux
Domoticz version: 2022.1
Location: Saint Pierre de Jards
Contact:

dzvents script to replace and augment native wunderground device

Post by Number8 »

Hello,
Wunderground recently unplugged the original API. You'll find here a script replacing the original Domoticz Wunderground device that is not working anymore. I kept the original devices in order to keep the values history.
My API key is free of charge since I'm contributing to the network. You'll have to create your own devices to get this working and get an api key of course.
It is just too bad that Domoticz features a very limited set of forecast id. Wunderground has 47 seven of them! This is why I have 4 texte devices in order to get a full forecast description.

Code: Select all

return {
--	active = true, -- optional
	on = { 
--		timer = {'every 30 minutes'},
		timer = {'every minute'},
		httpResponses = {'wundergroundResponse', 'wundergroundResponseForecast1', 'wundergroundResponseForecast2'}
	},
--	logging = {
--		level = domoticz.LOG_INFO,
--		marker = "meteo script"
--	},
   data = {
      loop = { initial = 0 },
		wheatherForecast1 = { initial = 'noinfo'},
		wheatherForecast2 = { initial = 'noinfo'}
	},
	execute = function (domoticz, item)
-- best match with wunderground forecast unfortunately domoticz is way beyond wunderground capabilities
-- see https://docs.google.com/document/d/1dNCf6nF6cjm4oOxQxjtqNuAvG_iEe5f9MQH1xlCeV4s/edit
		local wheatherForecastTHB =	{
			[0] = 	domoticz.BARO_CLOUDY,
			[1] = 	domoticz.BARO_CLOUDY,
			[2] = 	domoticz.BARO_CLOUDY,
			[3] = 	domoticz.BARO_RAIN,
			[4] = 	domoticz.BARO_RAIN,
			[5] = 	domoticz.BARO_RAIN,
			[6] = 	domoticz.BARO_RAIN,
			[7] = 	domoticz.BARO_RAIN,
			[8] = 	domoticz.BARO_RAIN,
			[9] = 	domoticz.BARO_RAIN,
			[10] = 	domoticz.BARO_RAIN,
			[11] = 	domoticz.BARO_RAIN,
			[12] = 	domoticz.BARO_RAIN,
			[13] = 	domoticz.BARO_RAIN,
			[14] = 	domoticz.BARO_RAIN,
			[15] = 	domoticz.BARO_RAIN,
			[16] = 	domoticz.BARO_RAIN,
			[17] = 	domoticz.BARO_RAIN,
			[18] = 	domoticz.BARO_RAIN,
			[19] = 	domoticz.BARO_CLOUDY,
			[20] = 	domoticz.BARO_CLOUDY,
			[21] = 	domoticz.BARO_CLOUDY,
			[22] = 	domoticz.BARO_CLOUDY,
			[23] = 	domoticz.BARO_CLOUDY,
			[24] = 	domoticz.BARO_CLOUDY,
			[25] = 	domoticz.BARO_CLOUDY,
			[26] = 	domoticz.BARO_CLOUDY,
			[27] = 	domoticz.BARO_CLOUDY, -- shoud be BARO_PARTLY_CLOUDY (value not yey supported in this domoticz version?)
			[28] = 	domoticz.BARO_CLOUDY, -- shoud be BARO_PARTLY_CLOUDY
			[29] = 	domoticz.BARO_CLOUDY, -- shoud be BARO_PARTLY_CLOUDY
			[30] = 	domoticz.BARO_CLOUDY, -- shoud be BARO_PARTLY_CLOUDY
			[31] = 	domoticz.BARO_SUNNY,
			[32] = 	domoticz.BARO_SUNNY,
			[33] = 	domoticz.BARO_SUNNY,
			[34] = 	domoticz.BARO_SUNNY,
			[35] = 	domoticz.BARO_RAIN,
			[36] = 	domoticz.BARO_SUNNY,
			[37] = 	domoticz.BARO_RAIN,
			[38] = 	domoticz.BARO_RAIN,
			[39] = 	domoticz.BARO_RAIN,
			[40] = 	domoticz.BARO_RAIN,
			[41] = 	domoticz.BARO_RAIN,
			[42] = 	domoticz.BARO_RAIN,
			[43] = 	domoticz.BARO_RAIN,
			[44] = 	domoticz.BARO_NOINFO,
			[45] = 	domoticz.BARO_RAIN,
			[46] = 	domoticz.BARO_RAIN,
			[47] = 	domoticz.BARO_RAIN,
		}

		if (item.isTimer) then
			apiKey = 'yourpersonalapikey''
			station = 'IPAYSDEL120'
--			wunderURL = 'http://api.wunderground.com/api/' .. apiKey .. '/conditions/forecast/q/' .. station .. '.json'
			wunderURL = 'https://api.weather.com/v2/pws/observations/current?stationId=' .. station .. '&format=json&units=m&apiKey=' .. apiKey
--			domoticz.log (wunderURL)
			domoticz.openURL({
				url = wunderURL,
				callback = 'wundergroundResponse'
		   })

			station = 'ICENTRES8'
			wunderURL = 'https://api.weather.com/v2/pws/observations/current?stationId=' .. station .. '&format=json&units=m&apiKey=' .. apiKey
--			domoticz.log (wunderURL)
			domoticz.openURL({
				url = wunderURL,
				callback = 'wundergroundResponse'
		   })

			domoticz.log ('loop number : ' .. tostring(domoticz.data.loop))

			if domoticz.data.loop >= 60 then
				domoticz.log ('calling forecast')
				domoticz.data.loop = 0
				wunderURL = 'https://api.weather.com/v3/wx/forecast/daily/5day?geocode=47.097,1.966&language=fr-FR&format=json&units=m&apiKey=' .. apiKey
				domoticz.openURL({
					url = wunderURL,
					callback = 'wundergroundResponseForecast1'
			   })
				wunderURL = 'https://api.weather.com/v3/wx/forecast/daily/5day?geocode=46.721,-2.347&language=fr-FR&format=json&units=m&apiKey=' .. apiKey
				domoticz.openURL({
					url = wunderURL,
					callback = 'wundergroundResponseForecast2'
			   })

			end
		end
		if (item.isHTTPResponse) then
		   if (item.ok) then
				if item.trigger == 'wundergroundResponse' then
					if item.json.observations[1].stationID == 'IPAYSDEL120' then				
						domoticz.devices(334).updateTempHumBaro(item.json.observations[1].metric.temp,item.json.observations[1].humidity,domoticz.HUM_NORMAL,item.json.observations[1].metric.pressure,domoticz.data.wheatherForecast2)
					elseif item.json.observations[1].stationID == 'ICENTRES8' then
						domoticz.data.loop = domoticz.data.loop + 1
						windir = tonumber(item.json.observations[1].winddir)
						interval = 11.25
						if (windir >= 337.5+interval and windir < 0+interval) then
							winddir = "N"
						elseif (windir >= 22.5-interval and windir < 22.5+interval) then
							windir = "NNE"
						elseif (windir >= 45-interval and windir < 45+interval) then
							windir = "NE"
						elseif (windir >= 67.5-interval and windir < 67.5+interval) then
							windir = "ENE"
						elseif (windir >= 90-interval and windir < 90+interval) then
							windir = "E"					
						elseif (windir >= 112.5-interval and windir < 112.5+interval) then
							windir = "ESE"					
						elseif (windir >= 135-interval and windir < 135+interval) then
							windir = "SE"					
						elseif (windir >= 157.5-interval and windir < 157.5+interval) then
							windir = "SSE"					
						elseif (windir >= 180-interval and windir < 180+interval) then
							windir = "S"					
						elseif (windir >= 202.5-interval and windir < 202.5+interval) then
							windir = "SSE"					
						elseif (windir >= 225-interval and windir < 225+interval) then
							windir = "SW"					
						elseif (windir >= 247.5-interval and windir < 247.5+interval) then
							windir = "WSW"					
						elseif (windir >= 270-interval and windir < 270+interval) then
							windir = "W"					
						elseif (windir >= 292.5-interval and windir < 292.5+interval) then
							windir = "WNW"					
						elseif (windir >= 315-interval and windir < 315+interval) then
							windir = "NW"					
						elseif (windir >= 337.5-interval and windir < 337.5+interval) then
							windir = "NNW"					
						end
--						domoticz.log ('Wheather forecast : ' .. domoticz.data.wheatherForecast)
						domoticz.devices(11).updateRadiation(item.json.observations[1].solarRadiation)
		--				domoticz.devices(8).updateUV(item.json.observations[1].uv)
						domoticz.devices(9).updateRain(item.json.observations[1].metric.precipRate,item.json.observations[1].metric.precipTotal)
						domoticz.devices(7).updateWind(item.json.observations[1].winddir,windir,item.json.observations[1].metric.windSpeed/3.6,item.json.observations[1].metric.windGust/3.6,item.json.observations[1].metric.temp,item.json.observations[1].metric.windChill)
						domoticz.devices(6).updateTempHumBaro(item.json.observations[1].metric.temp,item.json.observations[1].humidity,domoticz.HUM_NORMAL,item.json.observations[1].metric.pressure,domoticz.data.wheatherForecast1)
					end
				elseif item.trigger == 'wundergroundResponseForecast1' then
					-- get icon code in order to retrieve forecast
					icon = item.json.daypart[1]['iconCode'][2]
					-- save forecast in a persistent variable. Device will be updated next round
					domoticz.data.wheatherForecast1 = wheatherForecastTHB[icon]
					domoticz.log ('new forecast 1: ' .. wheatherForecastTHB[icon])
					forecastNarrative = item.json.daypart[1]['narrative'][2]
					domoticz.devices(355).updateText(forecastNarrative)
					forecastNarrative = item.json.daypart[1]['narrative'][3]
					domoticz.devices(357).updateText(forecastNarrative)
				elseif item.trigger == 'wundergroundResponseForecast2' then
					-- get icon code in order to retrieve forecast
					icon = item.json.daypart[1]['iconCode'][2]
					-- save forecast in a persistent variable. Device will be updated next round
					domoticz.data.wheatherForecast2 = wheatherForecastTHB[icon]
					domoticz.log ('new forecast 2: ' .. wheatherForecastTHB[icon])
					-- forecast at +12h
					forecastNarrative = item.json.daypart[1]['narrative'][2]
					domoticz.devices(356).updateText(forecastNarrative)
					-- forecast at +24h
					forecastNarrative = item.json.daypart[1]['narrative'][3]
					domoticz.devices(358).updateText(forecastNarrative)
				end
		   end
		end
    end
}
Debian buster on NUC and three RPi with buster.
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 1 guest