Yahoo Weather Download

Hey,

This script works fine to get weather info from Yahoo into Indigo, my automation software,
but if it’s below zero, which it very much is here, it strips out the minus sign.
e.g. -15 becomes 15.

-- Get Weather
-- This is the city code. Search the code for your city on http://weather.yahoo.com/
set CityCode to 2430513 ---Hungry Horse 12783901
-- Temperature format
set t_format to "F"
-- Voiceover format
set v_format to "S"
-- Say present condition
set a_format to "Y"

set IURL to "http://weather.yahooapis.com/forecastrss?w=" & CityCode

-- Downloading the file using curl
set file_content to (do shell script "curl " & IURL)
-- Looking for the line with actual condition
set theText to text ((offset of "yweather:condition" in file_content) + 1) thru -1 of file_content
set sub_1 to text ((offset of "\"" in theText) + 1) thru -1 of theText

-- Today conditions found
set actual_condition to text 1 thru ((offset of "\"" in sub_1) - 1) of sub_1

-- Looking for actual temperature temperature
set sub_1a to text ((offset of "temp=" in sub_1)) thru -1 of sub_1
set sub_1b to text ((offset of "\"" in sub_1a) + 1) thru -1 of sub_1a
set actual_temp to text 1 thru ((offset of "\"" in sub_1b) - 1) of sub_1b

if t_format is equal to "C" then
	set actual_temp to (5 / 9) * (actual_temp - 32) as integer
end if

-- Looking for today forecast
set theText to text ((offset of "yweather:forecast" in file_content) + 1) thru -1 of file_content
set sub_2 to text ((offset of "\"" in theText) + 1) thru -1 of theText

-- Maximum and minimum temperatures found
set today_min_temp to word 9 of sub_2
set today_max_temp to word 12 of sub_2
if t_format is equal to "C" then
	set today_min_temp to (5 / 9) * (today_min_temp - 32) as integer
	set today_max_temp to (5 / 9) * (today_max_temp - 32) as integer
end if

-- Looking for today forecast condition (a bit tricky)
set sub_3 to text ((offset of "text" in sub_2) + 1) thru -1 of sub_2
set sub_4 to text ((offset of "\"" in sub_3) + 1) thru -1 of sub_3
set today_forecast to text 1 thru ((offset of "\"" in sub_4) - 1) of sub_4

-- Looking for tomorrow forecast
set sub_5 to text ((offset of "yweather:forecast" in sub_4) + 1) thru -1 of sub_4
set sub_6 to text ((offset of "\"" in sub_5) + 1) thru -1 of sub_5

-- Maximum and minimum temperatures found
set tomorrow_min_temp to word 9 of sub_6
set tomorrow_max_temp to word 12 of sub_6
if t_format is equal to "C" then
	set tomorrow_min_temp to (5 / 9) * (tomorrow_min_temp - 32) as integer
	set tomorrow_max_temp to (5 / 9) * (tomorrow_max_temp - 32) as integer
end if

-- Looking for tomorrow forecast condition (a bit tricky)
set sub_7 to text ((offset of "text" in sub_6) + 1) thru -1 of sub_6
set sub_8 to text ((offset of "\"" in sub_7) + 1) thru -1 of sub_7
set tomorrow_forecast to text 1 thru ((offset of "\"" in sub_8) - 1) of sub_8

tell application "IndigoServer"
	set value of variable "Yahoo_tomorrow_max_temp" to tomorrow_max_temp as string
	set value of variable "Yahoo_tomorrow_forecast" to tomorrow_forecast as string
	set value of variable "Yahoo_tomorrow_min_temp" to tomorrow_min_temp as string
end tell


Any thoughts on how to keep a minus sign very much appreciated!

Edit: I tried changing the word number from 9 to 8 which I hoped would reveal the minus sign
but it just shows an = sign. Maybe it’s not even there :frowning:

Thanks,

Carl

It’s normal, you are extracting them with :

– Maximum and minimum temperatures found
set today_min_temp to word 9 of sub_2
set today_max_temp to word 12 of sub_2

word doesn’t embed the minus character.

Use text item

Yvan KOENIG (VALLAURIS, France) vendredi 6 décembre 2013 19:46:22

Here my proposal.
I’m quite sure that some of your instructions are no longer useful but I leave that as an exercise.

-- Get Weather
-- This is the city code. Search the code for your city on http://weather.yahoo.com/
set CityCode to 2430513 ---Hungry Horse 12783901
-- Temperature format
set t_format to "F"
-- Voiceover format
set v_format to "S"
-- Say present condition
set a_format to "Y"

set IURL to "http://weather.yahooapis.com/forecastrss?w=" & CityCode

-- Downloading the file using curl
set file_content to (do shell script "curl " & IURL)
-- Looking for the line with actual condition
set theText to text ((offset of "yweather:condition" in file_content) + 1) thru -1 of file_content
set sub_1 to text ((offset of "\"" in theText) + 1) thru -1 of theText

-- Today conditions found
set actual_condition to text 1 thru ((offset of "\"" in sub_1) - 1) of sub_1

-- Looking for actual temperature temperature
set sub_1a to text ((offset of "temp=" in sub_1)) thru -1 of sub_1
set sub_1b to text ((offset of "\"" in sub_1a) + 1) thru -1 of sub_1a
set actual_temp to text 1 thru ((offset of "\"" in sub_1b) - 1) of sub_1b

if t_format is equal to "C" then
	set actual_temp to (5 / 9) * (actual_temp - 32) as integer
end if

-- Looking for today forecast
set theText to text ((offset of "yweather:forecast" in file_content) + 1) thru -1 of file_content
set sub_2 to text ((offset of "\"" in theText) + 1) thru -1 of theText

# added code
set low_text to "low=" & quote
set high_text to quote & " high=" & quote
set sub_20 to my recolle(items 2 thru -1 of my decoupe(sub_2, low_text), low_text)
set aList to my decoupe(sub_20, high_text)
set today_min_temp to item 1 of aList
set sub_20 to my recolle(items 2 thru -1 of aList, high_text)
set today_max_temp to text 1 thru ((offset of quote in sub_20) - 1) of sub_20
log today_min_temp
log today_max_temp

-- Maximum and minimum temperatures found
 # your code
if t_format is equal to "C" then
	set today_min_temp to (5 / 9) * (today_min_temp - 32) as integer
	set today_max_temp to (5 / 9) * (today_max_temp - 32) as integer
end if

-- Looking for today forecast condition (a bit tricky)
set sub_3 to text ((offset of "text" in sub_2) + 1) thru -1 of sub_2
set sub_4 to text ((offset of "\"" in sub_3) + 1) thru -1 of sub_3
set today_forecast to text 1 thru ((offset of "\"" in sub_4) - 1) of sub_4

-- Looking for tomorrow forecast
set sub_5 to text ((offset of "yweather:forecast" in sub_4) + 1) thru -1 of sub_4
set sub_6 to text ((offset of "\"" in sub_5) + 1) thru -1 of sub_5

# new code
set sub_20 to my recolle(items 2 thru -1 of my decoupe(sub_20, low_text), low_text)
set aList to my decoupe(sub_20, high_text)
set tomorrow_min_temp to item 1 of aList
set sub_20 to my recolle(items 2 thru -1 of aList, high_text)
set tomorrow_max_temp to text 1 thru ((offset of quote in sub_20) - 1) of sub_20
log tomorrow_min_temp
log tomorrow_max_temp
-- Maximum and minimum temperatures found

# your code
if t_format is equal to "C" then
	set tomorrow_min_temp to (5 / 9) * (tomorrow_min_temp - 32) as integer
	set tomorrow_max_temp to (5 / 9) * (tomorrow_max_temp - 32) as integer
end if

-- Looking for tomorrow forecast condition (a bit tricky)
set sub_7 to text ((offset of "text" in sub_6) + 1) thru -1 of sub_6
set sub_8 to text ((offset of "\"" in sub_7) + 1) thru -1 of sub_7
set tomorrow_forecast to text 1 thru ((offset of "\"" in sub_8) - 1) of sub_8

tell application "IndigoServer"
   set value of variable "Yahoo_tomorrow_max_temp" to tomorrow_max_temp as string
   set value of variable "Yahoo_tomorrow_forecast" to tomorrow_forecast as string
   set value of variable "Yahoo_tomorrow_min_temp" to tomorrow_min_temp as string
end tell

#=====

# two added handlers

on decoupe(t, d)
	local oTIDs, l
	set {oTIDs, AppleScript's text item delimiters} to {AppleScript's text item delimiters, d}
	set l to text items of t
	set AppleScript's text item delimiters to oTIDs
	return l
end decoupe

#=====

on recolle(l, d)
	local oTIDs, t
	set {oTIDs, AppleScript's text item delimiters} to {AppleScript's text item delimiters, d}
	set t to "" & l
	set AppleScript's text item delimiters to oTIDs
	return t
end recolle

#=====

Yvan KOENIG (VALLAURIS, France) vendredi 6 décembre 2013 21:41:13

Perfect. I see a lot to learn in that.

Thanks a bunch!

Carl

I have a script very similar to this but I want to make some changes…
for instance when the today_forecast says “cloudy” it would change my forecast greeting

Original script:


--this is the city code. Search the code for your city on http://weather.yahoo.com/
set CityCode to 2430683
--temperature format
set t_format to "F"
--voiceover format
set v_format to "S"
--say present condition
set a_format to "Y"

set IURL to "http://weather.yahooapis.com/forecastrss?w=" & CityCode

--downloading the file using curl
set file_content to (do shell script "curl " & IURL)
--looking for the line with actual condition
set theText to text ((offset of "yweather:condition" in file_content) + 1) thru -1 of file_content
set sub_1 to text ((offset of "\"" in theText) + 1) thru -1 of theText

--today conditions found
set actual_condition to text 1 thru ((offset of "\"" in sub_1) - 1) of sub_1

--looking for actual temperature temperature
set sub_1a to text ((offset of "temp=" in sub_1)) thru -1 of sub_1
set sub_1b to text ((offset of "\"" in sub_1a) + 1) thru -1 of sub_1a
set actual_temp to text 1 thru ((offset of "\"" in sub_1b) - 1) of sub_1b

if t_format is equal to "C" then
	set actual_temp to (5 / 9) * (actual_temp - 32) as integer
end if

--looking for today forecast
set theText to text ((offset of "yweather:forecast" in file_content) + 1) thru -1 of file_content
set sub_2 to text ((offset of "\"" in theText) + 1) thru -1 of theText

--maximum and minimum temperatures found
set today_min_temp to word 9 of sub_2
set today_max_temp to word 12 of sub_2
if t_format is equal to "C" then
	set today_min_temp to (5 / 9) * (today_min_temp - 32) as integer
	set today_max_temp to (5 / 9) * (today_max_temp - 32) as integer
end if

--looking for today forecast condition (a bit tricky)
set sub_3 to text ((offset of "text" in sub_2) + 1) thru -1 of sub_2
set sub_4 to text ((offset of "\"" in sub_3) + 1) thru -1 of sub_3
set today_forecast to text 1 thru ((offset of "\"" in sub_4) - 1) of sub_4

--looking for tomorrow forecast
set sub_5 to text ((offset of "yweather:forecast" in sub_4) + 1) thru -1 of sub_4
set sub_6 to text ((offset of "\"" in sub_5) + 1) thru -1 of sub_5

--maximum and minimum temperatures found
set tomorrow_min_temp to word 9 of sub_6
set tomorrow_max_temp to word 12 of sub_6
if t_format is equal to "C" then
	set tomorrow_min_temp to (5 / 9) * (tomorrow_min_temp - 32) as integer
	set tomorrow_max_temp to (5 / 9) * (tomorrow_max_temp - 32) as integer
end if

set sub_7 to text ((offset of "text" in sub_6) + 1) thru -1 of sub_6
set sub_8 to text ((offset of "\"" in sub_7) + 1) thru -1 of sub_7
set tomorrow_forecast to text 1 thru ((offset of "\"" in sub_8) - 1) of sub_8


if v_format is equal to "L" then
	say "Your current temperature outside is," & actual_temp & " degrees."
	delay 0.5
	say "The conditions in your location for today looks like: " & today_forecast & ", with a high of " & today_max_temp & "and a low of " & today_min_temp & " degrees.
	Tomorrow: " & tomorrow_forecast & ", between " & tomorrow_min_temp & ", and" & tomorrow_max_temp & " degrees."
else
	say "Currently the temperature outside is," & actual_temp & " degrees."
	delay 0.5
	
	#set forecast_greeting to today_forecast
	if today_forecast is "cloudy" or "mostly cloudy" then
		say "It's going to be overcast outside, todays forecast is" & today_forecast & ", skies."
		
	end if
	
	say "With a high of " & today_max_temp & "and a low of " & today_min_temp & " degrees.
	Tomorrow: " & tomorrow_forecast & ", between " & tomorrow_min_temp & ", and" & tomorrow_max_temp & " degrees."
	
end if

my failed attempt:


if today_forecast is "cloudy" or "mostly cloudy" then
say "It's going to be overcast outside, todays forecast is" & today_forecast & ", skies."
else if today_forecast is "isolated thunderstorms" or drizzle" or "rain" then
say "Looks like you'll need an umbrella today, the weather calls for" & today_forecast
end if

I found a list of Yahoo Weather condition codes,
https://developer.yahoo.com/weather/documentation.html

Any help or ideas would be great.
Thanks,

B

either


if today_forecast is "cloudy" or today_forecast is "mostly cloudy" then
	say "It's going to be overcast outside, todays forecast is" & today_forecast & ", skies."
else if today_forecast is "isolated thunderstorms" or today_forecast is "drizzle" or today_forecast is "rain" then
	say "Looks like you'll need an umbrella today, the weather calls for" & today_forecast
end if

or easier


if today_forecast is in {"cloudy", "mostly cloudy"} then
	say "It's going to be overcast outside, todays forecast is" & today_forecast & ", skies."
else if today_forecast is in {"isolated thunderstorms", "drizzle", "rain"} then
	say "Looks like you'll need an umbrella today, the weather calls for" & today_forecast
end if

PS: the script could be dramatically simplified with the XML parsing capabilities of System Events


--this is the city code. Search the code for your city on http://weather.yahoo.com/
set CityCode to 2430683
--temperature format
set t_format to "F"
--voiceover format
set v_format to "S"
--say present condition
set a_format to "Y"

set IURL to "http://weather.yahooapis.com/forecastrss?w=" & CityCode
set file_content to (do shell script "curl " & IURL)

tell application "System Events"
	
	set XMLdata to make new XML data with properties {text:file_content}
	set weatherItem to XML element "item" of XML element "channel" of XML element "rss" of XMLdata
	tell XML element "yweather:condition" of weatherItem
		set actual_condition to value of XML attribute "text"
		set actual_temp to value of XML attribute "temp"
	end tell
	
	set weatherForecasts to XML elements of weatherItem whose name is "yweather:forecast"
	set {todayForecast, tomorrowForecast} to items 1 thru 2 of weatherForecasts
end tell

set {today_min_temp, today_max_temp, today_forecast} to my getforcastData(todayForecast)
set {tomorrow_min_temp, tomorrow_max_temp, tomorrow_forecast} to my getforcastData(tomorrowForecast)

if t_format is equal to "C" then
	set actual_temp to fahrenheitToCelsius(actual_temp)
	set today_min_temp to fahrenheitToCelsius(today_min_temp)
	set today_max_temp to fahrenheitToCelsius(today_max_temp)
	set tomorrow_min_temp to fahrenheitToCelsius(tomorrow_min_temp)
	set tomorrow_max_temp to fahrenheitToCelsius(tomorrow_max_temp)
end if

if v_format is equal to "L" then
	say "Your current temperature outside is," & actual_temp & " degrees."
	delay 0.5
	say "The conditions in your location for today looks like: " & today_forecast & ", with a high of " & today_max_temp & "and a low of " & today_min_temp & " degrees.
Tomorrow: " & tomorrow_forecast & ", between " & tomorrow_min_temp & ", and" & tomorrow_max_temp & " degrees."
else
	say "Currently the temperature outside is," & actual_temp & " degrees."
	delay 0.5
	
	#set forecast_greeting to today_forecast
	if today_forecast is "cloudy" then
		say "It's going to be overcast outside, todays forecast is" & today_forecast & ", skies."
	end if
	
	say "With a high of " & today_max_temp & "and a low of " & today_min_temp & " degrees.
Tomorrow: " & tomorrow_forecast & ", between " & tomorrow_min_temp & ", and" & tomorrow_max_temp & " degrees."
	
end if

on getforcastData(element)
	tell application "System Events"
		tell element
			return {value of XML attribute "low", value of XML attribute "high", value of XML attribute "text"}
		end tell
	end tell
end getforcastData

on fahrenheitToCelsius(f)
	return (5 / 9) * (f - 32) as integer
end fahrenheitToCelsius

Thanks StefanK that works great!

StefanK is there a way to extract the “wind speed” and maybe the “humidity” or “time of sunset” out of the XML data?

yes, it is, the requested values are in the variables windSpeed, humidity and sunset


.
tell application "System Events"
	
	set XMLdata to make new XML data with properties {text:file_content}
	set windData to XML element "yweather:wind" of XML element "channel" of XML element "rss" of XMLdata
	set windSpeed to value of XML attribute "speed" of windData
	set atmosphereData to XML element "yweather:atmosphere" of XML element "channel" of XML element "rss" of XMLdata
	set humidity to value of XML attribute "humidity" of atmosphereData
	set astronomyData to XML element "yweather:astronomy" of XML element "channel" of XML element "rss" of XMLdata
	set sunset to value of XML attribute "sunset" of astronomyData
	
	set weatherItem to XML element "item" of XML element "channel" of XML element "rss" of XMLdata
.



Perfect!!! Much Thanks.

I figure out how to convert the Wind Direction & Degrees (yahoo lists them out as numbers) into actual compass direction like; North, East, South and West for the windspeed. Heres what I came up with…


--this is the city code. Search the code for your city on http://weather.yahoo.com/
set CityCode to 2430683
--temperature format
set t_format to "F"
--voiceover format
set v_format to "S"
--say present condition
set a_format to "Y"
set {year:y, month:m, weekday:w, day:d} to (current date) + 1 * days

set weatherHours to hours of (current date)
if weatherHours < 10 then
	set timeofDay to "This Morning"
else if weatherHours < 14 then
	set timeofDay to "This Afternoon"
else if weatherHours < 18 then
	set timeofDay to "This Evening"
else
	set timeofDay to "Tonight"
end if

set IURL to "http://weather.yahooapis.com/forecastrss?w=" & CityCode
set file_content to (do shell script "curl " & IURL)

tell application "System Events"
	
	set XMLdata to make new XML data with properties {text:file_content}
	set windData to XML element "yweather:wind" of XML element "channel" of XML element "rss" of XMLdata
	set windSpeed to value of XML attribute "speed" of windData
	set windDir to value of XML attribute "direction" of windData
	set atmosphereData to XML element "yweather:atmosphere" of XML element "channel" of XML element "rss" of XMLdata
	set humidity to value of XML attribute "humidity" of atmosphereData
	set astronomyData to XML element "yweather:astronomy" of XML element "channel" of XML element "rss" of XMLdata
	set sunset to value of XML attribute "sunset" of astronomyData
	set sunrise to value of XML attribute "sunrise" of astronomyData
	
	set weatherItem to XML element "item" of XML element "channel" of XML element "rss" of XMLdata
	tell XML element "yweather:condition" of weatherItem
		set actual_condition to value of XML attribute "text"
		set actual_temp to value of XML attribute "temp"
	end tell
	
	set weatherForecasts to XML elements of weatherItem whose name is "yweather:forecast"
	set {todayForecast, tomorrowForecast} to items 1 thru 2 of weatherForecasts
end tell

set {today_min_temp, today_max_temp, today_forecast} to my getforcastData(todayForecast)
set {tomorrow_min_temp, tomorrow_max_temp, tomorrow_forecast} to my getforcastData(tomorrowForecast)

--Classification of Wind Speeds
set wind_speed to round (windSpeed)
if wind_speed < 5 then
	set windAdvisory to "calm, "
else if wind_speed < 10 then
	set windAdvisory to "light, "
--My computer doesn't pronounce "gentle" right so I had to try and do it phonetically
else if wind_speed < 15 then
	set windAdvisory to "genil, "
else if wind_speed < 20 then
	set windAdvisory to "moderate, "
else if wind_speed < 25 then
	set windAdvisory to "gusty, "
else if wind_speed < 35 then
	set windAdvisory to "high, "
else
	set windAdvisory to "strong,"
end if

set windDirection to round (windDir)
if windDirection = 0 then
	set windCompass to "North"
else if windDirection ≤ 45 then
	set windCompass to "NorthEast"
else if windDirection ≤ 90 then
	set windCompass to "East"
else if windDirection ≤ 135 then
	set windCompass to "SouthEast"
else if windDirection ≤ 180 then
	set windCompass to "South"
else if windDirection ≤ 225 then
	set windCompass to "Southwest"
else if windDirection ≤ 270 then
	set windCompass to "West"
else
	set windCompass to "NorthWest"
end if

if t_format = "C" then
	set actual_temp to fahrenheitToCelsius(actual_temp)
	set today_min_temp to fahrenheitToCelsius(today_min_temp)
	set today_max_temp to fahrenheitToCelsius(today_max_temp)
	set tomorrow_min_temp to fahrenheitToCelsius(tomorrow_min_temp)
	set tomorrow_max_temp to fahrenheitToCelsius(tomorrow_max_temp)
end if

if v_format = "L" then
	say "Your current temperature outside is," & actual_temp & " degrees."
	delay 0.5
	say "The conditions in Kansas City for today looks like: " & today_forecast & ", with a high of " & today_max_temp & "and a low of " & today_min_temp & " degrees.
		Tomorrow: " & tomorrow_forecast & ", between " & tomorrow_min_temp & ", and" & tomorrow_max_temp & " degrees."
else
	if today_forecast is in {"cloudy", "mostly cloudy"} then
		say "It's going to be gloomy " & timeofDay & ", the forecast is calling for " & today_forecast & " skies."
	else if today_forecast is in {"partly cloudy"} then
		say "The forecast is calling for " & today_forecast & " skies " & timeofDay & ". With " & windAdvisory & windCompass & "ern wind's of:" & windSpeed & "miles per hour."
	else if today_forecast is in {"isolated thunderstorms", "scattered thunderstorms", "drizzle", "rain", "showers", "scattered showers", "isolated thundershowers", "mixed rain and hail"} then
		say "Looks like you might need an umbrella " & timeofDay & ", the weather calls for:" & today_forecast
	else if today_forecast is in {"tornado", "tripical storm", "hurricane", "severe thunderstorms", "heavy thunderstorms"} then
		say "There is a Severe Weather Watch Warning out! Becareful outside " & timeofDay & " the forecast calls for a chance of " & today_forecast & "in the metro area. With wind speeds approximately " & windSpeed & " miles per hour, from the " & windCompass
	else if today_forecast is in {"mixed rain and snow", "mixed rain and sleet", "mixed snow and sleet", "freezing drizzle", "freezing rain", "snow showers"} then
		say "Are you sure you don't just want to stay in bed today? The forecast calls for " & today_forecast
	else if today_forecast is in {"snow flurries", "light snow showers", "blowing snow"} then
		say "There might be some " & today_forecast & timeofDay
	else if today_forecast is in {"heavy snow", "scattered snow showers", "snow"} then
		say "Winter is coming! The forecast for  " & timeofDay & " looks like " & today_forecast
	else if today_forecast is in {"hail", "sleet"} then
		say "The roads might be a little slick " & timeofDay & ", the weather calls for " & today_forecast
	else if today_forecast is in {"dust", "foggy", "haze", "smoky"} then
		say "Visibility might be an issue when you head outside " & today_forecast & " conditions will make it hard to see."
	else if today_forecast is in {"windy", "blustery"} then
		say "Don't get blown away, today will be " & today_forecast & ". With " & windAdvisory & windCompass & "ern wind's, at:" & windSpeed & " miles per hour."
	else if today_forecast is in {"cold"} then
		say "Bundle up it's going to be " & today_forecast & "out there " & timeofDay
	else if today_forecast is in {"hot"} then
		say "Better crank up the AC, " & timeofDay & " its going to be " & today_forecast
	else if today_forecast is in {"sunny", "fair"} then
		say "It is going to be gorgeous " & timeofDay & " outside, weather calls for " & today_forecast & " skies. With " & windAdvisory & windCompass & "ern wind's, at:" & windSpeed & " miles per hour."
	else
		say "The local weather forecast for " & timeofDay & " calls for:" & today_forecast & ". With " & windAdvisory & windCompass & "ern wind's, at:" & windSpeed & " miles per hour."
	end if
	delay 0.5
	
	say "Right now the temperature outside is " & actual_temp & " degrees. With the possible high reaching " & today_max_temp & " during the day: and a low of " & today_min_temp & " degrees overnight."
	delay 0.5
	
	if humidity ≥ ((actual_temp) - 10) then
		say "It might feel humid " & timeofDay
	end if
	
	say "Relative humidity levels in the area will approach " & humidity & "%"
	delay 0.5
	say "This evening: Sunset in Kansas City will be around " & sunset
	delay 1
	say "Tomorrow: Sunrise is at " & sunrise & ". Your " & w & " forecast calls for " & tomorrow_forecast & ", between " & tomorrow_max_temp & ", and " & tomorrow_min_temp & " degrees."
end if

on getforcastData(element)
	tell application "System Events"
		tell element
			return {value of XML attribute "low", value of XML attribute "high", value of XML attribute "text"}
		end tell
	end tell
end getforcastData

on fahrenheitToCelsius(f)
	return (5 / 9) * (f - 32) as integer
end fahrenheitToCelsius

Im trying to figure out a way to change a couple lines dependent on the sunset time. Changing something from present tense to past tense depending on the time of day. I’ve tried…


if (sunset > time string of (current date)) then
		set verb to " is at "
	else
		set verb to " was at "
	end if

I think my problem is the sunset time it pulls is formatted like “6:15 PM” and the time string is “6:15:32 PM”, Im not sure what to do make this work. I’ve tried several versions but all failed :frowning:
Thanks!

You could use this handler it converts a string hh:mm a to an AppleScript date which can be compared


on convert12To24Hour(dateString)
	tell dateString to set {ampm, timePart} to {text -2 thru -1, text 1 thru -4}
	set currentDate to current date
	set {TID, text item delimiters} to {text item delimiters, ":"}
	tell text items of timePart to set {hr, mn} to {item 1 as integer, item 2 as integer}
	set text item delimiters to TID
	if (ampm = "pm" or ampm = "PM") and hr < 12 then
		set hr to hr + 12
	else if (ampm = "am" or ampm = "AM") and hr = 12 then
		set hr to hr - 12
	end if
	tell currentDate to set {its hours, its minutes, its seconds} to {hr, mn, 0}
	return currentDate
end convert12To24Hour

set theDate to convert12To24Hour("12:23 am")

Thanks Stefan! Im getting an error with what you just gave me. However I just copied my old time script and that seems to be doing the trick, I hope. I’ll have to wait for sunset to see if it works :wink:


if (sunset > getTimeInHoursAndMinutes()) then
		set verb to " is at "
	else
		set verb to " was at "
	end if


on getTimeInHoursAndMinutes()
	
	-- Get the "hour"
	set timeStr to time string of (current date)
	set Pos to offset of ":" in timeStr
	set theHour to characters 1 thru (Pos - 1) of timeStr as string
	set timeStr to characters (Pos + 1) through end of timeStr as string
	-- Get the "minute"
	set Pos to offset of ":" in timeStr
	set theMin to characters 1 thru (Pos - 1) of timeStr as string
	set timeStr to characters (Pos + 1) through end of timeStr as string
	--Get "AM or PM"
	set Pos to offset of " " in timeStr
	set theSfx to characters (Pos + 1) through end of timeStr as string
	return (theHour & ":" & theMin & " " & theSfx) as string
	
end getTimeInHoursAndMinutes


Basically you cannot compare (< = >) time strings containing an am/pm suffix, either get the seconds from midnight respectively or compose an AppleScript date which is comparable

I was wondering that too Stefan.I think I figured out a work-around, converting all the times to a 24hr string. That way I can compare the 2 numbers then.


--Gets current 24hr
set {year:y, month:m, weekday:w, day:d, hours:h, minutes:mn} to (current date)

if mn ≤ 9 then
	set min to ("0" & mn)
else
	set min to (mn)
end if

if h < 10 then
	set current24hr to ("0" & h & min) as string
else
	set current24hr to (h & min) as string
end if

-- Converts sunset 12hr to 24hrs
set sunsetHR to (characters 1 of sunset) + 12
set sunsetMN to characters 3 thru 4 of sunset
set sunset24 to (sunsetHR & sunsetMN) as string
	
if (sunset24 > current24hr) then
	set verb to " is at "
else
	set verb to " was at "
end if

Since the sunset time is pulled from the weather website its always changing I thought it would be nice to have a script that could change with it. Stefan help me realize 7:23 pm can’t be (>=<) so I did a little script math to do the work.
It basically converts the time: sunset24=(1923) > current24hr=(1432)

Edit:
I had to add a “0” before the hours for anything before 10AM otherwise the > equations showed false.

What’s wrong with my handler? It converts a date string e.g. 6:25 pm to an AppleScript date based on the current date

Yahoo has changed their API as of March 15, 2016 so this script doesn’t work anymore :frowning:

Looks like an API key is required now?!

No, you have to use the api differently. You can use the yql language to select specific data from the wheaterforecast API.

--this is the city code. Search the code for your city on http://weather.yahoo.com/
set CityCode to "2430683"
--temperature format
set t_format to "F"
--voiceover format
set v_format to "S"
--say present condition
set a_format to "Y"
set {year:y, month:m, weekday:w, day:d} to (current date) + 1 * days

set weatherHours to hours of (current date)
if weatherHours < 10 then
	set timeofDay to "This Morning"
else if weatherHours < 14 then
	set timeofDay to "This Afternoon"
else if weatherHours < 18 then
	set timeofDay to "This Evening"
else
	set timeofDay to "Tonight"
end if

set yahooQuery to "select * from weather.forecast where woeid = '" & CityCode & "'"
set yql to AST URL encode yahooQuery

set IURL to "https://query.yahooapis.com/v1/public/yql?q=" & yql & "&format=xml"
set file_content to (do shell script "curl " & IURL)

tell application "System Events"
	
	set XMLdata to make new XML data with properties {text:file_content}
	set windData to XML element "yweather:wind" of XML element "channel" of XML element "results" of XML element "query" of XMLdata
	set windSpeed to value of XML attribute "speed" of windData
	set windDir to value of XML attribute "direction" of windData
	set atmosphereData to XML element "yweather:atmosphere" of XML element "channel" of XML element "results" of XML element "query" of XMLdata
	set humidity to value of XML attribute "humidity" of atmosphereData
	set astronomyData to XML element "yweather:astronomy" of XML element "channel" of XML element "results" of XML element "query" of XMLdata
	set sunset to value of XML attribute "sunset" of astronomyData
	set sunrise to value of XML attribute "sunrise" of astronomyData
	
	set weatherItem to XML element "item" of XML element "channel" of XML element "results" of XML element "query" of XMLdata
	tell XML element "yweather:condition" of weatherItem
		set actual_condition to value of XML attribute "text"
		set actual_temp to value of XML attribute "temp"
	end tell
	
	set weatherForecasts to XML elements of weatherItem whose name is "yweather:forecast"
	set {todayForecast, tomorrowForecast} to items 1 thru 2 of weatherForecasts
end tell

set {today_min_temp, today_max_temp, today_forecast} to my getforcastData(todayForecast)
set {tomorrow_min_temp, tomorrow_max_temp, tomorrow_forecast} to my getforcastData(tomorrowForecast)

set windAdvisory to getWindAdvisory(windSpeed)
set windCompass to getWindDirection(windDir)

if t_format = "C" then
	set actual_temp to fahrenheitToCelsius(actual_temp)
	set today_min_temp to fahrenheitToCelsius(today_min_temp)
	set today_max_temp to fahrenheitToCelsius(today_max_temp)
	set tomorrow_min_temp to fahrenheitToCelsius(tomorrow_min_temp)
	set tomorrow_max_temp to fahrenheitToCelsius(tomorrow_max_temp)
end if

if v_format = "L" then
	say "Your current temperature outside is," & actual_temp & " degrees."
	delay 0.5
	say "The conditions in Kansas City for today looks like: " & today_forecast & ", with a high of " & today_max_temp & "and a low of " & today_min_temp & " degrees.
		Tomorrow: " & tomorrow_forecast & ", between " & tomorrow_min_temp & ", and" & tomorrow_max_temp & " degrees."
else
	if today_forecast is in {"cloudy", "mostly cloudy"} then
		say "It's going to be gloomy " & timeofDay & ", the forecast is calling for " & today_forecast & " skies."
	else if today_forecast is in {"partly cloudy"} then
		say "The forecast is calling for " & today_forecast & " skies " & timeofDay & ". With " & windAdvisory & windCompass & "ern wind's of:" & windSpeed & "miles per hour."
	else if today_forecast is in {"isolated thunderstorms", "scattered thunderstorms", "drizzle", "rain", "showers", "scattered showers", "isolated thundershowers", "mixed rain and hail"} then
		say "Looks like you might need an umbrella " & timeofDay & ", the weather calls for:" & today_forecast
	else if today_forecast is in {"tornado", "tripical storm", "hurricane", "severe thunderstorms", "heavy thunderstorms"} then
		say "There is a Severe Weather Watch Warning out! Becareful outside " & timeofDay & " the forecast calls for a chance of " & today_forecast & "in the metro area. With wind speeds approximately " & windSpeed & " miles per hour, from the " & windCompass
	else if today_forecast is in {"mixed rain and snow", "mixed rain and sleet", "mixed snow and sleet", "freezing drizzle", "freezing rain", "snow showers"} then
		say "Are you sure you don't just want to stay in bed today? The forecast calls for " & today_forecast
	else if today_forecast is in {"snow flurries", "light snow showers", "blowing snow"} then
		say "There might be some " & today_forecast & timeofDay
	else if today_forecast is in {"heavy snow", "scattered snow showers", "snow"} then
		say "Winter is coming! The forecast for  " & timeofDay & " looks like " & today_forecast
	else if today_forecast is in {"hail", "sleet"} then
		say "The roads might be a little slick " & timeofDay & ", the weather calls for " & today_forecast
	else if today_forecast is in {"dust", "foggy", "haze", "smoky"} then
		say "Visibility might be an issue when you head outside " & today_forecast & " conditions will make it hard to see."
	else if today_forecast is in {"windy", "blustery"} then
		say "Don't get blown away, today will be " & today_forecast & ". With " & windAdvisory & windCompass & "ern wind's, at:" & windSpeed & " miles per hour."
	else if today_forecast is in {"cold"} then
		say "Bundle up it's going to be " & today_forecast & "out there " & timeofDay
	else if today_forecast is in {"hot"} then
		say "Better crank up the AC, " & timeofDay & " its going to be " & today_forecast
	else if today_forecast is in {"sunny", "fair"} then
		say "It is going to be gorgeous " & timeofDay & " outside, weather calls for " & today_forecast & " skies. With " & windAdvisory & windCompass & "ern wind's, at:" & windSpeed & " miles per hour."
	else
		say "The local weather forecast for " & timeofDay & " calls for:" & today_forecast & ". With " & windAdvisory & windCompass & "ern wind's, at:" & windSpeed & " miles per hour."
	end if
	delay 0.5
	
	say "Right now the temperature outside is " & actual_temp & " degrees. With the possible high reaching " & today_max_temp & " during the day: and a low of " & today_min_temp & " degrees overnight."
	delay 0.5
	
	if humidity ≥ ((actual_temp) - 10) then
		say "It might feel humid " & timeofDay
	end if
	
	say "Relative humidity levels in the area will approach " & humidity & "%"
	delay 0.5
	say "This evening: Sunset in Kansas City will be around " & sunset
	delay 1
	say "Tomorrow: Sunrise is at " & sunrise & ". Your " & w & " forecast calls for " & tomorrow_forecast & ", between " & tomorrow_max_temp & ", and " & tomorrow_min_temp & " degrees."
end if

on getforcastData(element)
	tell application "System Events"
		tell element
			return {value of XML attribute "low", value of XML attribute "high", value of XML attribute "text"}
		end tell
	end tell
end getforcastData

on fahrenheitToCelsius(f)
	return (5 / 9) * (f - 32) as integer
end fahrenheitToCelsius

on getWindDirection(windDir)
	set windDirection to ((windDir + 22.5) div 45) + 1
	return item windDirection of {"North", "NorthEast", "East", "SouthEast", "South", "Southwest", "West", "NorthWest", "North"}
end getWindDirection

on getWindAdvisory(windSpeed)
	set adv to (windSpeed div 5) + 1
	if adv > 7 then set adv to 7
	return item adv of {"calm, ", "light, ", "genil, ", "moderate, ", "gusty, ", "high, ", "strong,"}
end getWindAdvisory

note: I’m using AppleScript Toolbox to URL encode the query, you can use PHP on the command line to get the same results.

update: get rid of some if-statements.

Thanks for the help DJ Bazzie Wazzie! AppleScript Toolbox did the trick!