NWS Outside Temperature Driver

Hello,

Following on from my NWS Weather Information driver, I used parts of the code to create an outside temperature driver.

Basically, the driver uses the National Weather Service API to pull the current temperature for your location and reports it like a regular temperature sensor. This can then be used in rules etc...

The driver uses the longitude and latitude configured in the hub settings to pull weather information for your specific location so these must be set.

Here's a link to the code for importing purposes - hubitat-drivers/nws-outside-temperature.groovy at main · b69ca/hubitat-drivers · GitHub

Once you add the driver code, just create a device using the driver to simulate an outside temperature sensor:

Hope this is of use to someone.

6 Likes

This is great, thanks! Within minutes of reading this, I installed, meshed, and plugged into a few apps.

1 Like

Thanks it works great. Super easy.

1 Like

I don't understand why I am not getting accurate temperature readings. I have a C8 with the latest software version installed. The temperature is not updating on a regular basis. Any help would be greatly appreciated!





It doesn't seem to update temperature on a regular basis. Any ideas?
Thanks!!

So looking into this, it seems to be a problem with the source data (the data which the driver is pulling from).

As previously noted, the driver pulls data from the NWS API by doing a few things -

First it uses the coordinates from the hub to hit the API and get a list of weather stations for the location. Once it has the list of stations, it goes to the first station and reads the temperature.

For example, for my location in Utah, my station is KPVU (Provo Airport) - so it hits this -

https://api.weather.gov/stations/KPVU/observations/latest

When I grabbed this using cURL, I got the following back

...
"properties": {
        "@id": "https://api.weather.gov/stations/KPVU/observations/2025-08-03T01:56:00+00:00",
        "@type": "wx:ObservationStation",
        "elevation": {
            "unitCode": "wmoUnit:m",
            "value": 1369
        },
        "station": "https://api.weather.gov/stations/KPVU",
        "stationId": "KPVU",
        "stationName": "Provo Municipal Airport",
        "timestamp": "2025-08-03T01:56:00+00:00",
        "rawMessage": "KPVU 030156Z 33019G25KT 7SM FEW016 28/08 A3012 RMK AO2 PK WND 35027/0140 SLP144 T02780083 $",
        "textDescription": "Mostly Clear",
        "icon": "https://api.weather.gov/icons/land/night/few?size=medium",
        "presentWeather": [],
        "temperature": {
            "unitCode": "wmoUnit:degC",
            "value": 27.8,
            "qualityControl": "V"
        },
...

Notice that the API gave me back a temperate of 27.8c which is around 82.4f - which is not my current temperature. However I also noticed the timestamp was 2025-08-03T01:56:00+00:00 which is Aug 2, 2025, 7:56:00 PM (Local) - over an hour ago.

So it seems that we're struggling with the update frequency provided by the weather stations - looking at all of the observations, i'm seeing updates anywhere from 2 hours to 4 hours and more depending on the station.

Obviously this isn't good enough for the purpose of the driver - it works, but the update frequency is not good enough for a lot of use-cases.

I'll see if there is another API I can use for more uptodate temperature readings. It might take me a few days as i'm pretty stacked this weekend but i'll see what I can find.

1 Like

OK here's another using the Open-Mateo API which suggests it's update frequency might be better.

Give this driver a try, if this is better, i'll ditch using the NWS data and expand on this driver with good error checking and stuff...

/**
 *
 *  ****************  Outside Temperature Sensor (Open-Meteo Edition)  ****************
 *
 *  Replaces NWS API with Open-Meteo for real-time temperature.
 *
 *  Copyright 2025 Jon Wallace
 *
 *  LICENSE: MIT
 */

metadata {
  definition (
    name: "Outside Temperature Sensor (Open-Meteo)",
    namespace: "jonw",
    author: "Jon Wallace"
  ) {
    capability "TemperatureMeasurement"
    capability "Sensor"
    capability "Refresh"

    command "getOutsideTemperature"
  }

  preferences {
    input name: "logEnable", type: "bool", title: "Enable debug logging", defaultValue: false
    input name: "updateFrequency", type: "number", title: "Auto-Refresh Interval (minutes)", defaultValue: 30, range: "1..1440"
    input name: "minChange", type: "number", title: "Minimum Temperature Change to Send Event (°F)", defaultValue: 0.1, range: "0.01..100"
  }
}

def installed() {
  log.info "Installed Open-Meteo Temperature Sensor"
  initialize()
}

def updated() {
  log.info "Updated settings"
  initialize()
}

def initialize() {
  unschedule()
  scheduleAutoRefresh()
  getOutsideTemperature()
}

def refresh() {
  getOutsideTemperature()
}

def scheduleAutoRefresh() {
  def minutes = settings?.updateFrequency ?: 30
  minutes = Math.max(1, Math.min(1440, minutes))

  if (logEnable) log.debug "Scheduling auto-refresh every ${minutes} minutes"

  schedule("0 */${minutes} * ? * *", getOutsideTemperature)
}

def getOutsideTemperature() {
  def coords = getHubCoordinates()
  if (!coords) {
    log.error "Hub coordinates not set"
    return
  }

  def lat = coords.lat
  def lon = coords.lon
  def url = "https://api.open-meteo.com/v1/forecast?latitude=${lat}&longitude=${lon}&current=temperature_2m"

  if (logEnable) log.debug "Requesting temperature from: ${url}"

  try {
    httpGet([uri: url, contentType: "application/json"]) { resp ->
      if (resp.status == 200) {
        def data = resp.data
        def tempC = data?.current?.temperature_2m
        if (tempC != null) {
          def tempF = ((tempC * 9 / 5) + 32).setScale(1, BigDecimal.ROUND_HALF_UP)
          def currentVal = device.currentValue("temperature")
          def currentTemp = currentVal != null ? new BigDecimal(currentVal.toString()) : null
          def threshold = (settings?.minChange ?: 0.1) as BigDecimal

          if (currentTemp == null || (tempF - currentTemp).abs() >= threshold) {
            sendEvent(name: "temperature", value: tempF, unit: "°F")
            if (logEnable) log.debug "Temperature updated to ${tempF}°F"
          } else if (logEnable) {
            log.debug "Temperature change (${tempF}°F) within threshold (${threshold}°F); event not sent."
          }
        } else {
          log.warn "Temperature data missing in Open-Meteo response"
        }
      } else {
        log.error "Failed to get temperature: ${resp.status}"
      }
    }
  } catch (Exception e) {
    log.error "Error fetching temperature: ${e.message}"
  }
}

def getHubCoordinates() {
  def lat = location?.latitude
  def lon = location?.longitude
  return (lat && lon) ? [lat: lat, lon: lon] : null
}

2 Likes

Thank you for the effort you put in on this. Unfortunately, I cannot use this to control my whole house fan. It doesn't update the temperature often enough to use as a reliable trigger. Nine hours between checks won't work.
Thank you for trying mate!

So even the second driver I posted in this thread takes 9 hours to update?

Yes. I wanted it to update every five minutes so I could build an automation around it. But, you can see in the log how often it is checking the current weather.

Are you completely sure you are using the latest driver code I posted? The reason I ask is that I am seeing mine update every 5 minutes -

Can you go into the device settings (not the driver), and turn logging on in preferences. Wait an hour or so and then post your log for me.

Thanks for this!
Works great, updates 30 minutes.
It's the only thing showing temp in Fahrenheit on my system though. :smiley:

I'll add an option to change this - just will take me a couple of days as i'm tied up for a couple of days right now.

Not a problem.
Nothing I can't live with. :wink:
Thanks again.

Sorry for the delay in responding. I decided to go with the Sonoff snzb-02p temperature/humidity sensor. Using the Tuya Temperature Humidity Illuminance LCD Display with a Clock driver, I can configure the sensor to update the temperature and humidity level anywhere from once a minute to once an hour.
Once again, thank you so very much for your efforts.

I've installed the driver code and added the device, however, when I view my device it does not show the state variables, any fixes for this? I did ensure my location was set in the settings.