[OBSOLETE] Weather Station Tile 2.0

Brilliant. Well done @Ghosted.
Now things are working as they should.

So my OCD kicked in and I did some minor adjustments to make everything (according to me) look a little bit better.

Changes:

REMOVED Solar Radiation. It nevers displays for me.
Sunrise & Sunset now in 24 Hour Mode
Last Updated now in 24 Hour Mode
Humidity moved instead of feels like and vice-versa
Added “Wind” wording to Wind Forecast
Removed “LUX” wording and added it as a “lux” unit
REMOVED Forecast For. Was cramming things up a bit

/**
*  Copyright 2015 SmartThings
*
*  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
*
*  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
*  for the specific language governing permissions and limitations under the License.
*
*  SmartWeather Station
*
*  Author: SmartThings
*
*  Date: 2013-04-30
*/
metadata {
    definition (name: "SmartWeather Station Tile 2.0", namespace: "takis", author: "Takis") {
        capability "Illuminance Measurement"
        capability "Temperature Measurement"
        capability "Relative Humidity Measurement"
        capability "Sensor"
        capability "Polling"

        attribute "localSunrise", "string"
        attribute "localSunset", "string"
        attribute "city", "string"
        attribute "timeZoneOffset", "string"
        attribute "weather", "string"
        attribute "wind", "string"
        attribute "winddirection", "string"
        attribute "wind_gust", "string"
        attribute "winddirection_deg", "string"
        attribute "windinfo", "string"
        attribute "uv_index", "string"
        attribute "water", "string"
        attribute "weatherIcon", "string"
        attribute "forecastIcon", "string"
        attribute "feelsLike", "string"
        attribute "percentPrecip", "string"
        attribute "percentPrecipToday", "string"
        attribute "percentPrecipLastHour", "string"
        attribute "alert", "string"
        attribute "alertKeys", "string"
        attribute "sunriseDate", "string"
        attribute "sunsetDate", "string"
        attribute "dewpoint", "string"
        attribute "wind_degrees", "string"
        attribute "pressure", "string"
        attribute "solarradiation", "string"
        attribute "visibility", "string"
        attribute "pressureTrend", "string"
        
        command "refresh"
    }

    preferences {
        input "zipCode", "text", title: "Zip Code (optional)", required: false
        input (description: "Setting the Barometer Pressure units (optional)", 
            title: "Pressure units", displayDuringSetup: false, type: "paragraph", element: "paragraph")
        input ("pres_units", "enum", title: "Pressure units", required: false, 
			options: [
		        "press_in":"Inches",
		        "press_mb":"milli bars"
            ])
        input (description: "Setting the distance units (optional)",
			title: "Distance Units", displayDuringSetup: false, type: "paragraph", element: "paragraph")
        input ("dist_units", "enum", title: "Distance units", required: false, 
			options: [
		        "dist_mi":"Miles",
		        "dist_km":"Kilometers"
            ])
        input (description: "Setting the Height units (optional)",
			title: "Height Units", displayDuringSetup: false, type: "paragraph", element: "paragraph")
        input("height_units", "enum", title: "Height units", required: false, 
			options: [
                "height_in":"Inches",
                "height_mm":"Millimiters"
            ])
        input (description: "Setting the Speed units (optional)",
			title: "Speed Units", displayDuringSetup: false, type: "paragraph", element: "paragraph")
        input("speed_units", "enum", title: "Speed units", required: false, 
			options: [
                "speed_mph":"Miles per Hour",
                "speed_kph":"Kilometers per Hour"
            ])
        input "weather", "device.smartweatherStationTile", title: "Weather...", multiple: true, required: false
    }
    
    tiles(scale: 2) {
        multiAttributeTile(name:"temperature", type:"generic", width:6, height:4, canChangeIcon: false) {
            tileAttribute("device.temperature", key: "PRIMARY_CONTROL") {
                attributeState("temperature",label:'${currentValue}°',
					backgroundColors:[
					[value: 32, color: "#153591"],
					[value: 44, color: "#1e9cbb"],
					[value: 59, color: "#90d2a7"],
					[value: 74, color: "#44b621"],
					[value: 84, color: "#f1d801"],
					[value: 92, color: "#d04e00"],
					[value: 98, color: "#bc2323"]
                    ])
            }
            tileAttribute("device.feelsLike", key: "SECONDARY_CONTROL") {
                attributeState("default", label:'Feels Like ${currentValue}°')
            }
        }    
        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("lastSTupdate", "device.lastSTupdate", inactiveLabel: false, width: 2, height: 1, decoration: "flat", wordWrap: true) {
            state("default", label: 'Last Updated\n ${currentValue}')
        }
        valueTile("humidity", "device.humidity", inactiveLabel: false, width: 2, height: 1, decoration: "flat", wordWrap: true) {
            state "default", label:'Humidity ${currentValue}%', unit:"%"
        }
        valueTile("weather", "device.weather", inactiveLabel: false, width: 1, height: 1, decoration: "flat", wordWrap: true) {
            state "default", label:'${currentValue}'
        }
        valueTile("percentPrecip", "device.percentPrecip", inactiveLabel: false, width: 1, height: 1, decoration: "flat", wordWrap: true) {
            state "default", label:'Rain\n ${currentValue}%'
        }
        valueTile("percentPrecipToday", "device.percentPrecipToday", inactiveLabel: false, width: 2, height: 1, decoration: "flat", wordWrap: true) {
            state "default", label:'Rain Today\n ${currentValue}'
        }
        valueTile("percentPrecipLastHour", "device.percentPrecipLastHour", inactiveLabel: false, width: 2, height: 1, decoration: "flat", wordWrap: true) {
            state "default", label:'Rain Last Hour\n ${currentValue}'
        }
        standardTile("refresh", "device.weather", inactiveLabel: false, width: 1, height: 1, decoration: "flat", wordWrap: true) {
            state "default", label: "", action: "refresh", icon:"st.secondary.refresh"
        }
        valueTile("alert", "device.alert", inactiveLabel: false, width: 5, height: 1, decoration: "flat", wordWrap: true) {
            state "default", label:'Weather Alerts:\n ${currentValue}'
        }
        valueTile("rise", "device.localSunrise", inactiveLabel: false, width: 2, height: 1, decoration: "flat", wordWrap: true) {
            state "default", label:'Sunrise\n ${currentValue}'
        }
        valueTile("set", "device.localSunset", inactiveLabel: false, width: 2, height: 1, decoration: "flat", wordWrap: true) {
            state "default", label:'Sunset\n ${currentValue}'
        }
        valueTile("light", "device.illuminance", inactiveLabel: false, width: 2, height: 1, decoration: "flat", wordWrap: true) {
            state "default", label:'${currentValue} lux'
        }
        valueTile("visibility", "device.visibility", inactiveLabel: false, width: 2, height: 1, decoration: "flat", wordWrap: true) {
            state "default", label:'Visibility\n ${currentValue}'
        }
        valueTile("uv_index", "device.uv_index", inactiveLabel: false, width: 2, height: 1, decoration: "flat", wordWrap: true) {
            state "uv_index", label: 'UV Index ${currentValue}', unit: "UV Index"
        }
        standardTile("water", "device.water", inactiveLabel: false, width: 1, height: 1, decoration: "flat", wordWrap: true) {
            state "default", label: 'updating...', icon: "st.unknown.unknown.unknown"
            state "true",        icon: "st.alarm.water.wet",        backgroundColor:"#ff9999"
            state "false",       icon: "st.alarm.water.dry",        backgroundColor:"#99ff99"
        }
        valueTile("dewpoint", "device.dewpoint", inactiveLabel: false, width: 2, height: 1, decoration: "flat", wordWrap: true) {
            state "default", label:'Dewpoint ${currentValue}°'
        }
        valueTile("pressure", "device.pressure", inactiveLabel: false, width: 3, height: 1, decoration: "flat", wordWrap: true) {
            state "pressure", label: 'Barometric Pressure ${currentValue}'
        }
        valueTile("windinfo", "device.windinfo", inactiveLabel: false, width: 3, height: 1, decoration: "flat", wordWrap: true) {
            state "windinfo", label: 'Wind ${currentValue}'
        }
        valueTile("temperature2", "device.temperature", width: 1, height: 1, canChangeIcon: true) {
            state "temperature", label: '${currentValue}°',
				backgroundColors:[
					[value: 32, color: "#153591"],
					[value: 44, color: "#1e9cbb"],
					[value: 59, color: "#90d2a7"],
					[value: 74, color: "#44b621"],
					[value: 84, color: "#f1d801"],
					[value: 92, color: "#d04e00"],
					[value: 98, color: "#bc2323"]
            ]
        }
        
        main(["temperature2"])
        details(["temperature", "feelslike", "weatherIcon", "weather", "humidity" , "dewpoint", "windinfo", "pressure", "solarradiation", "uv_index", "light", "visibility", "city", "rise", "set", "lastSTupdate", "percentPrecip", "percentPrecipToday", "percentPrecipLastHour", "water", "alert", "refresh"])}
}

// parse events into attributes
def parse(String description) {
    log.debug "Parsing '${description}'"
}

def installed() {
	runEvery15Minutes(poll)
}

def uninstalled() {
	unschedule()
}

def updated() {
	unschedule()
    runEvery15Minutes(poll)
}

// handle commands
def poll() {
    log.debug "WUSTATION: Executing 'poll', location: ${location.name}"

    // Current conditions
    def obs = get("conditions")?.current_observation
    if (obs) {
        log.debug "obs --> ${obs}"
        def now = new Date().format('HH:mm:ss M.d.yyyy',location.timeZone)
        sendEvent(name:"lastSTupdate", value: now)
        
        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")
            send(name: "dewpoint", value: Math.round(obs.dewpoint_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: "dewpoint", value: Math.round(obs.dewpoint_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: "uv_index", value: obs.UV)
        send(name: "solarradiation", value: obs.solarradiation, display: false)
        
        
        def pressure_trend_text
        switch (obs.pressure_trend) {
        case "-" :
            pressure_trend_text = "Falling"
            break;

        case "+":
            pressure_trend_text = "Rising"
            break;
        case "=":
            pressure_trend_text = "Steady"
            break;
        case "0":
            pressure_trend_text = "No Change"
            break;
        default:
            pressure_trend_text = "N/A"
        }
        
        if (pres_units) {
            switch (pres_units) {
            case "press_mb" :
                send(name: "pressure", value: "${obs.pressure_mb} mbar (${pressure_trend_text})")
                break;

            case "press_in":
                send(name: "pressure", value: "${obs.pressure_in} inches (${pressure_trend_text})")
                break;
            default:
                send(name: "pressure", value: "${obs.pressure_mb} mbar (${pressure_trend_text})")
            }
        } else {
            send(name: "pressure", value: "${obs.pressure_mb} mbar (${pressure_trend_text})")
        }        

        if (dist_units) {
            switch (dist_units) {
            case "dist_mi" :
                send(name: "visibility", value: "${obs.visibility_mi} mi")
                break;

            case "dist_km":
                send(name: "visibility", value: "${obs.visibility_km} km")
                break;
            default:
                send(name: "visibility", value: "${obs.visibility_mi} mi")
            }
        } else {
            send(name: "visibility", value: "${obs.visibility_mi} mi")
        }      
        
        if (height_units) {
            switch (height_units) {
            case "height_in" :
                send(name: "percentPrecipToday", value: "${obs.precip_today_in} in")
                send(name: "percentPrecipLastHour", value: "${obs.precip_1hr_in} in")
                break;

            case "height_mm":
                send(name: "percentPrecipToday", value: "${obs.precip_today_metric} mm")
                send(name: "percentPrecipLastHour", value: "${obs.precip_1hr_metric} mm")
                break;
            default:
                send(name: "percentPrecipToday", value: "${obs.precip_today_in} in")
                send(name: "percentPrecipLastHour", value: "${obs.precip_1hr_in} in")
            }
        } else {
            send(name: "percentPrecipToday", value: "${obs.precip_today_in} in")
            send(name: "percentPrecipLastHour", value: "${obs.precip_1hr_in} in")
        }  

        if (speed_units) {
            switch (speed_units) {
            case "speed_mph" :
                send(name: "windinfo", value: "${obs.wind_dir} (${obs.wind_degrees}°) at ${obs.wind_mph} mph\n(Gust: ${obs.wind_gust_mph} mph)")
                send(name: "wind_gust", value: "${obs.wind_gust_mph}")
                send(name: "winddirection", value: "${obs.wind_dir}")
                send(name: "winddirection_deg", value: "${obs.wind_degrees}")
                send(name: "wind", value: "${obs.wind_mph}")
                break;
            case "speed_kph":
                send(name: "windinfo", value: "${obs.wind_dir} (${obs.wind_degrees}°) at ${obs.wind_kph} kph\n(Gust: ${obs.wind_gust_kph} kph)")
                send(name: "wind_gust", value: "${obs.wind_gust_kph}")
                send(name: "winddirection", value: "${obs.wind_dir}")
                send(name: "winddirection_deg", value: "${obs.wind_degrees}")
                send(name: "wind", value: "${obs.wind_kph}")
                break;
            default:
                send(name: "windinfo", value: "${obs.wind_dir} (${obs.wind_degrees}°) at ${obs.wind_mph} mph\n(Gust: ${obs.wind_gust_mph} mph)")
                send(name: "wind_gust", value: "${obs.wind_gust_mph}")
                send(name: "winddirection", value: "${obs.wind_dir}")
                send(name: "winddirection_deg", value: "${obs.wind_degrees}")
                send(name: "wind", value: "${obs.wind_mph}")
            }
        } else {
            send(name: "windinfo", value: "${obs.wind_dir} (${obs.wind_degrees}°) at ${obs.wind_mph} mph\n(Gust: ${obs.wind_gust_mph} mph)")
        }                  
        
        // Since precip_1hr_in is a string, we need to convert it to a decimal in order to compare it as a number.
        if (obs.precip_1hr_in.toFloat() > 0) {
            sendEvent( name: 'water', value: "true" )
        } else {
            sendEvent( name: 'water', value: "false" )
        }

        if (obs.local_tz_offset != device.currentValue("timeZoneOffset")) {
            send(name: "timeZoneOffset", value: obs.local_tz_offset, isStateChange: true)
        }

        def cityValue = "${obs.display_location.city}, ${obs.display_location.state}"
        if (cityValue != device.currentValue("city")) {
            send(name: "city", value: cityValue, isStateChange: true)
        }

        // 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 = ltf.parse("${today} ${a.sunrise.hour}:${a.sunrise.minute}")
        def sunsetDate = ltf.parse("${today} ${a.sunset.hour}:${a.sunset.minute}")

        def tf = new java.text.SimpleDateFormat("HH:mm")
        tf.setTimeZone(TimeZone.getTimeZone("GMT${obs.local_tz_offset}"))
        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))

        // 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"
        }

        // 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"

        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 refresh() {
    poll()
}

def configure() {
    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
    }
}


private get(feature) {
    getWeatherFeature(feature, zipCode)
}

private localDate(timeZone) {
    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)
}

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
        }

        //adjust for dusk/dawn
        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
}

This is how it looks:

3 Likes

I do not see rain % did you remove that?

Does the Ferenheit color still work correctly with your code? Or did you only mod the Centigrade?

Actually I reversed that part of the change. It works with both Centigrade and Fahrenheit the way it was so I re-applied it. (Infact in the screenshot it shows 29 as red, which was wrong and in the later screenshot it shows 29 as yellow, which is as it suppose to).

1 Like

Cool. I will copy your code and try it out. Will update you later.

Can you post the link to the Raw code in your GitHub?

Only using GitHub to download from Repos at the moment. I do not have any code.

Seems to be working.

Great to hear! Now I am trying to do the following:

However to no success. It looks OK in the screenshot but that 27 is a static and it wont update. How do I set the label of a tile to that of another tile?

Just updated, now I can read the tiles, thank you.

You removed the “Weather” output capability from this Device Handler, which is present in the original. That weather output provides a combined output which looks really pretty in ActionTiles. Had to revert back to original.

Agreed - bummer. Just read the whole thread trying to find a solution for that.

@takissd
Is there any way to add 2 fields?

  1. Day’s Forecast High
  2. Day’s Forecast Low

And is there an associated attribute that we could poll via core/webcore to use in pistons?
(For piston use such as: If today’s high is forecast above 100, send txt message. "forecast high is {variable})

I really need a way to pull daily high (low would be nice too) forecast temp not just the real time temp.

1 Like

hello @cozdabuch, i just checked all the fields i can parse from the service and there is no forecast data that can be parsed. There is only a link, which is pretty much the same thing as your screenshot, but not the data. To see whats available you can go under logging and click on your device type, and refresh your weather device on your phone and you will see the fields.
For me for example the fields are:

obs --> [wind_gust_mph:0, precip_1hr_metric: 0, precip_today_metric:0, pressure_trend:0, forecast_url:http://www.wunderground.com/US/CA/San_Diego.html, history_url:http://www.wunderground.com/weatherstation/WXDailyHistory.asp?ID=KCASANDI399, estimated:[:], weather:Clear, windchill_string:NA, station_id:KCASANDI399, UV:4.0, observation_epoch:1498061867, wind_gust_kph:0, precip_1hr_in:0.00, observation_time:Last Updated on June 21, 9:17 AM PDT, feelslike_string:76.3 F (26 C), temp_f:76.3, local_tz_long:America/Los_Angeles, relative_humidity:69%, temp_c:24.6, image:[title:Weather Underground, link:http://www.wunderground.com, url:http://icons.wxug.com/graphics/wu2/logo_130x80.png], solarradiation:551, visibility_mi:10.0, observation_location:[full:Scripps Ranch Jerabek, San Diego, California, elevation:758 ft, state:California, longitude:-117.077995, latitude:32.916039, country_iso3166:US, country:US, city:Scripps Ranch Jerabek, San Diego], wind_mph:0.0, heat_index_c:NA, precip_today_string:0.00 in (0 mm), observation_time_rfc822:Wed, 21 Jun 2017 09:17:47 -0700, feelslike_f:76.3, heat_index_f:NA, feelslike_c:26, heat_index_string:NA, ob_url:http://www.wunderground.com/cgi-bin/findweather/getForecast?query=32.916039,-117.077995, dewpoint_string:66 F (19 C), local_tz_offset:-0700, wind_kph:0, windchill_f:NA, windchill_c:NA, wind_degrees:117, pressure_in:29.77, dewpoint_c:19, pressure_mb:1008, icon:clear, local_time_rfc822:Wed, 21 Jun 2017 09:18:01 -0700, precip_1hr_string:0.00 in ( 0 mm), icon_url:http://icons.wxug.com/i/c/k/clear.gif, wind_dir:ESE, dewpoint_f:66, nowcast:, display_location:[zip:92131, magic:1, full:San Diego, CA, elevation:239.9, state:CA, wmo:99999, longitude:-117.08000183, latitude:32.91999817, state_name:California, country_iso3166:US, country:US, city:San Diego], visibility_km:16.1, temperature_string:76.3 F (24.6 C), local_tz_short:PDT, local_epoch:1498061881, wind_string:Calm, precip_today_in:0.00]

1 Like

Thanks for the reply! I see what you mean.
Do you know of any other weather source that I can pull the high/low forecast data from? Related to this DH or not, I want to find a way to pull that data into ST. Ideas?

You need to use the forecast data feature - check this out:

https://www.wunderground.com/weather/api/d/docs?d=data/forecast

You can access the data in there with webCoRE by reading

$weather.forecast.<dynamic parameters from here>

for example:

$weather.forecast.forecast.txt_forecast.forecastday[0].fcttext

or for the UK users:

$weather.forecast.forecast.txt_forecast.forecastday[0].fcttext_metric

To get immediate low:

$weather.forecast.forecast.simpleforecast.forecastday[0].low.fahrenheit

and to get the next high:

$weather.forecast.forecast.simpleforecast.forecastday[0].high.fahrenheit

Replace fahrenheit with celsius to get the metric values.

Import this in webCoRE, save it, refresh the page, then hit the Test button.

The output:

║Today's forecast: Mostly cloudy. Lows overnight in the low 80s.
║Today's low: 80
║Today's high: 90
4 Likes

How do you format the current conditions correctly?

I’m tried like this so far:
{$weather.conditions.temp_f}
{$weather.temp_f]

I keep getting null regardless of how I tried to format it.
Current Conditions list is on this link but doesn’t really say how to correctly format it.: https://www.wunderground.com/weather/api/d/docs?d=data/conditions&MR=1

Try {$weather.conditions.current_observation.temp_f}

That worked, thanks.

1 Like