diff --git a/driver/apixu-weather.groovy b/driver/apixu-weather.groovy
index 1347357..87b8f04 100644
--- a/driver/apixu-weather.groovy
+++ b/driver/apixu-weather.groovy
@@ -2,14 +2,14 @@
* Copyright 2018 bangali
*
* Contributors:
-* https://github.com/jebbett code for new weather icons based on weather condition data
-* https://www.deviantart.com/vclouds/art/VClouds-Weather-Icons-179152045 new weather icons courtesy of VClouds
+* https://github.com/jebbett code for new weather icons based on weather condition data
+* https://www.deviantart.com/vclouds/art/VClouds-Weather-Icons-179152045 new weather icons courtesy of VClouds
* https://github.com/arnbme code for mytile
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at:
*
-* http://www.apache.org/licenses/LICENSE-2.0
+* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
@@ -35,10 +35,13 @@
*
***********************************************************************************************************************/
-public static String version() { return "v4.1.0" }
+public static String version() { return "v4.2.0" }
/***********************************************************************************************************************
*
+* Version: 4.2.0
+* 12/29/2018:cleanups, event optimizations
+*
* Version: 4.1.0
* 12/29/2018: merged mytile code
*
@@ -60,7 +63,7 @@ public static String version() { return "v4.1.0" }
*
* Version: 3.0.0
* 7/25/2018: added code contribution from https://github.com/jebbett for new cooler weather icons with icons courtesy
-* of https://www.deviantart.com/vclouds/art/VClouds-Weather-Icons-179152045.
+* of https://www.deviantart.com/vclouds/art/VClouds-Weather-Icons-179152045.
*
* Version: 2.5.0
* 5/23/2018: update condition_icon to contain image for use on dashboard and moved icon url to condition_icon_url.
@@ -75,505 +78,599 @@ public static String version() { return "v4.1.0" }
import groovy.transform.Field
-metadata {
- definition (name: "ApiXU Weather Driver", namespace: "bangali", author: "bangali") {
- capability "Actuator"
- capability "Sensor"
- capability "Polling"
- capability "Illuminance Measurement"
- capability "Temperature Measurement"
- capability "Relative Humidity Measurement"
- capability "Pressure Measurement"
- capability "Ultraviolet Index"
-// capability "Switch"
-
- attribute "name", "string"
- attribute "region", "string"
- attribute "country", "string"
- attribute "lat", "string"
- attribute "lon", "string"
- attribute "tz_id", "string"
- attribute "localtime_epoch", "string"
- attribute "local_time", "string"
- attribute "local_date", "string"
- attribute "last_updated_epoch", "string"
- attribute "last_updated", "string"
-// attribute "temp_c", "string"
-// attribute "temp_f", "string"
- attribute "is_day", "string"
- attribute "condition_text", "string"
- attribute "condition_icon", "string"
- attribute "condition_icon_url", "string"
- attribute "condition_code", "string"
- attribute "visual", "string"
- attribute "visualWithText", "string"
- attribute "wind_mph", "string"
- attribute "wind_kph", "string"
+metadata {
+ definition (name: "ApiXU Weather Driver", namespace: "bangali", author: "bangali") {
+ capability "Initialize"
+// capability "Actuator"
+ capability "Sensor"
+ capability "Polling"
+ capability "Illuminance Measurement"
+ capability "Temperature Measurement"
+ capability "Relative Humidity Measurement"
+ capability "Pressure Measurement"
+ capability "Ultraviolet Index"
+// capability "Switch"
+
+// Standard attributes from capabilities
+// attribute "temperature", "string"
+// attribute "humidity", "string"
+// attribute "illuminance", "string"
+// attribute "pressure", "string"
+// attribute "ultravioletindex", "string"
+
+
+// name not needed city has this
+ attribute "name", "string"
+
+ attribute "region", "string"
+ attribute "country", "string"
+
+// not needed
+ attribute "lat", "string"
+ attribute "lon", "string"
+ attribute "tz_id", "string"
+
+// these only used in dashboards
+ attribute "localtime_epoch", "string"
+ attribute "local_time", "string"
+ attribute "local_date", "string"
+ attribute "last_updated_epoch", "string"
+
+ attribute "last_updated", "string"
+
+// not needed
+// attribute "temp_c", "string"
+// attribute "temp_f", "string"
+ attribute "is_day", "string"
+ attribute "condition_text", "string"
+ attribute "condition_icon", "string"
+ attribute "condition_icon_url", "string"
+ attribute "condition_icon_only", "string"
+ attribute "condition_code", "string"
+ attribute "visual", "string"
+ attribute "visualWithText", "string"
+
+// obsolete
+ attribute "wind_mph", "string"
+ attribute "wind_kph", "string"
attribute "wind_mps", "string"
- attribute "wind_degree", "string"
- attribute "wind_dir", "string"
-// attribute "pressure_mb", "string"
-// attribute "pressure_in", "string"
- attribute "precip_mm", "string"
- attribute "precip_in", "string"
- attribute "cloud", "string"
- attribute "feelslike_c", "string"
- attribute "feelslike_f", "string"
- attribute "vis_km", "string"
- attribute "vis_miles", "string"
-
- attribute "location", "string"
- attribute "city", "string"
- attribute "local_sunrise", "string"
- attribute "local_sunset", "string"
- attribute "twilight_begin", "string"
- attribute "twilight_end", "string"
- attribute "illuminated", "string"
- attribute "cCF", "string"
- attribute "lastXUupdate", "string"
-
- attribute "weather", "string"
- attribute "forecastIcon", "string"
- attribute "feelsLike", "string"
- attribute "wind", "string"
- attribute "percentPrecip", "string"
-
- attribute "localSunrise", "string"
- attribute "localSunset", "string"
-
- attribute "visualDayPlus1", "string"
- attribute "visualDayPlus1WithText", "string"
- attribute "temperatureLowDayPlus1", "string"
- attribute "temperatureHighDayPlus1", "string"
- attribute "wind_mytile", "string"
- attribute "mytile", "string"
-
- command "refresh"
- }
-
- preferences {
- input "zipCode", "text", title: "Zip code or city name or latitude,longitude?", required: true
- input "apixuKey", "text", title: "ApiXU key?", required: true
- input "cityName", "text", title: "Override default city name?", required: false, defaultValue: null
- input "isFahrenheit", "bool", title: "Use Imperial units?", required: true, defaultValue: true
-// input "publishWU", "bool", title: "Publish WU mappings?", required: true, defaultValue: false
- input "dashClock", "bool", title: "Flash time ':' every 2 seconds?", required: true, defaultValue: false
- input "pollEvery", "enum", title: "Poll ApiXU how frequently?\nrecommended setting 30 minutes.\nilluminance is always updated every 5 minutes.", required: true, defaultValue: 30,
- options: [5:"5 minutes",10:"10 minutes",15:"15 minutes",30:"30 minutes"]
- }
+
+ attribute "wind_degree", "string"
+ attribute "wind_dir", "string"
+
+// attribute "pressure_mb", "string"
+// attribute "pressure_in", "string"
+
+// not needed
+ attribute "precip_mm", "string"
+ attribute "precip_in", "string"
+
+ attribute "precip_today", "string"
+
+// not needed feelsLike covers this
+ attribute "cloud", "string"
+ attribute "feelslike_c", "string"
+ attribute "feelslike_f", "string"
+
+ attribute "dewpoint", "string"
+ attribute "visibility", "string"
+
+// not needed (visibility covers these)
+ attribute "vis_km", "string"
+ attribute "vis_miles", "string"
+
+ attribute "location", "string"
+ attribute "city", "string"
+
+// used by dashboards as eye candy
+ attribute "local_sunrise", "string"
+ attribute "local_sunset", "string"
+ attribute "twilight_begin", "string"
+ attribute "twilight_end", "string"
+
+// obsolete covered by illuminance
+ attribute "illuminated", "string"
+
+//not needed
+ attribute "cCF", "string"
+ attribute "lastXUupdate", "string"
+
+ attribute "weather", "string"
+ attribute "feelsLike", "string"
+ attribute "wind", "string"
+
+// not filled in by apiXU
+ attribute "percentPrecip", "string"
+
+// used by dashboards - not needed
+ attribute "localSunrise", "string"
+ attribute "localSunset", "string"
+ attribute "visualDayPlus1", "string"
+ attribute "visualDayPlus1WithText", "string"
+ attribute "temperatureLowDayPlus1", "string"
+ attribute "temperatureHighDayPlus1", "string"
+ attribute "forecastIcon", "string"
+ attribute "forecast_icon_url", "string"
+ attribute "forecast_text", "string"
+ attribute "forecast_code", "string"
+ attribute "wind_mytile", "string"
+ attribute "mytile", "string"
+
+ command "refresh"
+ command "getApiXUData"
+ }
+
+ preferences {
+ input "apixuKey", "text", title: "ApiXU key?", required: true
+ input "zipCode", "text", title: "Override Zip code or set city name or latitude,longitude? (Default: ${location.zipCode})", defaultValue: null, required: false
+ input "cityName", "text", title: "Override default city name?", required: false, defaultValue: null
+ input "isFahrenheit", "bool", title: "Use Imperial units?", required: false, defaultValue: true
+// input "publishWU", "bool", title: "Publish WU mappings?", required: true, defaultValue: false
+ input "dashClock", "bool", title: "Flash time ':' every 2 seconds?", required: false, defaultValue: false
+ input "pollEvery", "enum", title: "Poll ApiXU how frequently?\nrecommended setting 30 minutes.\nilluminance is always updated every 5 minutes.", required: false, defaultValue: 30,
+ options: [5:"5 minutes",10:"10 minutes",15:"15 minutes",30:"30 minutes"]
+ }
}
-def updated() {
- unschedule()
- state.tz_id = null
- state.clockSeconds = true
- poll()
- "runEvery${pollEvery}Minutes"(poll)
- runEvery5Minutes(updateLux)
-// schedule("0 * * * * ?", updateClock)
-// schedule("0/2 0 0 ? * * *", updateClock)
- if (dashClock) updateClock();
+def getApiXUData() {
+ return state?.obs
}
-def poll() {
- log.debug ">>>>> apixu: Executing 'poll', location: $zipCode"
-
- def obs = getXUdata()
- if (!obs) {
- log.warn "No response from ApiXU API"
- return
- }
-
- def now = new Date().format('yyyy-MM-dd HH:mm', location.timeZone)
- sendEvent(name: "lastXUupdate", value: now, isStateChange: true, displayed: true)
-
- def tZ = TimeZone.getTimeZone(obs.location.tz_id)
- state.tz_id = obs.location.tz_id
-
- def localTime = new Date().parse("yyyy-MM-dd HH:mm", obs.location.localtime, tZ)
- def localDate = localTime.format("yyyy-MM-dd", tZ)
- def localTimeOnly = localTime.format("HH:mm", tZ)
-
- def sunriseAndSunset = getSunriseAndSunset(obs.location.lat, obs.location.lon, localDate)
- def sunriseTime = new Date().parse("yyyy-MM-dd'T'HH:mm:ssXXX", sunriseAndSunset.results.sunrise, tZ)
- def sunsetTime = new Date().parse("yyyy-MM-dd'T'HH:mm:ssXXX", sunriseAndSunset.results.sunset, tZ)
- def noonTime = new Date().parse("yyyy-MM-dd'T'HH:mm:ssXXX", sunriseAndSunset.results.solar_noon, tZ)
- def twilight_begin = new Date().parse("yyyy-MM-dd'T'HH:mm:ssXXX", sunriseAndSunset.results.civil_twilight_begin, tZ)
- def twilight_end = new Date().parse("yyyy-MM-dd'T'HH:mm:ssXXX", sunriseAndSunset.results.civil_twilight_end, tZ)
-
- def localSunrise = sunriseTime.format("HH:mm", tZ)
- sendEvent(name: "local_sunrise", value: localSunrise, descriptionText: "Sunrise today is at $localSunrise", isStateChange: true, displayed: true)
- def localSunset = sunsetTime.format("HH:mm", tZ)
- sendEvent(name: "local_sunset", value: localSunset, descriptionText: "Sunset today at is $localSunset", isStateChange: true, displayed: true)
- def tB = twilight_begin.format("HH:mm", tZ)
- sendEvent(name: "twilight_begin", value: tB, descriptionText: "Twilight begins today at $tB", isStateChange: true, displayed: true)
- def tE = twilight_end.format("HH:mm", tZ)
- sendEvent(name: "twilight_end", value: tE, descriptionText: "Twilight ends today at $tE", isStateChange: true, displayed: true)
-
- state.sunriseTime = sunriseTime.format("yyyy-MM-dd'T'HH:mm:ssXXX", tZ)
- state.sunsetTime = sunsetTime.format("yyyy-MM-dd'T'HH:mm:ssXXX", tZ)
- state.noonTime = noonTime.format("yyyy-MM-dd'T'HH:mm:ssXXX", tZ)
- state.twilight_begin = twilight_begin.format("yyyy-MM-dd'T'HH:mm:ssXXX", tZ)
- state.twilight_end = twilight_end.format("yyyy-MM-dd'T'HH:mm:ssXXX", tZ)
-
- sendEvent(name: "name", value: obs.location.name, isStateChange: true, displayed: true)
- sendEvent(name: "region", value: obs.location.region, isStateChange: true, displayed: true)
- sendEvent(name: "country", value: obs.location.country, isStateChange: true, displayed: true)
- sendEvent(name: "lat", value: obs.location.lat, isStateChange: true, displayed: true)
- sendEvent(name: "lon", value: obs.location.lon, isStateChange: true, displayed: true)
- sendEvent(name: "tz_id", value: obs.location.tz_id, isStateChange: true, displayed: true)
- sendEvent(name: "localtime_epoch", value: obs.location.localtime_epoch, isStateChange: true, displayed: true)
- sendEvent(name: "local_time", value: localTimeOnly, isStateChange: true, displayed: true)
- sendEvent(name: "local_date", value: localDate, isStateChange: true, displayed: true)
- sendEvent(name: "last_updated_epoch", value: obs.current.last_updated_epoch, isStateChange: true, displayed: true)
- sendEvent(name: "last_updated", value: obs.current.last_updated, isStateChange: true, displayed: true)
-// sendEvent(name: "temp_c", value: obs.current.temp_c, unit: "C")
-// sendEvent(name: "temp_f", value: obs.current.temp_f, unit: "F")
- sendEvent(name: "temperature", value: (isFahrenheit ? obs.current.temp_f : obs.current.temp_c), unit: "${(isFahrenheit ? 'F' : 'C')}", isStateChange: true, displayed: true)
- sendEvent(name: "is_day", value: obs.current.is_day, isStateChange: true, displayed: true)
- sendEvent(name: "condition_text", value: obs.current.condition.text, isStateChange: true, displayed: true)
- sendEvent(name: "condition_icon", value: '
', isStateChange: true, displayed: true)
- sendEvent(name: "condition_icon_url", value: 'https:' + obs.current.condition.icon, isStateChange: true, displayed: true)
- sendEvent(name: "condition_code", value: obs.current.condition.code, isStateChange: true, displayed: true)
- def imgName = getImgName(obs.current.condition.code, obs.current.is_day)
- sendEvent(name: "visual", value: '
', isStateChange: true, displayed: true)
- sendEvent(name: "visualWithText", value: '
' + obs.current.condition.text, isStateChange: true, displayed: true)
- sendEvent(name: "wind_mph", value: obs.current.wind_mph, unit: "MPH", isStateChange: true, displayed: true)
- sendEvent(name: "wind_kph", value: obs.current.wind_kph, unit: "KPH", isStateChange: true, displayed: true)
- sendEvent(name: "wind_mps", value: ((obs.current.wind_kph / 3.6f).round(1)), unit: "MPS", isStateChange: true, displayed: true)
- sendEvent(name: "wind_degree", value: obs.current.wind_degree, unit: "DEGREE", isStateChange: true, displayed: true)
- sendEvent(name: "wind_dir", value: obs.current.wind_dir, isStateChange: true, displayed: true)
-// sendEvent(name: "pressure_mb", value: obs.current.pressure_mb, unit: "MBAR")
-// sendEvent(name: "pressure_in", value: obs.current.pressure_in, unit: "IN")
- sendEvent(name: "pressure", value: (isFahrenheit ? obs.current.pressure_in : obs.current.pressure_mb), unit: "${(isFahrenheit ? 'IN' : 'MBAR')}", isStateChange: true, displayed: true)
- sendEvent(name: "precip_mm", value: obs.current.precip_mm, unit: "MM", isStateChange: true, displayed: true)
- sendEvent(name: "precip_in", value: obs.current.precip_in, unit: "IN", isStateChange: true, displayed: true)
- sendEvent(name: "humidity", value: obs.current.humidity, unit: "%", isStateChange: true, displayed: true)
- sendEvent(name: "cloud", value: obs.current.cloud, unit: "%", isStateChange: true, displayed: true)
- sendEvent(name: "feelslike_c", value: obs.current.feelslike_c, unit: "C", isStateChange: true, displayed: true)
- sendEvent(name: "feelslike_f", value: obs.current.feelslike_f, unit: "F", isStateChange: true, displayed: true)
- sendEvent(name: "vis_km", value: obs.current.vis_km, unit: "KM", isStateChange: true, displayed: true)
- sendEvent(name: "vis_miles", value: obs.current.vis_miles, unit: "MILES", isStateChange: true, displayed: true)
-
- sendEvent(name: "condition_icon_only", value: obs.current.condition.icon.split("/")[-1], isStateChange: true, displayed: true)
- sendEvent(name: "location", value: obs.location.name + ', ' + obs.location.region, isStateChange: true, displayed: true)
- state.condition_code = obs.current.condition.code
- state.cloud = obs.current.cloud
- updateLux()
-
-// if (publishWU) {
- sendEvent(name: "city", value: (cityName ?: obs.location.name), isStateChange: true, displayed: true)
- sendEvent(name: "weather", value: obs.current.condition.text, isStateChange: true, displayed: true)
- sendEvent(name: "forecastIcon", value: getWUIconName(obs.current.condition.code, 1), isStateChange: true, displayed: true)
- sendEvent(name: "feelsLike", value: (isFahrenheit ? obs.current.feelslike_f : obs.current.feelslike_c), unit: "${(isFahrenheit ? 'F' : 'C')}", isStateChange: true, displayed: true)
- sendEvent(name: "wind", value: (isFahrenheit ? obs.current.wind_mph : obs.current.wind_kph), unit: "${(isFahrenheit ? 'MPH' : 'KPH')}", isStateChange: true, displayed: true)
- sendEvent(name: "percentPrecip", value: (isFahrenheit ? obs.current.precip_in : obs.current.precip_mm), unit: "${(isFahrenheit ? 'IN' : 'MM')}", isStateChange: true, displayed: true)
- sendEvent(name: "localSunrise", value: localSunrise, isStateChange: true, displayed: true)
- sendEvent(name: "localSunset", value: localSunset, isStateChange: true, displayed: true)
-// }
-
- def wind_mytile=(isFahrenheit ? "${Math.round(obs.current.wind_mph)}" + " mph " : "${Math.round(obs.current.wind_kph)}" + " kph ")
- sendEvent(name: "wind_mytile", value: wind_mytile, isStateChange: true, displayed: true)
-
- imgName = getImgName(obs.forecast.forecastday[0].day.condition.code, 1)
- sendEvent(name: "visualDayPlus1", value: '
', isStateChange: true, displayed: true)
- sendEvent(name: "visualDayPlus1WithText", value: '
' + obs.forecast.forecastday[0].day.condition.text, isStateChange: true, displayed: true)
- sendEvent(name: "temperatureHighDayPlus1", value: (isFahrenheit ? obs.forecast.forecastday[0].day.maxtemp_f :
- obs.forecast.forecastday[0].day.maxtemp_c), unit: "${(isFahrenheit ? 'F' : 'C')}", isStateChange: true, displayed: true)
- sendEvent(name: "temperatureLowDayPlus1", value: (isFahrenheit ? obs.forecast.forecastday[0].day.mintemp_f :
- obs.forecast.forecastday[0].day.mintemp_c), unit: "${(isFahrenheit ? 'F' : 'C')}", isStateChange: true, displayed: true)
-
- def mytext = obs.location.name + ', ' + obs.location.region
-// if (isFahrenheit) {
-// mytext += '
' + "${Math.round(obs.current.temp_f)}" + '°F ' + obs.current.humidity + '%'
-// mytext += '
' + localSunrise + '
' + localSunset
-// mytext += (wind_mytile == "0 mph " ? '
Wind is calm' : '
' + obs.current.wind_dir + ' ' + wind_mytile)
-// if (wind_mytile == "0 mph ")
-// mytext+='
Wind is calm'
-// else
-// mytext+='
' + obs.current.wind_dir + ' ' + wind_mytile
-// mytext += '
' + obs.current.condition.text
-// }
-// else {
-// mytext += '
' + obs.current.temp_c + '°C ' + obs.current.humidity + '%'
-// mytext += '
' + localSunrise + '
' + localSunset
-// mytext += (wind_mytile == "0 kph " ? '
Wind is calm' : '
' + obs.current.wind_dir + ' ' + wind_mytile)
-// if (wind_mytile == "0 kph ")
-// mytext+='
Wind is calm'
-// else
-// mytext+='
' + obs.current.wind_dir + ' ' + wind_mytile
-// mytext += '
' + obs.current.condition.text
+def installed() {
+ updated()
+}
+
+def initialize() {
+ updated()
+}
+
+def updated() {
+ if(apixuKey) {
+ state.zipCode = settings?.zipCode ?: location.zipCode
+ state.poll = settings?.pollEvery ?: 30
+ state.wantMetric = settings?.isFahrenheit != null ? !settings?.isFahrenheit : (getTemperatureScale() == "C")
+ state.today = null
+ unschedule()
+ state.tz_id = null
+ state.clockSeconds = true
+ poll()
+ "runEvery${state.poll}Minutes"(poll)
+ runEvery5Minutes(updateLux)
+// schedule("0 * * * * ?", updateClock)
+// schedule("0/2 0 0 ? * * *", updateClock)
+ if (dashClock) updateClock();
+ } else { log.error "apixuKey not set" }
+}
+
+def wantMetric() {
+ def t0 = state?.wantMetric == true ? true : false
+ return t0
+}
+
+def poll() {
+ log.debug ">>>>> apixu: Executing 'poll', location: ${state?.zipCode}"
+
+ def obs = getXUdata()
+ if (!obs) {
+ log.warn "No response from ApiXU API"
+ return
+ }
+
+ state.obs = obs
+
+ def now = new Date().format('yyyy-MM-dd HH:mm', location.timeZone)
+ sendEvent(name: "lastXUupdate", value: now, /* isStateChange: true, */ displayed: true)
+
+ def tZ = TimeZone.getTimeZone(obs.location.tz_id)
+ state.tz_id = obs.location.tz_id
+
+ def localTime = new Date().parse("yyyy-MM-dd HH:mm", obs.location.localtime, tZ)
+ def localDate = localTime.format("yyyy-MM-dd", tZ)
+ def localTimeOnly = localTime.format("HH:mm", tZ)
+ def todayDay = localTime.format("dd", tZ)
+
+ if (!state?.today || state.today != todayDay) {
+ state.today = todayDay
+ def sunriseAndSunset = getSunriseAndSunset(obs.location.lat, obs.location.lon, localDate)
+ def sunriseTime = new Date().parse("yyyy-MM-dd'T'HH:mm:ssXXX", sunriseAndSunset.results.sunrise, tZ)
+ def sunsetTime = new Date().parse("yyyy-MM-dd'T'HH:mm:ssXXX", sunriseAndSunset.results.sunset, tZ)
+ def noonTime = new Date().parse("yyyy-MM-dd'T'HH:mm:ssXXX", sunriseAndSunset.results.solar_noon, tZ)
+ def twilight_begin = new Date().parse("yyyy-MM-dd'T'HH:mm:ssXXX", sunriseAndSunset.results.civil_twilight_begin, tZ)
+ def twilight_end = new Date().parse("yyyy-MM-dd'T'HH:mm:ssXXX", sunriseAndSunset.results.civil_twilight_end, tZ)
+ def localSunrise = sunriseTime.format("HH:mm", tZ)
+ sendEvent(name: "local_sunrise", value: localSunrise, descriptionText: "Sunrise today is at $localSunrise", /* isStateChange: true, */ displayed: true)
+ def localSunset = sunsetTime.format("HH:mm", tZ)
+ sendEvent(name: "local_sunset", value: localSunset, descriptionText: "Sunset today at is $localSunset", /* isStateChange: true, */ displayed: true)
+ def tB = twilight_begin.format("HH:mm", tZ)
+ sendEvent(name: "twilight_begin", value: tB, descriptionText: "Twilight begins today at $tB", /* isStateChange: true, */ displayed: true)
+ def tE = twilight_end.format("HH:mm", tZ)
+ sendEvent(name: "twilight_end", value: tE, descriptionText: "Twilight ends today at $tE", /* isStateChange: true, */ displayed: true)
+
+ sendEvent(name: "localSunrise", value: localSunrise, /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "localSunset", value: localSunset, /* isStateChange: true, */ displayed: true)
+
+ state.sunriseTime = sunriseTime.format("yyyy-MM-dd'T'HH:mm:ssXXX", tZ)
+ state.sunsetTime = sunsetTime.format("yyyy-MM-dd'T'HH:mm:ssXXX", tZ)
+ state.noonTime = noonTime.format("yyyy-MM-dd'T'HH:mm:ssXXX", tZ)
+ state.twilight_begin = twilight_begin.format("yyyy-MM-dd'T'HH:mm:ssXXX", tZ)
+ state.twilight_end = twilight_end.format("yyyy-MM-dd'T'HH:mm:ssXXX", tZ)
+ }
+
+ sendEvent(name: "name", value: obs.location.name, /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "region", value: obs.location.region, /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "country", value: obs.location.country, /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "lat", value: obs.location.lat, /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "lon", value: obs.location.lon, /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "tz_id", value: obs.location.tz_id, /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "localtime_epoch", value: obs.location.localtime_epoch, /* isStateChange: true, */ displayed: false)
+ sendEvent(name: "local_time", value: localTimeOnly, /* isStateChange: true, */ displayed: false)
+ sendEvent(name: "local_date", value: localDate, /* isStateChange: true, */ displayed: false)
+ sendEvent(name: "last_updated_epoch", value: obs.current.last_updated_epoch, /* isStateChange: true, */ displayed: true)
+ if(isStateChange(device, "last_updated", obs.current.last_updated.toString())) {
+ sendEvent(name: "last_updated", value: obs.current.last_updated, isStateChange: true, displayed: true)
+ }
+// sendEvent(name: "temp_c", value: obs.current.temp_c, unit: "C")
+// sendEvent(name: "temp_f", value: obs.current.temp_f, unit: "F")
+ def t0 = (!wantMetric() ? obs.current.temp_f : obs.current.temp_c)
+ if(isStateChange(device, "temperature", t0.toString())) {
+ sendEvent(name: "temperature", value: t0, unit: "${(!wantMetric() ? 'F' : 'C')}", isStateChange: true, displayed: true)
+ }
+ sendEvent(name: "is_day", value: obs.current.is_day, /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "condition_text", value: obs.current.condition.text, /* isStateChange: true, */ displayed: true) // same as "weather" below
+ sendEvent(name: "condition_icon", value: '
', /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "condition_icon_url", value: 'https:' + obs.current.condition.icon, /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "condition_code", value: obs.current.condition.code, /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "condition_icon_only", value: obs.current.condition.icon.split("/")[-1], /* isStateChange: true, */ displayed: true)
+ def imgName = getImgName(obs.current.condition.code, obs.current.is_day)
+ sendEvent(name: "visual", value: '
', /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "visualWithText", value: '
' + obs.current.condition.text, /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "wind_mph", value: obs.current.wind_mph, unit: "MPH", /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "wind_kph", value: obs.current.wind_kph, unit: "KPH", /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "wind_mps", value: ((obs.current.wind_kph / 3.6f).round(1)), unit: "MPS", /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "wind_degree", value: obs.current.wind_degree, unit: "DEGREE", /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "wind_dir", value: obs.current.wind_dir, /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "ultravioletindex", value: obs.current.uv, /* isStateChange: true, */ displayed: true)
+// sendEvent(name: "pressure_mb", value: obs.current.pressure_mb, unit: "MBAR")
+// sendEvent(name: "pressure_in", value: obs.current.pressure_in, unit: "IN")
+ sendEvent(name: "pressure", value: (!wantMetric() ? obs.current.pressure_in : obs.current.pressure_mb), unit: "${(!wantMetric() ? 'IN' : 'MBAR')}", /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "precip_mm", value: obs.current.precip_mm, unit: "MM", /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "precip_in", value: obs.current.precip_in, unit: "IN", /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "humidity", value: obs.current.humidity, unit: "%", /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "cloud", value: obs.current.cloud, unit: "%", /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "feelslike_c", value: obs.current.feelslike_c, unit: "C", /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "feelslike_f", value: obs.current.feelslike_f, unit: "F", /* isStateChange: true, */ displayed: true)
+
+ def hum = obs.current.humidity?.toString().replaceAll("\\%", "") as Double
+ def Tc = Math.round(obs.current.feelslike_c as Double) as Double
+ def curDew = estimateDewPoint(hum,Tc)
+ if(obs.current.temp_c < curDew) { curDew = obs.current.temp_c }
+ curDew = !wantMetric() ? (curDew * 9/5 + 32).round(1) : curDew
+ sendEvent(name: "dewpoint", value: curDew, unit: "${(!wantMetric() ? 'F' : 'C')}", /* isStateChange: true, */ displayed: true)
+
+ sendEvent(name: "vis_km", value: obs.current.vis_km, unit: "KM", /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "vis_miles", value: obs.current.vis_miles, unit: "MILES", /* isStateChange: true, */ displayed: true)
+
+ def myCity = cityName ?: obs.location.name
+ sendEvent(name: "location", value: myCity + ', ' + obs.location.region, /* isStateChange: true, */ displayed: true)
+ state.condition_code = obs.current.condition.code
+ state.cloud = obs.current.cloud
+ updateLux()
+
+// if (publishWU) {
+ sendEvent(name: "city", value: myCity, /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "weather", value: obs.current.condition.text, /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "feelsLike", value: (!wantMetric() ? obs.current.feelslike_f : obs.current.feelslike_c), unit: "${(!wantMetric() ? 'F' : 'C')}", /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "wind", value: (!wantMetric() ? obs.current.wind_mph : obs.current.wind_kph), unit: "${(!wantMetric() ? 'MPH' : 'KPH')}", /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "visibility", value: (!wantMetric() ? obs.current.vis_miles : obs.current.vis_km), unit: "${(!wantMetric() ? 'MILES' : 'KM')}", /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "precip_today", value: (!wantMetric() ? obs.current.precip_in : obs.current.precip_mm), unit: "${(!wantMetric() ? 'IN' : 'MM')}", /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "percentPrecip", value: (!wantMetric() ? obs.current.precip_in : obs.current.precip_mm), unit: "${(!wantMetric() ? 'IN' : 'MM')}", /* isStateChange: true, */ displayed: true)
// }
- mytext += '
' + (isFahrenheit ? "${Math.round(obs.current.temp_f)}" + '°F ' : obs.current.temp_c + '°C ') + obs.current.humidity + '%'
- mytext += '
' + localSunrise + '
' + localSunset
- mytext += (wind_mytile == (isFahrenheit ? "0 mph " : "0 kph ") ? '
Wind is calm' : '
' + obs.current.wind_dir + ' ' + wind_mytile)
+ sendEvent(name: "forecastIcon", value: getWUIconName(obs.forecast.forecastday[1].day.condition.code, 1), /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "forecast_icon_url", value: 'https:' + obs.forecast.forecastday[1].day.condition.icon, /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "forecast_text", value: obs.forecast.forecastday[1].day.condition.text, /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "forecast_code", value: obs.forecast.forecastday[1].day.condition.code, /* isStateChange: true, */ displayed: true)
+
+ imgName = getImgName(obs.forecast.forecastday[1].day.condition.code, 1)
+ sendEvent(name: "visualDayPlus1", value: '
', /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "visualDayPlus1WithText", value: '
' + obs.forecast.forecastday[1].day.condition.text, /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "temperatureHighDayPlus1", value: (!wantMetric() ? obs.forecast.forecastday[1].day.maxtemp_f :
+ obs.forecast.forecastday[1].day.maxtemp_c), unit: "${(!wantMetric() ? 'F' : 'C')}", /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "temperatureLowDayPlus1", value: (!wantMetric() ? obs.forecast.forecastday[1].day.mintemp_f :
+ obs.forecast.forecastday[1].day.mintemp_c), unit: "${(!wantMetric() ? 'F' : 'C')}", /* isStateChange: true, */ displayed: true)
+
+ def wind_mytile=(!wantMetric() ? "${Math.round(obs.current.wind_mph)}" + " mph " : "${Math.round(obs.current.wind_kph)}" + " kph ")
+
+ sendEvent(name: "wind_mytile", value: wind_mytile, /* isStateChange: true, */ displayed: true)
+
+ def mytext = myCity + ', ' + obs.location.region
+ mytext += '
' + (!wantMetric() ? "${Math.round(obs.current.temp_f)}" + '°F ' : obs.current.temp_c + '°C ') + obs.current.humidity + '%'
+ mytext += '
' + device.currentState("localSunrise")?.value + '
' + device.currentState("localSunset")?.value
+ mytext += (wind_mytile == (!wantMetric() ? "0 mph " : "0 kph ") ? '
Wind is calm' : '
' + obs.current.wind_dir + ' ' + wind_mytile)
mytext += '
' + obs.current.condition.text
- sendEvent(name: "mytile", value: mytext, isStateChange: true, displayed: true)
- return
+ sendEvent(name: "mytile", value: mytext, /* isStateChange: true, */ displayed: true)
+
+ return
}
-def refresh() { poll() }
-
-def configure() { poll() }
-
-private getXUdata() {
- def obs = [:]
- def params = [ uri: "https://api.apixu.com/v1/forecast.json?key=$apixuKey&q=$zipCode&days=3" ]
- try {
- httpGet(params) { resp ->
- if (resp?.data) obs << resp.data;
- else log.error "http call for ApiXU weather api did not return data: $resp";
- }
- } catch (e) { log.error "http call failed for ApiXU weather api: $e" }
-// log.debug "$obs"
- return obs
+def refresh() { poll() }
+
+def configure() { poll() }
+
+private getXUdata() {
+ def obs = [:]
+ def params = [ uri: "https://api.apixu.com/v1/forecast.json?key=${apixuKey}&q=${state?.zipCode}&days=3" ]
+ try {
+ httpGet(params) { resp ->
+ if (resp?.data) obs << resp.data;
+ else log.error "http call for ApiXU weather api did not return data: $resp";
+ }
+ } catch (e) { log.error "http call failed for ApiXU weather api: $e" }
+// log.debug "$obs"
+ return obs
}
private getSunriseAndSunset(latitude, longitude, forDate) {
- def params = [ uri: "https://api.sunrise-sunset.org/json?lat=$latitude&lng=$longitude&date=$forDate&formatted=0" ]
- def sunRiseAndSet = [:]
- try {
- httpGet(params) { resp -> sunRiseAndSet = resp.data }
- } catch (e) { log.error "http call failed for sunrise and sunset api: $e" }
+ def params = [ uri: "https://api.sunrise-sunset.org/json?lat=$latitude&lng=$longitude&date=$forDate&formatted=0" ]
+ def sunRiseAndSet = [:]
+ try {
+ httpGet(params) { resp -> sunRiseAndSet = resp.data }
+ } catch (e) { log.error "http call failed for sunrise and sunset api: $e" }
- return sunRiseAndSet
+ return sunRiseAndSet
}
-def updateLux() {
- if (!state.sunriseTime || !state.sunsetTime || !state.noonTime || !state.twilight_begin || !state.twilight_end || !state.tz_id)
- return
-
- def tZ = TimeZone.getTimeZone(state.tz_id)
- def lT = new Date().format("yyyy-MM-dd'T'HH:mm:ssXXX", tZ)
- def localTime = new Date().parse("yyyy-MM-dd'T'HH:mm:ssXXX", lT, tZ)
- def sunriseTime = new Date().parse("yyyy-MM-dd'T'HH:mm:ssXXX", state.sunriseTime, tZ)
- def sunsetTime = new Date().parse("yyyy-MM-dd'T'HH:mm:ssXXX", state.sunsetTime, tZ)
- def noonTime = new Date().parse("yyyy-MM-dd'T'HH:mm:ssXXX", state.noonTime, tZ)
- def twilight_begin = new Date().parse("yyyy-MM-dd'T'HH:mm:ssXXX", state.twilight_begin, tZ)
- def twilight_end = new Date().parse("yyyy-MM-dd'T'HH:mm:ssXXX", state.twilight_end, tZ)
- def lux = estimateLux(localTime, sunriseTime, sunsetTime, noonTime, twilight_begin, twilight_end, state.condition_code, state.cloud, state.tz_id)
- sendEvent(name: "illuminance", value: lux, unit: "lux", isStateChange: true, displayed: true)
- sendEvent(name: "illuminated", value: String.format("%,d lux", lux), isStateChange: true, displayed: true)
+private estimateDewPoint(double rh,double t) {
+ def L = Math.log(rh/100)
+ def M = 17.27 * t
+ def N = 237.3 + t
+ def B = (L + (M/N)) / 17.27
+ def dp = (237.3 * B) / (1 - B)
+
+ def dp1 = 243.04 * ( Math.log(rh / 100) + ( (17.625 * t) / (243.04 + t) ) ) / (17.625 - Math.log(rh / 100) - ( (17.625 * t) / (243.04 + t) ) )
+ def ave = (dp + dp1)/2
+ //log.debug "dp: ${dp.round(1)} dp1: ${dp1.round(1)} ave: ${ave.round(1)}"
+ ave = dp1
+ return ave.round(1)
+}
+def updateLux() {
+ if (!state.sunriseTime || !state.sunsetTime || !state.noonTime || !state.twilight_begin || !state.twilight_end || !state.tz_id)
+ return
+
+ def tZ = TimeZone.getTimeZone(state.tz_id)
+ def lT = new Date().format("yyyy-MM-dd'T'HH:mm:ssXXX", tZ)
+ def localTime = new Date().parse("yyyy-MM-dd'T'HH:mm:ssXXX", lT, tZ)
+ def sunriseTime = new Date().parse("yyyy-MM-dd'T'HH:mm:ssXXX", state.sunriseTime, tZ)
+ def sunsetTime = new Date().parse("yyyy-MM-dd'T'HH:mm:ssXXX", state.sunsetTime, tZ)
+ def noonTime = new Date().parse("yyyy-MM-dd'T'HH:mm:ssXXX", state.noonTime, tZ)
+ def twilight_begin = new Date().parse("yyyy-MM-dd'T'HH:mm:ssXXX", state.twilight_begin, tZ)
+ def twilight_end = new Date().parse("yyyy-MM-dd'T'HH:mm:ssXXX", state.twilight_end, tZ)
+ def lux = estimateLux(localTime, sunriseTime, sunsetTime, noonTime, twilight_begin, twilight_end, state.condition_code, state.cloud, state.tz_id)
+ sendEvent(name: "illuminance", value: lux, unit: "lux", /* isStateChange: true, */ displayed: true)
+ sendEvent(name: "illuminated", value: String.format("%,d lux", lux), /* isStateChange: true, */ displayed: true)
}
-private estimateLux(localTime, sunriseTime, sunsetTime, noonTime, twilight_begin, twilight_end, condition_code, cloud, tz_id) {
-// log.debug "condition_code: $condition_code | cloud: $cloud"
-// log.debug "twilight_begin: $twilight_begin | twilight_end: $twilight_end | tz_id: $tz_id"
-// log.debug "localTime: $localTime | sunriseTime: $sunriseTime | noonTime: $noonTime | sunsetTime: $sunsetTime"
-
- def tZ = TimeZone.getTimeZone(tz_id)
- def lux = 0l
- def aFCC = true
- def l
-
- if (timeOfDayIsBetween(sunriseTime, noonTime, localTime, tZ)) {
- log.debug "between sunrise and noon"
- l = (((localTime.getTime() - sunriseTime.getTime()) * 10000f) / (noonTime.getTime() - sunriseTime.getTime()))
- lux = (l < 50f ? 50l : l.trunc(0) as long)
- }
- else if (timeOfDayIsBetween(noonTime, sunsetTime, localTime, tZ)) {
- log.debug "between noon and sunset"
- l = (((sunsetTime.getTime() - localTime.getTime()) * 10000f) / (sunsetTime.getTime() - noonTime.getTime()))
- lux = (l < 50f ? 50l : l.trunc(0) as long)
- }
- else if (timeOfDayIsBetween(twilight_begin, sunriseTime, localTime, tZ)) {
- log.debug "between sunrise and twilight"
- l = (((localTime.getTime() - twilight_begin.getTime()) * 50f) / (sunriseTime.getTime() - twilight_begin.getTime()))
- lux = (l < 10f ? 10l : l.trunc(0) as long)
- }
- else if (timeOfDayIsBetween(sunsetTime, twilight_end, localTime, tZ)) {
- log.debug "between sunset and twilight"
- l = (((twilight_end.getTime() - localTime.getTime()) * 50f) / (twilight_end.getTime() - sunsetTime.getTime()))
- lux = (l < 10f ? 10l : l.trunc(0) as long)
- }
- else if (!timeOfDayIsBetween(twilight_begin, twilight_end, localTime, tZ)) {
- log.debug "between non-twilight"
- lux = 5l
- aFCC = false
- }
-
- def cC = condition_code.toInteger()
- def cCT = ''
- def cCF
- if (aFCC)
- if (conditionFactor[cC]) {
- cCF = conditionFactor[cC][1]
- cCT = conditionFactor[cC][0]
- }
- else {
- cCF = ((100 - (cloud.toInteger() / 3d)) / 100).round(1)
- cCT = 'using cloud cover'
- }
- else {
- cCF = 1.0
- cCT = 'night time now'
- }
-
- lux = (lux * cCF) as long
- log.debug "condition: $cC | condition text: $cCT | condition factor: $cCF | lux: $lux"
- sendEvent(name: "cCF", value: cCF, isStateChange: true, displayed: true)
-
- return lux
+private estimateLux(localTime, sunriseTime, sunsetTime, noonTime, twilight_begin, twilight_end, condition_code, cloud, tz_id) {
+// log.debug "condition_code: $condition_code | cloud: $cloud"
+// log.debug "twilight_begin: $twilight_begin | twilight_end: $twilight_end | tz_id: $tz_id"
+// log.debug "localTime: $localTime | sunriseTime: $sunriseTime | noonTime: $noonTime | sunsetTime: $sunsetTime"
+
+ def tZ = TimeZone.getTimeZone(tz_id)
+ def lux = 0l
+ def aFCC = true
+ def l
+
+ if (timeOfDayIsBetween(sunriseTime, noonTime, localTime, tZ)) {
+ //log.debug "between sunrise and noon"
+ l = (((localTime.getTime() - sunriseTime.getTime()) * 10000f) / (noonTime.getTime() - sunriseTime.getTime()))
+ lux = (l < 50f ? 50l : l.trunc(0) as long)
+ }
+ else if (timeOfDayIsBetween(noonTime, sunsetTime, localTime, tZ)) {
+ //log.debug "between noon and sunset"
+ l = (((sunsetTime.getTime() - localTime.getTime()) * 10000f) / (sunsetTime.getTime() - noonTime.getTime()))
+ lux = (l < 50f ? 50l : l.trunc(0) as long)
+ }
+ else if (timeOfDayIsBetween(twilight_begin, sunriseTime, localTime, tZ)) {
+ //log.debug "between sunrise and twilight"
+ l = (((localTime.getTime() - twilight_begin.getTime()) * 50f) / (sunriseTime.getTime() - twilight_begin.getTime()))
+ lux = (l < 10f ? 10l : l.trunc(0) as long)
+ }
+ else if (timeOfDayIsBetween(sunsetTime, twilight_end, localTime, tZ)) {
+ //log.debug "between sunset and twilight"
+ l = (((twilight_end.getTime() - localTime.getTime()) * 50f) / (twilight_end.getTime() - sunsetTime.getTime()))
+ lux = (l < 10f ? 10l : l.trunc(0) as long)
+ }
+ else if (!timeOfDayIsBetween(twilight_begin, twilight_end, localTime, tZ)) {
+ //log.debug "between non-twilight"
+ lux = 5l
+ aFCC = false
+ }
+
+ def cC = condition_code.toInteger()
+ def cCT = ''
+ def cCF
+ if (aFCC)
+ if (conditionFactor[cC]) {
+ cCF = conditionFactor[cC][1]
+ cCT = conditionFactor[cC][0]
+ }
+ else {
+ cCF = ((100 - (cloud.toInteger() / 3d)) / 100).round(1)
+ cCT = 'using cloud cover'
+ }
+ else {
+ cCF = 1.0
+ cCT = 'night time now'
+ }
+
+ lux = (lux * cCF) as long
+ if(lux > 1100) {
+ long t0 = (lux/300)
+ lux = t0 * 300
+ }
+// log.debug "condition: $cC | condition text: $cCT | condition factor: $cCF | lux: $lux"
+ sendEvent(name: "cCF", value: cCF, /* isStateChange: true, */ displayed: true)
+
+ return lux
}
-private timeOfDayIsBetween(fromDate, toDate, checkDate, timeZone) {
- return (!checkDate.before(fromDate) && !checkDate.after(toDate))
+private timeOfDayIsBetween(fromDate, toDate, checkDate, timeZone) {
+ return (!checkDate.before(fromDate) && !checkDate.after(toDate))
}
-def updateClock() {
- runIn(2, updateClock)
- if (!state.tz_id) return;
- if (!tz_id) return;
- def nowTime = new Date()
- def tZ = TimeZone.getTimeZone(state.tz_id)
- sendEvent(name: "local_time", value: nowTime.format((state.clockSeconds ? "HH:mm" : "HH mm"), tZ), isStateChange: true, displayed: true)
- def localDate = nowTime.format("yyyy-MM-dd", tZ)
- if (localDate != state.localDate)
- { state.localDate = localDate
- sendEvent(name: "local_date", value: localDate, isStateChange: true, displayed: true)
- }
- state.clockSeconds = (state.clockSeconds ? false : true)
+def updateClock() {
+ runIn(2, updateClock)
+ if (!state.tz_id) return;
+ if (!tz_id) return;
+ def nowTime = new Date()
+ def tZ = TimeZone.getTimeZone(state.tz_id)
+ sendEvent(name: "local_time", value: nowTime.format((state.clockSeconds ? "HH:mm" : "HH mm"), tZ), displayed: true)
+ def localDate = nowTime.format("yyyy-MM-dd", tZ)
+ if (localDate != state.localDate) {
+ state.localDate = localDate
+ sendEvent(name: "local_date", value: localDate, displayed: true)
+ }
+ state.clockSeconds = (state.clockSeconds ? false : true)
}
-def getWUIconName(condition_code, is_day) {
- def cC = condition_code.toInteger()
- def wuIcon = (conditionFactor[cC] ? conditionFactor[cC][2] : '')
- if (is_day != 1 && wuIcon) wuIcon = 'nt_' + wuIcon;
- return wuIcon
+def getWUIconName(condition_code, is_day) {
+ def cC = condition_code.toInteger()
+ def wuIcon = (conditionFactor[cC] ? conditionFactor[cC][2] : '')
+ if (is_day != 1 && wuIcon) wuIcon = 'nt_' + wuIcon;
+ return wuIcon
}
-@Field final Map conditionFactor = [
- 1000: ['Sunny', 1, 'sunny'], 1003: ['Partly cloudy', 0.8, 'partlycloudy'],
- 1006: ['Cloudy', 0.6, 'cloudy'], 1009: ['Overcast', 0.5, 'cloudy'],
- 1030: ['Mist', 0.5, 'fog'], 1063: ['Patchy rain possible', 0.8, 'chancerain'],
- 1066: ['Patchy snow possible', 0.6, 'chancesnow'], 1069: ['Patchy sleet possible', 0.6, 'chancesleet'],
- 1072: ['Patchy freezing drizzle possible', 0.4, 'chancesleet'], 1087: ['Thundery outbreaks possible', 0.2, 'chancetstorms'],
- 1114: ['Blowing snow', 0.3, 'snow'], 1117: ['Blizzard', 0.1, 'snow'],
- 1135: ['Fog', 0.2, 'fog'], 1147: ['Freezing fog', 0.1, 'fog'],
- 1150: ['Patchy light drizzle', 0.8, 'rain'], 1153: ['Light drizzle', 0.7, 'rain'],
- 1168: ['Freezing drizzle', 0.5, 'sleet'], 1171: ['Heavy freezing drizzle', 0.2, 'sleet'],
- 1180: ['Patchy light rain', 0.8, 'rain'], 1183: ['Light rain', 0.7, 'rain'],
- 1186: ['Moderate rain at times', 0.5, 'rain'], 1189: ['Moderate rain', 0.4, 'rain'],
- 1192: ['Heavy rain at times', 0.3, 'rain'], 1195: ['Heavy rain', 0.2, 'rain'],
- 1198: ['Light freezing rain', 0.7, 'sleet'], 1201: ['Moderate or heavy freezing rain', 0.3, 'sleet'],
- 1204: ['Light sleet', 0.5, 'sleet'], 1207: ['Moderate or heavy sleet', 0.3, 'sleet'],
- 1210: ['Patchy light snow', 0.8, 'flurries'], 1213: ['Light snow', 0.7, 'snow'],
- 1216: ['Patchy moderate snow', 0.6, 'snow'], 1219: ['Moderate snow', 0.5, 'snow'],
- 1222: ['Patchy heavy snow', 0.4, 'snow'], 1225: ['Heavy snow', 0.3, 'snow'],
- 1237: ['Ice pellets', 0.5, 'sleet'], 1240: ['Light rain shower', 0.8, 'rain'],
- 1243: ['Moderate or heavy rain shower', 0.3, 'rain'], 1246: ['Torrential rain shower', 0.1, 'rain'],
- 1249: ['Light sleet showers', 0.7, 'sleet'], 1252: ['Moderate or heavy sleet showers', 0.5, 'sleet'],
- 1255: ['Light snow showers', 0.7, 'snow'], 1258: ['Moderate or heavy snow showers', 0.5, 'snow'],
- 1261: ['Light showers of ice pellets', 0.7, 'sleet'], 1264: ['Moderate or heavy showers of ice pellets',0.3, 'sleet'],
- 1273: ['Patchy light rain with thunder', 0.5, 'tstorms'], 1276: ['Moderate or heavy rain with thunder', 0.3, 'tstorms'],
- 1279: ['Patchy light snow with thunder', 0.5, 'tstorms'], 1282: ['Moderate or heavy snow with thunder', 0.3, 'tstorms']
- ]
-
-private getImgName(wCode, is_day) {
- def url = "https://cdn.rawgit.com/adey/bangali/master/resources/icons/weather/"
- def imgItem = imgNames.find{ it.code == wCode && it.day == is_day }
- return (url + (imgItem ? imgItem.img : 'na.png'))
+@Field final Map conditionFactor = [
+ 1000: ['Sunny', 1, 'sunny'], 1003: ['Partly cloudy', 0.8, 'partlycloudy'],
+ 1006: ['Cloudy', 0.6, 'cloudy'], 1009: ['Overcast', 0.5, 'cloudy'],
+ 1030: ['Mist', 0.5, 'fog'], 1063: ['Patchy rain possible', 0.8, 'chancerain'],
+ 1066: ['Patchy snow possible', 0.6, 'chancesnow'], 1069: ['Patchy sleet possible', 0.6, 'chancesleet'],
+ 1072: ['Patchy freezing drizzle possible', 0.4, 'chancesleet'], 1087: ['Thundery outbreaks possible', 0.2, 'chancetstorms'],
+ 1114: ['Blowing snow', 0.3, 'snow'], 1117: ['Blizzard', 0.1, 'snow'],
+ 1135: ['Fog', 0.2, 'fog'], 1147: ['Freezing fog', 0.1, 'fog'],
+ 1150: ['Patchy light drizzle', 0.8, 'rain'], 1153: ['Light drizzle', 0.7, 'rain'],
+ 1168: ['Freezing drizzle', 0.5, 'sleet'], 1171: ['Heavy freezing drizzle', 0.2, 'sleet'],
+ 1180: ['Patchy light rain', 0.8, 'rain'], 1183: ['Light rain', 0.7, 'rain'],
+ 1186: ['Moderate rain at times', 0.5, 'rain'], 1189: ['Moderate rain', 0.4, 'rain'],
+ 1192: ['Heavy rain at times', 0.3, 'rain'], 1195: ['Heavy rain', 0.2, 'rain'],
+ 1198: ['Light freezing rain', 0.7, 'sleet'], 1201: ['Moderate or heavy freezing rain', 0.3, 'sleet'],
+ 1204: ['Light sleet', 0.5, 'sleet'], 1207: ['Moderate or heavy sleet', 0.3, 'sleet'],
+ 1210: ['Patchy light snow', 0.8, 'flurries'], 1213: ['Light snow', 0.7, 'snow'],
+ 1216: ['Patchy moderate snow', 0.6, 'snow'], 1219: ['Moderate snow', 0.5, 'snow'],
+ 1222: ['Patchy heavy snow', 0.4, 'snow'], 1225: ['Heavy snow', 0.3, 'snow'],
+ 1237: ['Ice pellets', 0.5, 'sleet'], 1240: ['Light rain shower', 0.8, 'rain'],
+ 1243: ['Moderate or heavy rain shower', 0.3, 'rain'], 1246: ['Torrential rain shower', 0.1, 'rain'],
+ 1249: ['Light sleet showers', 0.7, 'sleet'], 1252: ['Moderate or heavy sleet showers', 0.5, 'sleet'],
+ 1255: ['Light snow showers', 0.7, 'snow'], 1258: ['Moderate or heavy snow showers', 0.5, 'snow'],
+ 1261: ['Light showers of ice pellets', 0.7, 'sleet'], 1264: ['Moderate or heavy showers of ice pellets',0.3, 'sleet'],
+ 1273: ['Patchy light rain with thunder', 0.5, 'tstorms'], 1276: ['Moderate or heavy rain with thunder', 0.3, 'tstorms'],
+ 1279: ['Patchy light snow with thunder', 0.5, 'tstorms'], 1282: ['Moderate or heavy snow with thunder', 0.3, 'tstorms']
+]
+
+private getImgName(wCode, is_day) {
+ def url = "https://cdn.rawgit.com/adey/bangali/master/resources/icons/weather/"
+ def imgItem = imgNames.find{ it.code == wCode && it.day == is_day }
+ return (url + (imgItem ? imgItem.img : 'na.png'))
}
-@Field final List imgNames = [
- [code: 1000, day: 1, img: '32.png', ], // DAY - Sunny
- [code: 1003, day: 1, img: '30.png', ], // DAY - Partly cloudy
- [code: 1006, day: 1, img: '28.png', ], // DAY - Cloudy
- [code: 1009, day: 1, img: '26.png', ], // DAY - Overcast
- [code: 1030, day: 1, img: '20.png', ], // DAY - Mist
- [code: 1063, day: 1, img: '39.png', ], // DAY - Patchy rain possible
- [code: 1066, day: 1, img: '41.png', ], // DAY - Patchy snow possible
- [code: 1069, day: 1, img: '41.png', ], // DAY - Patchy sleet possible
- [code: 1072, day: 1, img: '39.png', ], // DAY - Patchy freezing drizzle possible
- [code: 1087, day: 1, img: '38.png', ], // DAY - Thundery outbreaks possible
- [code: 1114, day: 1, img: '15.png', ], // DAY - Blowing snow
- [code: 1117, day: 1, img: '16.png', ], // DAY - Blizzard
- [code: 1135, day: 1, img: '21.png', ], // DAY - Fog
- [code: 1147, day: 1, img: '21.png', ], // DAY - Freezing fog
- [code: 1150, day: 1, img: '39.png', ], // DAY - Patchy light drizzle
- [code: 1153, day: 1, img: '11.png', ], // DAY - Light drizzle
- [code: 1168, day: 1, img: '8.png', ], // DAY - Freezing drizzle
- [code: 1171, day: 1, img: '10.png', ], // DAY - Heavy freezing drizzle
- [code: 1180, day: 1, img: '39.png', ], // DAY - Patchy light rain
- [code: 1183, day: 1, img: '11.png', ], // DAY - Light rain
- [code: 1186, day: 1, img: '39.png', ], // DAY - Moderate rain at times
- [code: 1189, day: 1, img: '12.png', ], // DAY - Moderate rain
- [code: 1192, day: 1, img: '39.png', ], // DAY - Heavy rain at times
- [code: 1195, day: 1, img: '12.png', ], // DAY - Heavy rain
- [code: 1198, day: 1, img: '8.png', ], // DAY - Light freezing rain
- [code: 1201, day: 1, img: '10.png', ], // DAY - Moderate or heavy freezing rain
- [code: 1204, day: 1, img: '5.png', ], // DAY - Light sleet
- [code: 1207, day: 1, img: '6.png', ], // DAY - Moderate or heavy sleet
- [code: 1210, day: 1, img: '41.png', ], // DAY - Patchy light snow
- [code: 1213, day: 1, img: '18.png', ], // DAY - Light snow
- [code: 1216, day: 1, img: '41.png', ], // DAY - Patchy moderate snow
- [code: 1219, day: 1, img: '16.png', ], // DAY - Moderate snow
- [code: 1222, day: 1, img: '41.png', ], // DAY - Patchy heavy snow
- [code: 1225, day: 1, img: '16.png', ], // DAY - Heavy snow
- [code: 1237, day: 1, img: '18.png', ], // DAY - Ice pellets
- [code: 1240, day: 1, img: '11.png', ], // DAY - Light rain shower
- [code: 1243, day: 1, img: '12.png', ], // DAY - Moderate or heavy rain shower
- [code: 1246, day: 1, img: '12.png', ], // DAY - Torrential rain shower
- [code: 1249, day: 1, img: '5.png', ], // DAY - Light sleet showers
- [code: 1252, day: 1, img: '6.png', ], // DAY - Moderate or heavy sleet showers
- [code: 1255, day: 1, img: '16.png', ], // DAY - Light snow showers
- [code: 1258, day: 1, img: '16.png', ], // DAY - Moderate or heavy snow showers
- [code: 1261, day: 1, img: '8.png', ], // DAY - Light showers of ice pellets
- [code: 1264, day: 1, img: '10.png', ], // DAY - Moderate or heavy showers of ice pellets
- [code: 1273, day: 1, img: '38.png', ], // DAY - Patchy light rain with thunder
- [code: 1276, day: 1, img: '35.png', ], // DAY - Moderate or heavy rain with thunder
- [code: 1279, day: 1, img: '41.png', ], // DAY - Patchy light snow with thunder
- [code: 1282, day: 1, img: '18.png', ], // DAY - Moderate or heavy snow with thunder
- [code: 1000, day: 0, img: '31.png', ], // NIGHT - Clear
- [code: 1003, day: 0, img: '29.png', ], // NIGHT - Partly cloudy
- [code: 1006, day: 0, img: '27.png', ], // NIGHT - Cloudy
- [code: 1009, day: 0, img: '26.png', ], // NIGHT - Overcast
- [code: 1030, day: 0, img: '20.png', ], // NIGHT - Mist
- [code: 1063, day: 0, img: '45.png', ], // NIGHT - Patchy rain possible
- [code: 1066, day: 0, img: '46.png', ], // NIGHT - Patchy snow possible
- [code: 1069, day: 0, img: '46.png', ], // NIGHT - Patchy sleet possible
- [code: 1072, day: 0, img: '45.png', ], // NIGHT - Patchy freezing drizzle possible
- [code: 1087, day: 0, img: '47.png', ], // NIGHT - Thundery outbreaks possible
- [code: 1114, day: 0, img: '15.png', ], // NIGHT - Blowing snow
- [code: 1117, day: 0, img: '16.png', ], // NIGHT - Blizzard
- [code: 1135, day: 0, img: '21.png', ], // NIGHT - Fog
- [code: 1147, day: 0, img: '21.png', ], // NIGHT - Freezing fog
- [code: 1150, day: 0, img: '45.png', ], // NIGHT - Patchy light drizzle
- [code: 1153, day: 0, img: '11.png', ], // NIGHT - Light drizzle
- [code: 1168, day: 0, img: '8.png', ], // NIGHT - Freezing drizzle
- [code: 1171, day: 0, img: '10.png', ], // NIGHT - Heavy freezing drizzle
- [code: 1180, day: 0, img: '45.png', ], // NIGHT - Patchy light rain
- [code: 1183, day: 0, img: '11.png', ], // NIGHT - Light rain
- [code: 1186, day: 0, img: '45.png', ], // NIGHT - Moderate rain at times
- [code: 1189, day: 0, img: '12.png', ], // NIGHT - Moderate rain
- [code: 1192, day: 0, img: '45.png', ], // NIGHT - Heavy rain at times
- [code: 1195, day: 0, img: '12.png', ], // NIGHT - Heavy rain
- [code: 1198, day: 0, img: '8.png', ], // NIGHT - Light freezing rain
- [code: 1201, day: 0, img: '10.png', ], // NIGHT - Moderate or heavy freezing rain
- [code: 1204, day: 0, img: '5.png', ], // NIGHT - Light sleet
- [code: 1207, day: 0, img: '6.png', ], // NIGHT - Moderate or heavy sleet
- [code: 1210, day: 0, img: '41.png', ], // NIGHT - Patchy light snow
- [code: 1213, day: 0, img: '18.png', ], // NIGHT - Light snow
- [code: 1216, day: 0, img: '41.png', ], // NIGHT - Patchy moderate snow
- [code: 1219, day: 0, img: '16.png', ], // NIGHT - Moderate snow
- [code: 1222, day: 0, img: '41.png', ], // NIGHT - Patchy heavy snow
- [code: 1225, day: 0, img: '16.png', ], // NIGHT - Heavy snow
- [code: 1237, day: 0, img: '18.png', ], // NIGHT - Ice pellets
- [code: 1240, day: 0, img: '11.png', ], // NIGHT - Light rain shower
- [code: 1243, day: 0, img: '12.png', ], // NIGHT - Moderate or heavy rain shower
- [code: 1246, day: 0, img: '12.png', ], // NIGHT - Torrential rain shower
- [code: 1249, day: 0, img: '5.png', ], // NIGHT - Light sleet showers
- [code: 1252, day: 0, img: '6.png', ], // NIGHT - Moderate or heavy sleet showers
- [code: 1255, day: 0, img: '16.png', ], // NIGHT - Light snow showers
- [code: 1258, day: 0, img: '16.png', ], // NIGHT - Moderate or heavy snow showers
- [code: 1261, day: 0, img: '8.png', ], // NIGHT - Light showers of ice pellets
- [code: 1264, day: 0, img: '10.png', ], // NIGHT - Moderate or heavy showers of ice pellets
- [code: 1273, day: 0, img: '47.png', ], // NIGHT - Patchy light rain with thunder
- [code: 1276, day: 0, img: '35.png', ], // NIGHT - Moderate or heavy rain with thunder
- [code: 1279, day: 0, img: '46.png', ], // NIGHT - Patchy light snow with thunder
- [code: 1282, day: 0, img: '18.png', ] // NIGHT - Moderate or heavy snow with thunder
+@Field final List imgNames = [
+ [code: 1000, day: 1, img: '32.png', ], // DAY - Sunny
+ [code: 1003, day: 1, img: '30.png', ], // DAY - Partly cloudy
+ [code: 1006, day: 1, img: '28.png', ], // DAY - Cloudy
+ [code: 1009, day: 1, img: '26.png', ], // DAY - Overcast
+ [code: 1030, day: 1, img: '20.png', ], // DAY - Mist
+ [code: 1063, day: 1, img: '39.png', ], // DAY - Patchy rain possible
+ [code: 1066, day: 1, img: '41.png', ], // DAY - Patchy snow possible
+ [code: 1069, day: 1, img: '41.png', ], // DAY - Patchy sleet possible
+ [code: 1072, day: 1, img: '39.png', ], // DAY - Patchy freezing drizzle possible
+ [code: 1087, day: 1, img: '38.png', ], // DAY - Thundery outbreaks possible
+ [code: 1114, day: 1, img: '15.png', ], // DAY - Blowing snow
+ [code: 1117, day: 1, img: '16.png', ], // DAY - Blizzard
+ [code: 1135, day: 1, img: '21.png', ], // DAY - Fog
+ [code: 1147, day: 1, img: '21.png', ], // DAY - Freezing fog
+ [code: 1150, day: 1, img: '39.png', ], // DAY - Patchy light drizzle
+ [code: 1153, day: 1, img: '11.png', ], // DAY - Light drizzle
+ [code: 1168, day: 1, img: '8.png', ], // DAY - Freezing drizzle
+ [code: 1171, day: 1, img: '10.png', ], // DAY - Heavy freezing drizzle
+ [code: 1180, day: 1, img: '39.png', ], // DAY - Patchy light rain
+ [code: 1183, day: 1, img: '11.png', ], // DAY - Light rain
+ [code: 1186, day: 1, img: '39.png', ], // DAY - Moderate rain at times
+ [code: 1189, day: 1, img: '12.png', ], // DAY - Moderate rain
+ [code: 1192, day: 1, img: '39.png', ], // DAY - Heavy rain at times
+ [code: 1195, day: 1, img: '12.png', ], // DAY - Heavy rain
+ [code: 1198, day: 1, img: '8.png', ], // DAY - Light freezing rain
+ [code: 1201, day: 1, img: '10.png', ], // DAY - Moderate or heavy freezing rain
+ [code: 1204, day: 1, img: '5.png', ], // DAY - Light sleet
+ [code: 1207, day: 1, img: '6.png', ], // DAY - Moderate or heavy sleet
+ [code: 1210, day: 1, img: '41.png', ], // DAY - Patchy light snow
+ [code: 1213, day: 1, img: '18.png', ], // DAY - Light snow
+ [code: 1216, day: 1, img: '41.png', ], // DAY - Patchy moderate snow
+ [code: 1219, day: 1, img: '16.png', ], // DAY - Moderate snow
+ [code: 1222, day: 1, img: '41.png', ], // DAY - Patchy heavy snow
+ [code: 1225, day: 1, img: '16.png', ], // DAY - Heavy snow
+ [code: 1237, day: 1, img: '18.png', ], // DAY - Ice pellets
+ [code: 1240, day: 1, img: '11.png', ], // DAY - Light rain shower
+ [code: 1243, day: 1, img: '12.png', ], // DAY - Moderate or heavy rain shower
+ [code: 1246, day: 1, img: '12.png', ], // DAY - Torrential rain shower
+ [code: 1249, day: 1, img: '5.png', ], // DAY - Light sleet showers
+ [code: 1252, day: 1, img: '6.png', ], // DAY - Moderate or heavy sleet showers
+ [code: 1255, day: 1, img: '16.png', ], // DAY - Light snow showers
+ [code: 1258, day: 1, img: '16.png', ], // DAY - Moderate or heavy snow showers
+ [code: 1261, day: 1, img: '8.png', ], // DAY - Light showers of ice pellets
+ [code: 1264, day: 1, img: '10.png', ], // DAY - Moderate or heavy showers of ice pellets
+ [code: 1273, day: 1, img: '38.png', ], // DAY - Patchy light rain with thunder
+ [code: 1276, day: 1, img: '35.png', ], // DAY - Moderate or heavy rain with thunder
+ [code: 1279, day: 1, img: '41.png', ], // DAY - Patchy light snow with thunder
+ [code: 1282, day: 1, img: '18.png', ], // DAY - Moderate or heavy snow with thunder
+ [code: 1000, day: 0, img: '31.png', ], // NIGHT - Clear
+ [code: 1003, day: 0, img: '29.png', ], // NIGHT - Partly cloudy
+ [code: 1006, day: 0, img: '27.png', ], // NIGHT - Cloudy
+ [code: 1009, day: 0, img: '26.png', ], // NIGHT - Overcast
+ [code: 1030, day: 0, img: '20.png', ], // NIGHT - Mist
+ [code: 1063, day: 0, img: '45.png', ], // NIGHT - Patchy rain possible
+ [code: 1066, day: 0, img: '46.png', ], // NIGHT - Patchy snow possible
+ [code: 1069, day: 0, img: '46.png', ], // NIGHT - Patchy sleet possible
+ [code: 1072, day: 0, img: '45.png', ], // NIGHT - Patchy freezing drizzle possible
+ [code: 1087, day: 0, img: '47.png', ], // NIGHT - Thundery outbreaks possible
+ [code: 1114, day: 0, img: '15.png', ], // NIGHT - Blowing snow
+ [code: 1117, day: 0, img: '16.png', ], // NIGHT - Blizzard
+ [code: 1135, day: 0, img: '21.png', ], // NIGHT - Fog
+ [code: 1147, day: 0, img: '21.png', ], // NIGHT - Freezing fog
+ [code: 1150, day: 0, img: '45.png', ], // NIGHT - Patchy light drizzle
+ [code: 1153, day: 0, img: '11.png', ], // NIGHT - Light drizzle
+ [code: 1168, day: 0, img: '8.png', ], // NIGHT - Freezing drizzle
+ [code: 1171, day: 0, img: '10.png', ], // NIGHT - Heavy freezing drizzle
+ [code: 1180, day: 0, img: '45.png', ], // NIGHT - Patchy light rain
+ [code: 1183, day: 0, img: '11.png', ], // NIGHT - Light rain
+ [code: 1186, day: 0, img: '45.png', ], // NIGHT - Moderate rain at times
+ [code: 1189, day: 0, img: '12.png', ], // NIGHT - Moderate rain
+ [code: 1192, day: 0, img: '45.png', ], // NIGHT - Heavy rain at times
+ [code: 1195, day: 0, img: '12.png', ], // NIGHT - Heavy rain
+ [code: 1198, day: 0, img: '8.png', ], // NIGHT - Light freezing rain
+ [code: 1201, day: 0, img: '10.png', ], // NIGHT - Moderate or heavy freezing rain
+ [code: 1204, day: 0, img: '5.png', ], // NIGHT - Light sleet
+ [code: 1207, day: 0, img: '6.png', ], // NIGHT - Moderate or heavy sleet
+ [code: 1210, day: 0, img: '41.png', ], // NIGHT - Patchy light snow
+ [code: 1213, day: 0, img: '18.png', ], // NIGHT - Light snow
+ [code: 1216, day: 0, img: '41.png', ], // NIGHT - Patchy moderate snow
+ [code: 1219, day: 0, img: '16.png', ], // NIGHT - Moderate snow
+ [code: 1222, day: 0, img: '41.png', ], // NIGHT - Patchy heavy snow
+ [code: 1225, day: 0, img: '16.png', ], // NIGHT - Heavy snow
+ [code: 1237, day: 0, img: '18.png', ], // NIGHT - Ice pellets
+ [code: 1240, day: 0, img: '11.png', ], // NIGHT - Light rain shower
+ [code: 1243, day: 0, img: '12.png', ], // NIGHT - Moderate or heavy rain shower
+ [code: 1246, day: 0, img: '12.png', ], // NIGHT - Torrential rain shower
+ [code: 1249, day: 0, img: '5.png', ], // NIGHT - Light sleet showers
+ [code: 1252, day: 0, img: '6.png', ], // NIGHT - Moderate or heavy sleet showers
+ [code: 1255, day: 0, img: '16.png', ], // NIGHT - Light snow showers
+ [code: 1258, day: 0, img: '16.png', ], // NIGHT - Moderate or heavy snow showers
+ [code: 1261, day: 0, img: '8.png', ], // NIGHT - Light showers of ice pellets
+ [code: 1264, day: 0, img: '10.png', ], // NIGHT - Moderate or heavy showers of ice pellets
+ [code: 1273, day: 0, img: '47.png', ], // NIGHT - Patchy light rain with thunder
+ [code: 1276, day: 0, img: '35.png', ], // NIGHT - Moderate or heavy rain with thunder
+ [code: 1279, day: 0, img: '46.png', ], // NIGHT - Patchy light snow with thunder
+ [code: 1282, day: 0, img: '18.png', ] // NIGHT - Moderate or heavy snow with thunder
]
//**********************************************************************************************************************