I give you the wUnderScraper!

Moderator: leecollings

Post Reply
BakSeeDaa
Posts: 485
Joined: Thursday 17 September 2015 10:13
Target OS: Raspberry Pi / ODroid
Domoticz version:

I give you the wUnderScraper!

Post by BakSeeDaa »

Here is a Weather Underground Scraper using the new features of dzVents 2.4

I'm aware there is also a plugin that makes something similar. I haven't tried it though. This is for you who wants to do it the dzVents way and have full control over whats going on. You will also be able to fetch forecasts.

This script requires dzVents 2.4

It comes with no documentation and because I will not hang around here any longer, it also comes without my support. You can use it if you like it and if you can understand how it works.

Hint: You should start with modifying the configuration script and create Domoticz devices for each sensor that you'd like to enable. Be extremely observant to create the Domoticz devices by the exact name that is in the config file, otherwise it will not work.

Sorry for not being able to give you any support. Maybe someone else like to take over the script. That would be perfectly OK with me.

Happy day!

wUnderScraperConfig.lua

Code: Select all

--[[
Edit this file suit your needs 
Place this file in the dzVents scripts folder using the name wUnderScraperConfig.lua

Using Weather API at http://api.wunderground.com/weather/api/d/docs

After editing always verify that it's valid LUA at http://codepad.org/ (Mark your paste as "Private"!!!)
--]]

local _C = {}

-- Variables you should customize are below

_C.location = 'Paris' -- City/location used for Wunderground API (You can also use a pws here like 'pws:ISTOCKHO854')
_C.countryCode = 'FR' -- Country code. See http://api.wunderground.com/weather/api/d/docs?d=resources/country-to-iso-matching
_C.wuAPIkey = 'XXXXXXXXXXX' -- Weather Underground API Key
_C.wuLang = 'EN' -- 'EN' Language for the API to return. See http://api.wunderground.com/weather/api/d/docs?d=language-support
_C.wuUseMetric = true -- Set to true for Metric. Set to false for Imperial. 

-- Uncomment only those devices that you wish to use in your system
-- You need a virtual Domoticz sensor for each entry that you intent to use and
-- each device must be of the correct Domoticz device type of course. 
-- You might want to create these devices on a dedicated virtual hardware device named "WU"
-- or something similar although it's not necessary to do that.
_C.domoWeatherDevices = {
	['Barometer'] = {['enabled'] = true, ['sensorType'] = 'C_BARO'},
	['Weather'] = {['enabled'] = true, ['sensorType'] = 'C_CONDITIONS'},
	['Visibility'] = {['enabled'] = true, ['sensorType'] = 'C_VISIBILITY'},
	['Solar radiation'] = {['enabled'] = true, ['sensorType'] = 'C_SOLAR_RADIATION'},
	--['temp'] = {['enabled'] = true, ['sensorType'] = 'C_TEMP'},
	--['hum'] = {['enabled'] = true, ['sensorType'] = 'C_HUM'},
	--['temp/hum'] = {['enabled'] = true, ['sensorType'] = 'C_TEMP_HUM'},
	--['temp/baro'] = {['enabled'] = true, ['sensorType'] = 'C_TEMP_BARO'},
	['Temp/hum/baro'] = {['enabled'] = true, ['sensorType'] = 'C_TEMP_HUM_BARO'},
	['Rain'] = {['enabled'] = true, ['sensorType'] = 'C_RAIN'},
	['Wind'] = {['enabled'] = true, ['sensorType'] = 'C_WIND'},
	['UV'] = {['enabled'] = true, ['sensorType'] = 'C_UV'},

	-- Devices used for forecast period 1. (D+1 = 1 Day after today)
	['Forecast D+1'] = {['enabled'] = true, ['sensorType'] = 'FC1_CONDITIONS'},
	['Forecast D+1 temp low'] = {['enabled'] = true, ['sensorType'] = 'FC1_LOW_TEMP'},
	['Forecast D+1 temp high'] = {['enabled'] = true, ['sensorType'] = 'FC1_HIGH_TEMP'},
	--['Forecast D+1 avg hum'] = {['enabled'] = true, ['sensorType'] = 'FC1_HUM'},
	--['Forecast D+1 rain all day'] = {['enabled'] = true, ['sensorType'] = 'FC1_QPF_ALLDAY'},
	['Forecast D+1 rain day'] = {['enabled'] = true, ['sensorType'] = 'FC1_QPF_DAY'},
	['Forecast D+1 rain night'] = {['enabled'] = true, ['sensorType'] = 'FC1_QPF_NIGHT'},
	--['Forecast D+1 snow all day'] = {['enabled'] = true, ['sensorType'] = 'FC1_SNOW_ALLDAY'},
	--['Forecast D+1 snow day'] = {['enabled'] = true, ['sensorType'] = 'FC1_SNOW_DAY'},
	--['Forecast D+1 snow night'] = {['enabled'] = true, ['sensorType'] = 'FC1_SNOW_NIGHT'},
	['Forecast D+1 wind'] = {['enabled'] = true, ['sensorType'] = 'FC1_WIND'},


	-- Devices used for forecast period 2. (D+2 = 2 Days after today)
	--['Forecast D+2'] = {['enabled'] = true, ['sensorType'] = 'FC2_CONDITIONS'},
	--['Forecast D+2 temp low'] = {['enabled'] = true, ['sensorType'] = 'FC2_LOW_TEMP'},
	--['Forecast D+2 temp high'] = {['enabled'] = true, ['sensorType'] = 'FC2_HIGH_TEMP'},
	--['Forecast D+2 avg hum'] = {['enabled'] = true, ['sensorType'] = 'FC2_HUM'},
	--['Forecast D+2 rain all day'] = {['enabled'] = true, ['sensorType'] = 'FC2_QPF_ALLDAY'},
	--['Forecast D+2 rain day'] = {['enabled'] = true, ['sensorType'] = 'FC2_QPF_DAY'},
	--['Forecast D+2 rain night'] = {['enabled'] = true, ['sensorType'] = 'FC2_QPF_NIGHT'},
	--['Forecast D+2 snow all day'] = {['enabled'] = true, ['sensorType'] = 'FC2_SNOW_ALLDAY'},
	--['Forecast D+2 snow day'] = {['enabled'] = true, ['sensorType'] = 'FC2_SNOW_DAY'},
	--['Forecast D+2 snow night'] = {['enabled'] = true, ['sensorType'] = 'FC2_SNOW_NIGHT'},
	--['Forecast D+2 wind'] = {['enabled'] = true, ['sensorType'] = 'FC2_WIND'},


	-- Devices used for forecast period 3. (D+3 = 3 Days after today)
	--['Forecast D+3'] = {['enabled'] = true, ['sensorType'] = 'FC3_CONDITIONS'},
	--['Forecast D+3 temp low'] = {['enabled'] = true, ['sensorType'] = 'FC3_LOW_TEMP'},
	--['Forecast D+3 temp high'] = {['enabled'] = true, ['sensorType'] = 'FC3_HIGH_TEMP'},
	--['Forecast D+3 avg hum'] = {['enabled'] = true, ['sensorType'] = 'FC3_HUM'},
	--['Forecast D+3 rain all day'] = {['enabled'] = true, ['sensorType'] = 'FC3_QPF_ALLDAY'},
	--['Forecast D+3 rain day'] = {['enabled'] = true, ['sensorType'] = 'FC3_QPF_DAY'},
	--['Forecast D+3 rain night'] = {['enabled'] = true, ['sensorType'] = 'FC3_QPF_NIGHT'},
	--['Forecast D+3 snow all day'] = {['enabled'] = true, ['sensorType'] = 'FC3_SNOW_ALLDAY'},
	--['Forecast D+3 snow day'] = {['enabled'] = true, ['sensorType'] = 'FC3_SNOW_DAY'},
	--['Forecast D+3 snow night'] = {['enabled'] = true, ['sensorType'] = 'FC3_SNOW_NIGHT'},
	--['Forecast D+3 wind'] = {['enabled'] = true, ['sensorType'] = 'FC3_WIND'},


	-- Devices used for forecast period 4. (D+4 = 4 Days after today)
	--['Forecast D+4'] = {['enabled'] = true, ['sensorType'] = 'FC4_CONDITIONS'},
	--['Forecast D+4 temp low'] = {['enabled'] = true, ['sensorType'] = 'FC4_LOW_TEMP'},
	--['Forecast D+4 temp high'] = {['enabled'] = true, ['sensorType'] = 'FC4_HIGH_TEMP'},
	--['Forecast D+4 avg hum'] = {['enabled'] = true, ['sensorType'] = 'FC4_HUM'},
	--['Forecast D+4 rain all day'] = {['enabled'] = true, ['sensorType'] = 'FC4_QPF_ALLDAY'},
	--['Forecast D+4 rain day'] = {['enabled'] = true, ['sensorType'] = 'FC4_QPF_DAY'},
	--['Forecast D+4 rain night'] = {['enabled'] = true, ['sensorType'] = 'FC4_QPF_NIGHT'},
	--['Forecast D+4 snow all day'] = {['enabled'] = true, ['sensorType'] = 'FC4_SNOW_ALLDAY'},
	--['Forecast D+4 snow day'] = {['enabled'] = true, ['sensorType'] = 'FC4_SNOW_DAY'},
	--['Forecast D+4 snow night'] = {['enabled'] = true, ['sensorType'] = 'FC4_SNOW_NIGHT'},
	--['Forecast D+4 wind'] = {['enabled'] = true, ['sensorType'] = 'FC4_WIND'},

}
return _C
wUnderScraper.lua

Code: Select all

-- Weather Underground Scraper, wUnderScraper.lua

--  There is a daily limit and minute rate limit to the number of requests that can be made to the WU API for free.
-- When writing this, the number of free calls per day (New York time) was 500.
local fetchIntervalDayMins = 20 -- Day time scraping interval. Never set this below 4 if you have a free WU API account.
local fetchIntervalNightMins = 30 -- Night time scraping interval. 

--[[
Please don't make any changes below this line. All configuration
except for the 2 variables above, is done in wUnderScrapeConfig.lua 

Using Weather API: http://api.wunderground.com/weather/api/d/docs

To look at the returned json, you might use: http://jsonviewer.stack.hu/

--]]

local scriptVersion = '1.0.0'
local scriptName = 'wUnderScraper'

return {
	active = true,
	logging = {
		--level = domoticz.LOG_DEBUG, -- Select one of LOG_DEBUG, LOG_INFO, LOG_ERROR, LOG_FORCE to override system log level
		marker = scriptName..' '..scriptVersion
	},
	on = {
		timer = {
			'every '..tostring(fetchIntervalDayMins)..' minutes at daytime',
			'every '..tostring(fetchIntervalNightMins)..' minutes at nighttime',
		},
		httpResponses = {scriptName}
	},
	data = {
		observation_epoch = {initial=-1}
	},
	execute = function(domoticz, item)
		local config = require (scriptName..'Config')

		if (item.isTimer) then
			local url = 'https://api.wunderground.com/api/'..config.wuAPIkey..'/conditions/forecast/'..'lang:'..config.wuLang..'/q/'..config.countryCode..'/'..config.location..'.json'
			domoticz.log('Requesting new weather data from Wunderground...', domoticz.LOG_DEBUG)
			domoticz.log('URL used: '..url, domoticz.LOG_DEBUG)
			domoticz.openURL({url = url, method = 'GET', callback = scriptName}).afterSec(10)
		end

		if not item.isHTTPResponse then return end

		local response = item
		if not response.ok or not response.isJSON then
			domoticz.log('Last http response was not what expected. Trigger: '..response.trigger, domoticz.LOG_ERROR)
			local _ = require('lodash')
			domoticz.log(_.str(response.data), domoticz.LOG_ERROR)
			return
		end

		local wuData = response.json
		local observation_epoch = tonumber(wuData.current_observation.observation_epoch) or 0
		local observation_time = wuData.current_observation.observation_time
		if observation_epoch <= domoticz.data.observation_epoch then
			domoticz.log('Data from Wunderground is not newer than the previously fetched, are you fetching to often maybe? ('..observation_time..')' , domoticz.LOG_FORCE)
			return
		else
			domoticz.data.observation_epoch = observation_epoch
		end 
		domoticz.log(wuData.current_observation.display_location.full..', '..observation_time, domoticz.LOG_INFO)

		-- Domoticz sensor types
		local SENSOR_BARO = 1
		local SENSOR_TEXT = 5
		local SENSOR_VISIBILITY = 12
		local SENSOR_SOLAR_RADIATION = 20
		local SENSOR_TEMP = 80
		local SENSOR_HUM = 81
		local SENSOR_TEMP_HUM = 82
		local SENSOR_TEMP_BARO = 247
		local SENSOR_TEMP_HUM_BARO = 84
		local SENSOR_RAIN = 85
		local SENSOR_WIND = 86
		local SENSOR_UV = 87

		-- Each domoWeatherDevices entry in the config file should use one of the following as sensorType:
		-- Where C_ stands for Current Conditions
		-- and FC* stands for Forecast period number 1-4 
		local sensorTypes={ 
			C_CONDITIONS = {domoType=SENSOR_TEXT, wuPeriod=0},
			C_BARO = {domoType=SENSOR_BARO, wuPeriod=0},
			C_VISIBILITY = {domoType=SENSOR_VISIBILITY, wuPeriod=0},
			C_SOLAR_RADIATION = {domoType=SENSOR_SOLAR_RADIATION, wuPeriod=0},
			C_TEMP = {domoType=SENSOR_TEMP, wuPeriod=0},
			C_HUM = {domoType=SENSOR_HUM, wuPeriod=0},
			C_TEMP_HUM = {domoType=SENSOR_TEMP_HUM, wuPeriod=0},
			C_TEMP_BARO = {domoType=SENSOR_TEMP_BARO, wuPeriod=0},
			C_TEMP_HUM_BARO = {domoType=SENSOR_TEMP_HUM_BARO, wuPeriod=0},
			C_RAIN = {domoType=SENSOR_RAIN, wuPeriod=0},
			C_WIND = {domoType=SENSOR_WIND, wuPeriod=0},
			C_UV = {domoType=SENSOR_UV, wuPeriod=0},

			FC1_LOW_TEMP = {domoType=SENSOR_TEMP, wuPeriod=1, wuField='low'},
			FC1_HIGH_TEMP = {domoType=SENSOR_TEMP, wuPeriod=1, wuField='high'},
			FC1_HUM = {domoType=SENSOR_HUM, wuPeriod=1, wuField='avehumidity'},
			FC1_CONDITIONS = {domoType=SENSOR_TEXT, wuPeriod=1},
			-- (QPF = Quantitative Precipitation Forecasts)
			FC1_QPF_ALLDAY = {domoType=SENSOR_RAIN, wuPeriod=1, wuField='qpf_allday'},
			FC1_QPF_DAY = {domoType=SENSOR_RAIN, wuPeriod=1, wuField='qpf_day'},
			FC1_QPF_NIGHT = {domoType=SENSOR_RAIN, wuPeriod=1, wuField='qpf_night'},
			FC1_SNOW_ALLDAY = {domoType=SENSOR_RAIN, wuPeriod=1},
			FC1_SNOW_DAY = {domoType=SENSOR_RAIN, wuPeriod=1},
			FC1_SNOW_NIGHT = {domoType=SENSOR_RAIN, wuPeriod=1},
			FC1_WIND = {domoType=SENSOR_WIND, wuPeriod=1},

			FC2_LOW_TEMP = {domoType=SENSOR_TEMP, wuPeriod=2, wuField='low'},
			FC2_HIGH_TEMP = {domoType=SENSOR_TEMP, wuPeriod=2, wuField='high'},
			FC2_HUM = {domoType=SENSOR_HUM, wuPeriod=2, wuField='avehumidity'},
			FC2_CONDITIONS = {domoType=SENSOR_TEXT, wuPeriod=2},
			FC2_QPF_ALLDAY = {domoType=SENSOR_RAIN, wuPeriod=2, wuField='qpf_allday'},
			FC2_QPF_DAY = {domoType=SENSOR_RAIN, wuPeriod=2, wuField='qpf_day'},
			FC2_QPF_NIGHT = {domoType=SENSOR_RAIN, wuPeriod=2, wuField='qpf_night'},
			FC2_SNOW_ALLDAY = {domoType=SENSOR_RAIN, wuPeriod=2},
			FC2_SNOW_DAY = {domoType=SENSOR_RAIN, wuPeriod=2},
			FC2_SNOW_NIGHT = {domoType=SENSOR_RAIN, wuPeriod=2},
			FC2_WIND = {domoType=SENSOR_WIND, wuPeriod=2},

			FC3_LOW_TEMP = {domoType=SENSOR_TEMP, wuPeriod=3, wuField='low'},
			FC3_HIGH_TEMP = {domoType=SENSOR_TEMP, wuPeriod=3, wuField='high'},
			FC3_HUM = {domoType=SENSOR_HUM, wuPeriod=3, wuField='avehumidity'},
			FC3_CONDITIONS = {domoType=SENSOR_TEXT, wuPeriod=3},
			FC3_QPF_ALLDAY = {domoType=SENSOR_RAIN, wuPeriod=3, wuField='qpf_allday'},
			FC3_QPF_DAY = {domoType=SENSOR_RAIN, wuPeriod=3, wuField='qpf_day'},
			FC3_QPF_NIGHT = {domoType=SENSOR_RAIN, wuPeriod=3, wuField='qpf_night'},
			FC3_SNOW_ALLDAY = {domoType=SENSOR_RAIN, wuPeriod=3},
			FC3_SNOW_DAY = {domoType=SENSOR_RAIN, wuPeriod=3},
			FC3_SNOW_NIGHT = {domoType=SENSOR_RAIN, wuPeriod=3},
			FC3_WIND = {domoType=SENSOR_WIND, wuPeriod=3},

			FC4_LOW_TEMP = {domoType=SENSOR_TEMP, wuPeriod=4, wuField='low'},
			FC4_HIGH_TEMP = {domoType=SENSOR_TEMP, wuPeriod=4, wuField='high'},
			FC4_HUM = {domoType=SENSOR_HUM, wuPeriod=4, wuField='avehumidity'},
			FC4_CONDITIONS = {domoType=SENSOR_TEXT, wuPeriod=4},
			FC4_QPF_ALLDAY = {domoType=SENSOR_RAIN, wuPeriod=4, wuField='qpf_allday'},
			FC4_QPF_DAY = {domoType=SENSOR_RAIN, wuPeriod=4, wuField='qpf_day'},
			FC4_QPF_NIGHT = {domoType=SENSOR_RAIN, wuPeriod=4, wuField='qpf_night'},
			FC4_SNOW_ALLDAY = {domoType=SENSOR_RAIN, wuPeriod=4},
			FC4_SNOW_DAY = {domoType=SENSOR_RAIN, wuPeriod=4},
			FC4_SNOW_NIGHT = {domoType=SENSOR_RAIN, wuPeriod=4},
			FC4_WIND = {domoType=SENSOR_WIND, wuPeriod=4}
		}

		local function degToCompass(num)
			num = (num >= 0 and num < 360) and num or 0
			local val = math.floor((num/22.5)+.5)
			local t = {'N','NNE','NE','ENE','E','ESE', 'SE', 'SSE','S','SSW','SW','WSW','W','WNW','NW','NNW'}
			return t[(val % 16) + 1]
		end

		local function getHumStat(hum)
			if hum > 70 then
				return domoticz.HUM_WET
			elseif hum < 30 then
				return domoticz.HUM_DRY
			else
				return domoticz.HUM_COMFORTABLE
			end
		end

		local function getBaroForecast(mbar)
			-- Barometer forecast, 0 = Stable, 1 = Sunny, 2 = Cloudy, 3 = Unstable, 4 = Thunderstorm, 5 = Unknown, 6 = Cloudy/Rain
			-- A very primitive method indeed to make conclusions based only on current barometric pressure.
			-- It wont work well! Better to also take other parameters in consideration.
			if mbar < 950 then
				return domoticz.BARO_THUNDERSTORM
			elseif mbar < 1000 then
				return domoticz.BARO_UNSTABLE
			elseif mbar < 1020 then
				return domoticz.BARO_CLOUDY
			else
				return domoticz.BARO_SUNNY
			end
		end

		local function wind_chill(temp, wind)
			-- Compute wind chill, using formula from http://en.wikipedia.org/wiki/wind_chill
			if not temp then return end
			local wind_kph = wind * 3.6
			if wind_kph <= 4.8 or temp > 10.0 then return temp end
			return domoticz.utils.round(math.min(13.12 + (temp * 0.6215) + (((0.3965 * temp) - 11.37) * (wind_kph ^ 0.16)), temp))
		end

		local function kmhToMs(kmh)
			return domoticz.utils.round(kmh * 0.2778, 1) -- km/h to m/s rounded
		end

		for dDev, devConfig in pairs(config.domoWeatherDevices) do
			if devConfig.enabled then
				if domoticz.devices(dDev) ~= nil then
					local device = domoticz.devices(dDev)

					local sensorType = devConfig.sensorType
					if not sensorTypes[sensorType] then
						domoticz.log(tostring(dDev)..' has an invalid sensorType: \''..sensorType..'\'', domoticz.LOG_ERROR)
						return
					end
					local sensorConfig = sensorTypes[sensorType]
					-- print(sensorType) e.g. 'C_BARO'
					local domoSensorType = sensorConfig.domoType
					local wuField = sensorConfig.wuField

					local fetchInterval = (domoticz.time.matchesRule('at nighttime') and fetchIntervalNightMins or fetchIntervalDayMins)

					local temperature, pressure, humidity, weather, visibility, radiation,
								rainCounter, rainRate, windBearing, windDirection, windSpeed,
								windGust, windChill, baroForecast, humidityStatus
				
					local wuPeriod = sensorConfig.wuPeriod

					if wuPeriod == 0 then -- Current observation
						temperature = tonumber(wuData.current_observation.temp_c) or 0
						pressure = tonumber(wuData.current_observation.pressure_mb) or 0
						local _hum, _ = wuData.current_observation.relative_humidity:gsub('%%','')
						humidity = tonumber(_hum) or 0
						weather = wuData.current_observation.weather
						visibility = tonumber(wuData.current_observation.visibility_km) or 0
						radiation = tonumber(wuData.current_observation.solarradiation) or 0
						rainCounter = tonumber(wuData.current_observation.precip_today_metric) or 0
						rainRate = tonumber(wuData.current_observation.precip_1hr_metric) or 0

						windBearing = tonumber(wuData.current_observation.wind_degrees) or 0
						windBearing = (windBearing >= 0 and windBearing <= 359) and windBearing or 0
						windDirection = degToCompass(windBearing)
						windSpeed = kmhToMs(tonumber(wuData.current_observation.wind_kph) or 0)
						windGust = kmhToMs(tonumber(wuData.current_observation.wind_gust_kph) or 0)
						baroForecast = getBaroForecast(pressure)

						domoticz.log('\n\n==================================================', domoticz.LOG_DEBUG)
						domoticz.log('temperature: '..tostring(temperature), domoticz.LOG_DEBUG)
						domoticz.log('pressure: '..tostring(pressure), domoticz.LOG_DEBUG)
						domoticz.log('humidity: '..tostring(humidity), domoticz.LOG_DEBUG)
						domoticz.log('weather: '..weather, domoticz.LOG_DEBUG)
						domoticz.log('visibility: '..tostring(visibility), domoticz.LOG_DEBUG)
						domoticz.log('radiation: '..tostring(radiation), domoticz.LOG_DEBUG)
						domoticz.log('rainCounter: '..tostring(rainCounter), domoticz.LOG_DEBUG)
						domoticz.log('rainRate: '..tostring(rainRate), domoticz.LOG_DEBUG)
						domoticz.log('windBearing: '..tostring(windBearing), domoticz.LOG_DEBUG)
						domoticz.log('windDirection: '..windDirection, domoticz.LOG_DEBUG)
						domoticz.log('windSpeed: '..tostring(windSpeed), domoticz.LOG_DEBUG)
						domoticz.log('windGust: '..tostring(windGust), domoticz.LOG_DEBUG)
						domoticz.log('baroForecast: '..baroForecast, domoticz.LOG_DEBUG)
						domoticz.log('==================================================\n\n', domoticz.LOG_DEBUG)

					else -- Forecast
						if domoSensorType == SENSOR_TEXT then
							weather = wuData.forecast.simpleforecast.forecastday[wuPeriod].conditions
						elseif domoSensorType == SENSOR_TEMP then
							temperature = tonumber(wuData.forecast.simpleforecast.forecastday[wuPeriod][wuField].celsius) or 0
						elseif domoSensorType == SENSOR_HUM then
							humidity = tonumber(wuData.forecast.simpleforecast.forecastday[wuPeriod][wuField]) or 0
						elseif domoSensorType == SENSOR_RAIN then
							rainCounter = tonumber(wuData.forecast.simpleforecast.forecastday[wuPeriod][wuField].mm) or 0
							rainRate = rainCounter
						elseif domoSensorType == SENSOR_WIND then
							wuField = 'low' -- Need a temperature for calculating wind chill
							temperature = tonumber(wuData.forecast.simpleforecast.forecastday[wuPeriod][wuField].celsius) or 0
							windBearing = tonumber(wuData.forecast.simpleforecast.forecastday[wuPeriod].avewind.degrees) or 0
							windBearing = (windBearing >= 0 and windBearing <= 359) and windBearing or 0
							windDirection = degToCompass(windBearing)
							windSpeed = kmhToMs(tonumber(wuData.forecast.simpleforecast.forecastday[wuPeriod].avewind.kph) or 0)
							windGust = kmhToMs(tonumber(wuData.forecast.simpleforecast.forecastday[wuPeriod].maxwind.kph) or 0)
						end
						-- Baro pressure N/A in forecast
						-- visibility N/A in forecast
						-- radiation = N/A in forecast
					end

					if temperature and windSpeed then windChill = wind_chill(temperature, windSpeed) end
					if humidity then humidityStatus = getHumStat(humidity) end

					if domoSensorType == SENSOR_BARO then
						if (pressure ~= device.barometer)
						or (baroForecast ~= device.forecast)
						or (device.lastUpdate.minutesAgo > 60-fetchInterval) then
							domoticz.log('Updating Domoticz barometer device '..tostring(dDev)..' to value: \''..tostring(pressure)..'\', \''..baroForecast..'\'', domoticz.LOG_DEBUG)
							device.updateBarometer(pressure, baroForecast)
						end

					elseif domoSensorType == SENSOR_TEXT then
						if weather ~= device.text then 
							domoticz.log('Updating Domoticz text device '..tostring(dDev)..' to value: \''..weather..'\'', domoticz.LOG_DEBUG)
							device.updateText(weather)
						end

					elseif domoSensorType == SENSOR_VISIBILITY then
						if (visibility ~= device.visibility) or (device.lastUpdate.minutesAgo > 60-fetchInterval) then 
							domoticz.log('Updating Domoticz solar visibility device '..tostring(dDev)..' to value: \''..tostring(visibility)..'\'', domoticz.LOG_DEBUG)
							device.updateVisibility(visibility)
						end

					elseif domoSensorType == SENSOR_SOLAR_RADIATION then
						if (radiation ~= device.radiation) or (device.lastUpdate.minutesAgo > 60-fetchInterval) then 
							domoticz.log('Updating Domoticz solar radiation device '..tostring(dDev)..' to value: \''..tostring(radiation)..'\'', domoticz.LOG_DEBUG)
							device.updateRadiation(radiation)
						end

					elseif domoSensorType == SENSOR_TEMP then
						if (temperature ~= device.temperature) or (device.lastUpdate.minutesAgo > 60-fetchInterval) then 
							domoticz.log('Updating Domoticz temperature device '..tostring(dDev)..' to value: \''..tostring(temperature)..'\'', domoticz.LOG_DEBUG)
							device.updateTemperature(temperature)
						end

					elseif domoSensorType == SENSOR_HUM then
						if (humidity ~= device.humidity)
						or (humidityStatus ~= device.humidityStatus)
						or (device.lastUpdate.minutesAgo > 60-fetchInterval) then 
							domoticz.log('Updating Domoticz humidity device '..tostring(dDev)..' to value: \''..tostring(humidity)..'\', \''..tostring(humidityStatus)..'\'', domoticz.LOG_DEBUG)
							device.updateHumidity(humidity, humidityStatus)
						end

					elseif domoSensorType == SENSOR_TEMP_HUM then
						if (temperature ~= device.temperature)
						or (humidity ~= device.humidity)
						or (humidityStatus ~= device.humidityStatus)
						or (device.lastUpdate.minutesAgo > 60-fetchInterval) then 
							domoticz.log('Updating Domoticz temp hum device '..tostring(dDev)..' to value: \''..tostring(temperature)..'\', \''..tostring(humidity)..'\', \''..tostring(humidityStatus)..'\'', domoticz.LOG_DEBUG)
							device.updateTempHum(temperature, humidity, humidityStatus)
						end

					elseif domoSensorType == SENSOR_TEMP_BARO then
						if (temperature ~= device.temperature)
						or (baroForecast ~= device.forecast)
						or (device.lastUpdate.minutesAgo > 60-fetchInterval) then 
							domoticz.log('Updating Domoticz temp baro device '..tostring(dDev)..' to value: \''..tostring(temperature)..'\', \''..tostring(pressure)..'\', \''..baroForecast..'\'', domoticz.LOG_DEBUG)
							device.updateTempBaro(temperature, pressure, baroForecast)
						end

					elseif domoSensorType == SENSOR_TEMP_HUM_BARO then
						if (temperature ~= device.temperature)
						or (humidity ~= device.humidity)
						or (baroForecast ~= device.forecast)
						or (device.lastUpdate.minutesAgo > 60-fetchInterval) then 
							domoticz.log('Updating Domoticz temp hum baro device '..tostring(dDev)..' to value: \''..tostring(temperature)..'\', \''..tostring(humidity)..'\', \''..tostring(humidityStatus)..'\', \''..tostring(pressure)..'\', \''..baroForecast..'\'', domoticz.LOG_DEBUG)
							device.updateTempHumBaro(temperature, humidity, humidityStatus, pressure, baroForecast)
						end

					elseif domoSensorType == SENSOR_RAIN then
						if (rainCounter ~= device.rain)
						or (rainRate ~= device.rainRate)
						or (device.lastUpdate.minutesAgo > 60-fetchInterval) then 
							domoticz.log('Updating Domoticz rain device '..tostring(dDev)..' to value: \''..tostring(rainRate)..'\', \''..tostring(rainCounter)..'\', \''..tostring(humidityStatus)..'\'', domoticz.LOG_DEBUG)
							device.updateRain(rainRate, rainCounter)
						end

					elseif domoSensorType == SENSOR_WIND then
						if (windBearing ~= device.direction)
						or (windDirection ~= device.directionString)
						or (windSpeed ~= device.speed)
						or (windGust ~= device.gust)
						or (temperature ~= device.temperature)
						or (windChill ~= device.chill)
						or (device.lastUpdate.minutesAgo > 60-fetchInterval) then 
							domoticz.log('Updating Domoticz wind device '..tostring(dDev)..' to value: \''..tostring(windBearing)..'\', \''..windDirection..'\', \''..tostring(windSpeed)..'\', \''..tostring(windGust)..'\', \''..tostring(temperature)..'\', \''..tostring(windChill)..'\'', domoticz.LOG_DEBUG)
							device.updateWind(windBearing, windDirection, windSpeed, windGust, temperature, windChill)
						end

					elseif domoSensorType == SENSOR_UV then
						if (radiation ~= device.uv) or (device.lastUpdate.minutesAgo > 60-fetchInterval) then 
							domoticz.log('Updating Domoticz UV device '..tostring(dDev)..' to value: \''..tostring(radiation)..'\'', domoticz.LOG_DEBUG)
							device.updateUV(radiation)
						end

					else
							domoticz.log('I don\'t know what to do with: '..tostring(dDev)..', domoSensorType: '..tostring(domoSensorType), domoticz.LOG_ERROR)
					end

				end
			end
		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: I give you the wUnderScraper!

Post by EdwinK »

Going to try this out. Hope this can some how be combined with the SolarData script from you.
Running latest BETA on a Pi-3 | Toon® Thermostat (rooted) | Hue | Tuya | IKEA tradfri | Dashticz V3 on Lenovo Huawei Tablet | Conbee
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest