WWST-2091 Converted SmartWeather Station to TWC APIs (#3802)

This commit is contained in:
Bob Florian
2018-12-20 11:33:10 -08:00
committed by GitHub
parent 2c62a9378f
commit 044330ee8d

View File

@@ -17,355 +17,362 @@
* Date: 2013-04-30
*/
metadata {
definition (name: "SmartWeather Station Tile", namespace: "smartthings", author: "SmartThings") {
capability "Illuminance Measurement"
capability "Temperature Measurement"
capability "Relative Humidity Measurement"
capability "Ultraviolet Index"
capability "Sensor"
definition (name: "SmartWeather Station Tile", namespace: "smartthings", author: "SmartThings") {
capability "Illuminance Measurement"
capability "Temperature Measurement"
capability "Relative Humidity Measurement"
capability "Ultraviolet Index"
capability "Sensor"
capability "Refresh"
attribute "localSunrise", "string"
attribute "localSunset", "string"
attribute "city", "string"
attribute "timeZoneOffset", "string"
attribute "weather", "string"
attribute "wind", "string"
attribute "weatherIcon", "string"
attribute "forecastIcon", "string"
attribute "feelsLike", "string"
attribute "percentPrecip", "string"
attribute "alert", "string"
attribute "alertKeys", "string"
attribute "sunriseDate", "string"
attribute "sunsetDate", "string"
attribute "lastUpdate", "string"
attribute "localSunrise", "string"
attribute "localSunset", "string"
attribute "city", "string"
attribute "timeZoneOffset", "string"
attribute "weather", "string"
attribute "wind", "string"
attribute "windVector", "string"
attribute "weatherIcon", "string"
attribute "forecastIcon", "string"
attribute "feelsLike", "string"
attribute "percentPrecip", "string"
attribute "alert", "string"
attribute "alertKeys", "string"
attribute "sunriseDate", "string"
attribute "sunsetDate", "string"
attribute "lastUpdate", "string"
attribute "uvDescription", "string"
attribute "forecastToday", "string"
attribute "forecastTonight", "string"
attribute "forecastTomorrow", "string"
}
command "refresh"
}
preferences {
input "zipCode", "text", title: "Zip Code (optional)", required: false
}
preferences {
input "zipCode", "text", title: "Zip Code (optional)", required: false
}
tiles {
valueTile("temperature", "device.temperature") {
state "default", label:'${currentValue}°',
backgroundColors:[
[value: 31, color: "#153591"],
[value: 44, color: "#1e9cbb"],
[value: 59, color: "#90d2a7"],
[value: 74, color: "#44b621"],
[value: 84, color: "#f1d801"],
[value: 95, color: "#d04e00"],
[value: 96, color: "#bc2323"]
]
}
tiles {
valueTile("temperature", "device.temperature") {
state "default", label:'${currentValue}°',
backgroundColors:[
[value: 31, color: "#153591"],
[value: 44, color: "#1e9cbb"],
[value: 59, color: "#90d2a7"],
[value: 74, color: "#44b621"],
[value: 84, color: "#f1d801"],
[value: 95, color: "#d04e00"],
[value: 96, color: "#bc2323"]
]
}
valueTile("humidity", "device.humidity", decoration: "flat") {
state "default", label:'${currentValue}% humidity'
}
valueTile("humidity", "device.humidity", decoration: "flat") {
state "default", label:'${currentValue}% humidity'
}
standardTile("weatherIcon", "device.weatherIcon", decoration: "flat") {
state "00", icon:"https://smartthings-twc-icons.s3.amazonaws.com/00.png", label: ""
state "01", icon:"https://smartthings-twc-icons.s3.amazonaws.com/01.png", label: ""
state "02", icon:"https://smartthings-twc-icons.s3.amazonaws.com/02.png", label: ""
state "03", icon:"https://smartthings-twc-icons.s3.amazonaws.com/03.png", label: ""
state "04", icon:"https://smartthings-twc-icons.s3.amazonaws.com/04.png", label: ""
state "05", icon:"https://smartthings-twc-icons.s3.amazonaws.com/05.png", label: ""
state "06", icon:"https://smartthings-twc-icons.s3.amazonaws.com/06.png", label: ""
state "07", icon:"https://smartthings-twc-icons.s3.amazonaws.com/07.png", label: ""
state "08", icon:"https://smartthings-twc-icons.s3.amazonaws.com/08.png", label: ""
state "09", icon:"https://smartthings-twc-icons.s3.amazonaws.com/09.png", label: ""
state "10", icon:"https://smartthings-twc-icons.s3.amazonaws.com/10.png", label: ""
state "11", icon:"https://smartthings-twc-icons.s3.amazonaws.com/11.png", label: ""
state "12", icon:"https://smartthings-twc-icons.s3.amazonaws.com/12.png", label: ""
state "13", icon:"https://smartthings-twc-icons.s3.amazonaws.com/13.png", label: ""
state "14", icon:"https://smartthings-twc-icons.s3.amazonaws.com/14.png", label: ""
state "15", icon:"https://smartthings-twc-icons.s3.amazonaws.com/15.png", label: ""
state "16", icon:"https://smartthings-twc-icons.s3.amazonaws.com/16.png", label: ""
state "17", icon:"https://smartthings-twc-icons.s3.amazonaws.com/17.png", label: ""
state "18", icon:"https://smartthings-twc-icons.s3.amazonaws.com/18.png", label: ""
state "19", icon:"https://smartthings-twc-icons.s3.amazonaws.com/19.png", label: ""
state "20", icon:"https://smartthings-twc-icons.s3.amazonaws.com/20.png", label: ""
state "21", icon:"https://smartthings-twc-icons.s3.amazonaws.com/21.png", label: ""
state "22", icon:"https://smartthings-twc-icons.s3.amazonaws.com/22.png", label: ""
state "23", icon:"https://smartthings-twc-icons.s3.amazonaws.com/23.png", label: ""
state "24", icon:"https://smartthings-twc-icons.s3.amazonaws.com/24.png", label: ""
state "25", icon:"https://smartthings-twc-icons.s3.amazonaws.com/25.png", label: ""
state "26", icon:"https://smartthings-twc-icons.s3.amazonaws.com/26.png", label: ""
state "27", icon:"https://smartthings-twc-icons.s3.amazonaws.com/27.png", label: ""
state "28", icon:"https://smartthings-twc-icons.s3.amazonaws.com/28.png", label: ""
state "29", icon:"https://smartthings-twc-icons.s3.amazonaws.com/29.png", label: ""
state "30", icon:"https://smartthings-twc-icons.s3.amazonaws.com/30.png", label: ""
state "31", icon:"https://smartthings-twc-icons.s3.amazonaws.com/31.png", label: ""
state "32", icon:"https://smartthings-twc-icons.s3.amazonaws.com/32.png", label: ""
state "33", icon:"https://smartthings-twc-icons.s3.amazonaws.com/33.png", label: ""
state "34", icon:"https://smartthings-twc-icons.s3.amazonaws.com/34.png", label: ""
state "35", icon:"https://smartthings-twc-icons.s3.amazonaws.com/35.png", label: ""
state "36", icon:"https://smartthings-twc-icons.s3.amazonaws.com/36.png", label: ""
state "37", icon:"https://smartthings-twc-icons.s3.amazonaws.com/37.png", label: ""
state "38", icon:"https://smartthings-twc-icons.s3.amazonaws.com/38.png", label: ""
state "39", icon:"https://smartthings-twc-icons.s3.amazonaws.com/39.png", label: ""
state "40", icon:"https://smartthings-twc-icons.s3.amazonaws.com/40.png", label: ""
state "41", icon:"https://smartthings-twc-icons.s3.amazonaws.com/41.png", label: ""
state "42", icon:"https://smartthings-twc-icons.s3.amazonaws.com/42.png", label: ""
state "43", icon:"https://smartthings-twc-icons.s3.amazonaws.com/43.png", label: ""
state "44", icon:"https://smartthings-twc-icons.s3.amazonaws.com/44.png", label: ""
state "45", icon:"https://smartthings-twc-icons.s3.amazonaws.com/45.png", label: ""
state "46", icon:"https://smartthings-twc-icons.s3.amazonaws.com/46.png", label: ""
state "47", icon:"https://smartthings-twc-icons.s3.amazonaws.com/47.png", label: ""
state "na", icon:"https://smartthings-twc-icons.s3.amazonaws.com/na.png", label: ""
}
standardTile("weatherIcon", "device.weatherIcon", decoration: "flat") {
state "chanceflurries", icon:"st.custom.wu1.chanceflurries", label: ""
state "chancerain", icon:"st.custom.wu1.chancerain", label: ""
state "chancesleet", icon:"st.custom.wu1.chancesleet", label: ""
state "chancesnow", icon:"st.custom.wu1.chancesnow", label: ""
state "chancetstorms", icon:"st.custom.wu1.chancetstorms", label: ""
state "clear", icon:"st.custom.wu1.clear", label: ""
state "cloudy", icon:"st.custom.wu1.cloudy", label: ""
state "flurries", icon:"st.custom.wu1.flurries", label: ""
state "fog", icon:"st.custom.wu1.fog", label: ""
state "hazy", icon:"st.custom.wu1.hazy", label: ""
state "mostlycloudy", icon:"st.custom.wu1.mostlycloudy", label: ""
state "mostlysunny", icon:"st.custom.wu1.mostlysunny", label: ""
state "partlycloudy", icon:"st.custom.wu1.partlycloudy", label: ""
state "partlysunny", icon:"st.custom.wu1.partlysunny", label: ""
state "rain", icon:"st.custom.wu1.rain", label: ""
state "sleet", icon:"st.custom.wu1.sleet", label: ""
state "snow", icon:"st.custom.wu1.snow", label: ""
state "sunny", icon:"st.custom.wu1.sunny", label: ""
state "tstorms", icon:"st.custom.wu1.tstorms", label: ""
state "cloudy", icon:"st.custom.wu1.cloudy", label: ""
state "partlycloudy", icon:"st.custom.wu1.partlycloudy", label: ""
state "nt_chanceflurries", icon:"st.custom.wu1.nt_chanceflurries", label: ""
state "nt_chancerain", icon:"st.custom.wu1.nt_chancerain", label: ""
state "nt_chancesleet", icon:"st.custom.wu1.nt_chancesleet", label: ""
state "nt_chancesnow", icon:"st.custom.wu1.nt_chancesnow", label: ""
state "nt_chancetstorms", icon:"st.custom.wu1.nt_chancetstorms", label: ""
state "nt_clear", icon:"st.custom.wu1.nt_clear", label: ""
state "nt_cloudy", icon:"st.custom.wu1.nt_cloudy", label: ""
state "nt_flurries", icon:"st.custom.wu1.nt_flurries", label: ""
state "nt_fog", icon:"st.custom.wu1.nt_fog", label: ""
state "nt_hazy", icon:"st.custom.wu1.nt_hazy", label: ""
state "nt_mostlycloudy", icon:"st.custom.wu1.nt_mostlycloudy", label: ""
state "nt_mostlysunny", icon:"st.custom.wu1.nt_mostlysunny", label: ""
state "nt_partlycloudy", icon:"st.custom.wu1.nt_partlycloudy", label: ""
state "nt_partlysunny", icon:"st.custom.wu1.nt_partlysunny", label: ""
state "nt_sleet", icon:"st.custom.wu1.nt_sleet", label: ""
state "nt_rain", icon:"st.custom.wu1.nt_rain", label: ""
state "nt_sleet", icon:"st.custom.wu1.nt_sleet", label: ""
state "nt_snow", icon:"st.custom.wu1.nt_snow", label: ""
state "nt_sunny", icon:"st.custom.wu1.nt_sunny", label: ""
state "nt_tstorms", icon:"st.custom.wu1.nt_tstorms", label: ""
state "nt_cloudy", icon:"st.custom.wu1.nt_cloudy", label: ""
state "nt_partlycloudy", icon:"st.custom.wu1.nt_partlycloudy", label: ""
}
valueTile("feelsLike", "device.feelsLike", decoration: "flat") {
state "default", label:'feels like ${currentValue}°'
}
valueTile("feelsLike", "device.feelsLike", decoration: "flat") {
state "default", label:'feels like ${currentValue}°'
}
valueTile("wind", "device.wind", decoration: "flat") {
state "default", label:'wind ${currentValue} mph'
}
valueTile("wind", "device.windVector", decoration: "flat") {
state "default", label:'wind ${currentValue}'
}
valueTile("weather", "device.weather", decoration: "flat") {
state "default", label:'${currentValue}'
}
valueTile("weather", "device.weather", decoration: "flat") {
state "default", label:'${currentValue}'
}
valueTile("city", "device.city", decoration: "flat") {
state "default", label:'${currentValue}'
}
valueTile("city", "device.city", decoration: "flat") {
state "default", label:'${currentValue}'
}
valueTile("percentPrecip", "device.percentPrecip", decoration: "flat") {
state "default", label:'${currentValue}% precip'
}
valueTile("percentPrecip", "device.percentPrecip", decoration: "flat") {
state "default", label:'${currentValue}% precip'
}
valueTile("ultravioletIndex", "device.ultravioletIndex", decoration: "flat") {
state "default", label:'${currentValue} UV index'
}
valueTile("ultravioletIndex", "device.uvDescription", decoration: "flat") {
state "default", label:'UV ${currentValue}'
}
valueTile("alert", "device.alert", width: 2, height: 1, decoration: "flat") {
state "default", label:'${currentValue}'
}
standardTile("refresh", "device.weather", decoration: "flat") {
state "default", label: "", action: "refresh", icon:"st.secondary.refresh"
}
valueTile("alert", "device.alert", width: 2, height: 1, decoration: "flat") {
state "default", label:'${currentValue}'
}
valueTile("rise", "device.localSunrise", decoration: "flat") {
state "default", label:'Sunrise ${currentValue}'
}
standardTile("refresh", "device.weather", decoration: "flat") {
state "default", label: "", action: "refresh", icon:"st.secondary.refresh"
}
valueTile("set", "device.localSunset", decoration: "flat") {
state "default", label:'Sunset ${currentValue}'
}
valueTile("rise", "device.localSunrise", decoration: "flat") {
state "default", label:'Sunrise ${currentValue}'
}
valueTile("light", "device.illuminance", decoration: "flat") {
state "default", label:'${currentValue} lux'
}
valueTile("lastUpdate", "device.lastUpdate", width: 3, height: 1, decoration: "flat") {
state "default", label:'Last update:\n${currentValue}'
}
valueTile("set", "device.localSunset", decoration: "flat") {
state "default", label:'Sunset ${currentValue}'
}
main(["temperature", "weatherIcon","feelsLike"])
details(["temperature", "humidity", "weatherIcon", "feelsLike", "wind", "weather", "city", "percentPrecip", "ultravioletIndex", "alert", "refresh", "rise", "set", "light", "lastUpdate"])}
valueTile("light", "device.illuminance", decoration: "flat") {
state "default", label:'${currentValue} lux'
}
valueTile("city", "device.forecastToday", decoration: "flat") {
state "default", label:'Today: ${currentValue}'
}
valueTile("city", "device.forecastTonight", decoration: "flat") {
state "default", label:'Tonight: ${currentValue}'
}
valueTile("city", "device.forecastTomorrow", decoration: "flat") {
state "default", label:'Tomorrow: ${currentValue}'
}
valueTile("lastUpdate", "device.lastUpdate", width: 3, height: 1, decoration: "flat") {
state "default", label:'Last update:\n${currentValue}'
}
main(["temperature", "weatherIcon","feelsLike"])
details(["temperature", "humidity", "weatherIcon", "feelsLike", "wind",
"weather", "city", "percentPrecip", "ultravioletIndex", "alert",
"refresh", "rise", "set", "light", "lastUpdate"])}
}
// parse events into attributes
def parse(String description) {
log.debug "Parsing '${description}'"
log.debug "Parsing '${description}'"
}
def installed() {
poll()
runEvery30Minutes(poll)
poll()
runEvery30Minutes(poll)
}
def uninstalled() {
unschedule()
unschedule()
}
// handle commands
def poll() {
log.debug "WUSTATION: Executing 'poll', location: ${location.name}"
log.info "WUSTATION: Executing 'poll', location: ${location.name}"
// Last update time stamp
def timeStamp = new Date().format("yyyy MMM dd EEE h:mm:ss a", location.timeZone)
sendEvent(name: "lastUpdate", value: timeStamp)
// Last update time stamp
def timeStamp = new Date().format("yyyy MMM dd EEE h:mm:ss a", location.timeZone)
sendEvent(name: "lastUpdate", value: timeStamp)
// Current conditions
def obs = get("conditions")?.current_observation
if (obs) {
def weatherIcon = obs.icon_url.split("/")[-1].split("\\.")[0]
// Current conditions
def tempUnits = getTemperatureScale()
def obs = getTwcConditions(zipCode)
if (obs) {
// TODO def weatherIcon = obs.icon_url.split("/")[-1].split("\\.")[0]
if(getTemperatureScale() == "C") {
send(name: "temperature", value: Math.round(obs.temp_c), unit: "C")
send(name: "feelsLike", value: Math.round(obs.feelslike_c as Double), unit: "C")
} else {
send(name: "temperature", value: Math.round(obs.temp_f), unit: "F")
send(name: "feelsLike", value: Math.round(obs.feelslike_f as Double), unit: "F")
}
send(name: "humidity", value: obs.relative_humidity[0..-2] as Integer, unit: "%")
send(name: "weather", value: obs.weather)
send(name: "weatherIcon", value: weatherIcon, displayed: false)
send(name: "wind", value: Math.round(obs.wind_mph) as String, unit: "MPH") // as String because of bug in determining state change of 0 numbers
send(name: "temperature", value: obs.temperature, unit: tempUnits)
send(name: "feelsLike", value: obs.temperatureFeelsLike, unit: tempUnits)
if (obs.local_tz_offset != device.currentValue("timeZoneOffset")) {
send(name: "timeZoneOffset", value: obs.local_tz_offset, isStateChange: true)
}
send(name: "humidity", value: obs.relativeHumidity, unit: "%")
send(name: "weather", value: obs.wxPhraseShort)
send(name: "weatherIcon", value: obs.iconCode as String, displayed: false)
send(name: "wind", value: obs.windSpeed as String, unit: tempUnits == "C" ? "KPH" : "MPH") // as String because of bug in determining state change of 0 numbers
send(name: "windVector", value: "${obs.windDirectionCardinal}@${obs.windSpeed}", unit: tempUnits == "C" ? "KPH" : "MPH")
log.trace "Getting location info"
def loc = getTwcLocation(zipCode).location
def cityValue = "${loc.city}, ${loc.adminDistrictCode} ${loc.countryCode}"
if (cityValue != device.currentValue("city")) {
send(name: "city", value: cityValue, isStateChange: true)
}
def cityValue = "${obs.display_location.city}, ${obs.display_location.state}"
if (cityValue != device.currentValue("city")) {
send(name: "city", value: cityValue, isStateChange: true)
}
send(name: "ultravioletIndex", value: obs.uvIndex)
send(name: "uvDescription", value: obs.uvDescription)
send(name: "ultravioletIndex", value: Math.round(obs.UV as Double))
def dtf = new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
// Sunrise / Sunset
def a = get("astronomy")?.moon_phase
def today = localDate("GMT${obs.local_tz_offset}")
def ltf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm")
ltf.setTimeZone(TimeZone.getTimeZone("GMT${obs.local_tz_offset}"))
def utf = new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
utf.setTimeZone(TimeZone.getTimeZone("GMT"))
def sunriseDate = dtf.parse(obs.sunriseTimeLocal)
log.info "'${obs.sunriseTimeLocal}'"
def sunriseDate = ltf.parse("${today} ${a.sunrise.hour}:${a.sunrise.minute}")
def sunsetDate = ltf.parse("${today} ${a.sunset.hour}:${a.sunset.minute}")
def sunsetDate = dtf.parse(obs.sunsetTimeLocal)
def tf = new java.text.SimpleDateFormat("h:mm a")
tf.setTimeZone(TimeZone.getTimeZone("GMT${obs.local_tz_offset}"))
tf.setTimeZone(TimeZone.getTimeZone(loc.ianaTimeZone))
def localSunrise = "${tf.format(sunriseDate)}"
def localSunset = "${tf.format(sunsetDate)}"
send(name: "localSunrise", value: localSunrise, descriptionText: "Sunrise today is at $localSunrise")
send(name: "localSunset", value: localSunset, descriptionText: "Sunset today at is $localSunset")
send(name: "illuminance", value: estimateLux(sunriseDate, sunsetDate, weatherIcon))
send(name: "illuminance", value: estimateLux(obs, sunriseDate, sunsetDate))
// Forecast
def f = get("forecast")
def f1= f?.forecast?.simpleforecast?.forecastday
if (f1) {
def icon = f1[0].icon_url.split("/")[-1].split("\\.")[0]
def value = f1[0].pop as String // as String because of bug in determining state change of 0 numbers
send(name: "percentPrecip", value: value, unit: "%")
send(name: "forecastIcon", value: icon, displayed: false)
}
else {
log.warn "Forecast not found"
}
// Forecast
def f = getTwcForecast(zipCode)
if (f) {
def icon = f.daypart[0].iconCode[0] ?: f.daypart[0].iconCode[1]
def value = f.daypart[0].precipChance[0] ?: f.daypart[0].precipChance[1]
def narrative = f.daypart[0].narrative
send(name: "percentPrecip", value: value, unit: "%")
send(name: "forecastIcon", value: icon, displayed: false)
send(name: "forecastToday", value: narrative[0])
send(name: "forecastTonight", value: narrative[1])
send(name: "forecastTomorrow", value: narrative[2])
}
else {
log.warn "Forecast not found"
}
// Alerts
def alerts = get("alerts")?.alerts
def newKeys = alerts?.collect{it.type + it.date_epoch} ?: []
log.debug "WUSTATION: newKeys = $newKeys"
log.trace device.currentState("alertKeys")
def oldKeys = device.currentState("alertKeys")?.jsonValue
log.debug "WUSTATION: oldKeys = $oldKeys"
// Alerts
def alerts = getTwcAlerts(zipCode)
if (alerts) {
alerts.each {alert ->
def msg = alert.headlineText
if (alert.effectiveTimeLocal && !msg.contains(" from ")) {
msg += " from ${parseAlertTime(alert.effectiveTimeLocal).format("E hh:mm a", TimeZone.getTimeZone(alert.effectiveTimeLocalTimeZone))}"
}
if (alert.expireTimeLocal && !msg.contains(" until ")) {
msg += " until ${parseAlertTime(alert.expireTimeLocal).format("E hh:mm a", TimeZone.getTimeZone(alert.expireTimeLocalTimeZone))}"
}
send(name: "alert", value: msg, descriptionText: msg)
}
}
else {
send(name: "alert", value: "No current alerts", descriptionText: msg)
}
}
else {
log.warn "No response from TWC API"
}
}
def noneString = "no current weather alerts"
if (!newKeys && oldKeys == null) {
send(name: "alertKeys", value: newKeys.encodeAsJSON(), displayed: false)
send(name: "alert", value: noneString, descriptionText: "${device.displayName} has no current weather alerts", isStateChange: true)
}
else if (newKeys != oldKeys) {
if (oldKeys == null) {
oldKeys = []
}
send(name: "alertKeys", value: newKeys.encodeAsJSON(), displayed: false)
def newAlerts = false
alerts.each {alert ->
if (!oldKeys.contains(alert.type + alert.date_epoch)) {
def msg = "${alert.description} from ${alert.date} until ${alert.expires}"
send(name: "alert", value: pad(alert.description), descriptionText: msg, isStateChange: true)
newAlerts = true
}
}
if (!newAlerts && device.currentValue("alert") != noneString) {
send(name: "alert", value: noneString, descriptionText: "${device.displayName} has no current weather alerts", isStateChange: true)
}
}
}
else {
log.warn "No response from Weather Underground API"
}
def parseAlertTime(s) {
def dtf = new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
def s2 = s.replaceAll(/([0-9][0-9]):([0-9][0-9])$/,'$1$2')
dtf.parse(s2)
}
def refresh() {
poll()
poll()
}
def configure() {
poll()
poll()
}
private pad(String s, size = 25) {
def n = (size - s.size()) / 2
if (n > 0) {
def sb = ""
n.times {sb += " "}
sb += s
n.times {sb += " "}
return sb
}
else {
return s
}
def n = (size - s.size()) / 2
if (n > 0) {
def sb = ""
n.times {sb += " "}
sb += s
n.times {sb += " "}
return sb
}
else {
return s
}
}
private get(feature) {
getWeatherFeature(feature, zipCode)
getWeatherFeature(feature, zipCode)
}
private localDate(timeZone) {
def df = new java.text.SimpleDateFormat("yyyy-MM-dd")
df.setTimeZone(TimeZone.getTimeZone(timeZone))
df.format(new Date())
def df = new java.text.SimpleDateFormat("yyyy-MM-dd")
df.setTimeZone(TimeZone.getTimeZone(timeZone))
df.format(new Date())
}
private send(map) {
log.debug "WUSTATION: event: $map"
sendEvent(map)
log.debug "WUSTATION: event: $map"
sendEvent(map)
}
private estimateLux(sunriseDate, sunsetDate, weatherIcon) {
def lux = 0
def now = new Date().time
if (now > sunriseDate.time && now < sunsetDate.time) {
//day
switch(weatherIcon) {
case 'tstorms':
lux = 200
break
case ['cloudy', 'fog', 'rain', 'sleet', 'snow', 'flurries',
'chanceflurries', 'chancerain', 'chancesleet',
'chancesnow', 'chancetstorms']:
lux = 1000
break
case 'mostlycloudy':
lux = 2500
break
case ['partlysunny', 'partlycloudy', 'hazy']:
lux = 7500
break
default:
//sunny, clear
lux = 10000
}
private estimateLux(obs, sunriseDate, sunsetDate) {
def lux = 0
if (obs.dayOrNight == 'N') {
lux = 10
}
else {
//day
switch(obs.iconCode) {
case '04':
lux = 200
break
case ['05', '06', '07', '08', '09', '10',
'11', '12', '13','14', '15','17','18','19','20',
'21','22','23','24','25','26']:
lux = 1000
break
case ['27', '28']:
lux = 2500
break
case ['29', '30']:
lux = 7500
break
default:
//sunny, clear
lux = 10000
}
//adjust for dusk/dawn
def afterSunrise = now - sunriseDate.time
def beforeSunset = sunsetDate.time - now
def oneHour = 1000 * 60 * 60
//adjust for dusk/dawn
def now = new Date().time
def afterSunrise = now - sunriseDate.time
def beforeSunset = sunsetDate.time - now
def oneHour = 1000 * 60 * 60
if(afterSunrise < oneHour) {
//dawn
lux = (long)(lux * (afterSunrise/oneHour))
} else if (beforeSunset < oneHour) {
//dusk
lux = (long)(lux * (beforeSunset/oneHour))
}
}
else {
//night - always set to 10 for now
//could do calculations for dusk/dawn too
lux = 10
}
lux
}
if(afterSunrise < oneHour) {
//dawn
lux = (long)(lux * (afterSunrise/oneHour))
} else if (beforeSunset < oneHour) {
//dusk
lux = (long)(lux * (beforeSunset/oneHour))
}
}
lux
}