Hmmm...I see how that works. That probably would be the best way. I've updated my script to be contained within a single scpt
file that is triggered by the "valid time" displays in each of my 5 button groups as well as by my LaunchAgent. Moving from AS widgets to standard buttons is obviously preferable, and I think I can easily compile the JSON in AS using JSON Helper. I'd prefer not to rewrite the whole script at the moment, and I'm not familiar with JSA syntax and Apple's documentation is kind of terrible.
That said, already this is massively more performant than before with BetterTouchToolApplescriptRunner
now hovering around 0 to 2% in Activity Monitor instead of the 10-15% it was before. Thanks so much for your help so far.
That said, getting back to my original request, I still think I see a value for dynamic buttons. For example, in my main BTT temperature display, it would be great if my AS could check for significant weather in the other parameters (wind speeds, rainfall amounts), and dynamically create buttons that open the respective parameter group. It's not quite as "urgent" a request since you've shown me a feature I was unaware of that has solved my primary problem: performance.
I'm going to embed my script here so far just in case there's some obvious BTT feature I'm missing. It's a bit big and there's a more to do. I'll try converting things to standard buttons in the coming week.
-- Still to do:
-- - Add detailed views for humidity
-- - Add detailed view for pressure
-- - Re-develop all the conditional highlighting routines
-- - Define colours for each highlight state-data freshness combination
-- This section stores the UUID for each button that will be updated with fresh weather data.
-- Primary TB Display
set main_temperature to "D929545C-D98D-408D-AC96-89469CC1FA6E"
-- Overview PWS Display
set overview_temperature to "7A1434B8-8E56-46F8-86D9-442AED0B6E62"
set overview_wind to "F03865B3-2458-472B-B607-C3E0DA358A15"
set overview_precip to "A4A40194-821D-410B-81D7-77316BBC478D"
set overview_dewpoint to "EF960A7A-C0D9-4C14-833A-399B764ABDEC"
set overview_humidity to "E2C885F0-9C8B-405B-9271-CB6E2CD7C129"
set overview_pressure to "4DBDF23C-918A-4D95-B6E4-91E9AFFC49F8"
set valid_time to {"56AD0CC2-8C3D-4740-9483-0E45AD856A73", "9F1072E0-E19B-476E-B008-40F9CC13F990", "6B72BB64-58DC-484D-8E41-0FF2C062410E", "2586DB7A-99C5-459F-B4FC-7CECBBE3A107", "D49C45C3-1D13-4D18-94D2-7C66F8F8DD68"}
-- Detailed View: Temperature
set detailed_temperature_current to "BCF48091-B7B1-4AC3-A804-66D283E1FA19"
set detailed_temperature_trend to "FA49A1D3-DB9A-447D-8694-CB39729159BF"
set detailed_temperature_daily_high to "36C0F984-6567-41BB-8962-382B74F691E2"
set detailed_temperature_daily_low to "AC22F34B-6D3B-454F-B825-86F17BB81DA9"
-- Detailed View: Wind
set detailed_wind_current to "34382C26-DDD1-438E-A508-6267E3447476"
set detailed_wind_peak_sustained to "CFC924D2-F0C2-4E0B-B44A-12D14A37DEF7"
set detailed_wind_peak_gust to "D22CD0CF-A368-4854-8CD1-C1B7C4B47B93"
set detailed_wind_dominant_direction to "790E9E0F-BD16-4F7F-A850-1C07106DDDE8"
-- Detailed View: Precipitation
set detailed_precip_rate_current to "8555D85E-9F55-4948-B56D-E3574148C193"
set detailed_precip_amount_last_hour to "74E01A22-9A44-4DAC-BD13-4147CBD1F7F6"
set detailed_precip_amount_today to "8DFF54E4-5C8A-4C71-BFBB-95F46BDE4F23"
set detailed_precip_rate_daily_max to "858D2DEE-934F-4F43-A4F8-FFB6A79D44CF"
set detailed_precip_amount_twentyfour_hours to "3745AD44-2CF0-4248-9369-650EBD812EF7"
set detailed_precip_amount_yesterday to "67C3D28C-8D71-49F6-AC80-99056D335EAF"
set detailed_precip_amount_storm to "5D94D946-4E74-4D6F-8B75-5CB67F4D5D56"
-- Detailed View: Humidity
set detailed_humidity_dew_point_current to "D93D6345-1874-4E2E-AC6F-5C371EF7B1A5"
set detailed_humidity_dew_point_daily_max to "74180204-B5E1-44D8-BB00-D1791E39B8C5"
set detailed_humidity_dew_point_daily_min to "C84C4EE7-0951-49F6-A3D9-205ABA6F2559"
-- Set Color Variables for Data Freshness
set text_fresh to "255,255,255,255"
set bg_fresh to "75,75,75,255"
set text_stale to "178,178,178,255"
set bg_stale to "135,105,63,255"
set text_expired_red to "255,223,222,225"
set bg_expired_red to "155,54,63,255"
set text_expired to "100,100,100,255"
set bg_expired to "75,45,45,255"
-- Set Color Variables for Conditional Highlighting Based on Thresholds
set bg_elevated to "217,168,54,255"
set bg_alert to "232,91,86,255"
-- Other Variables Needed
set my_shared_secret to "s6Ed8nWXBEJeaRb?"
set json_target to "/Users/Brad/.glenwood_pws/api.json"
set font_size to 13
-- Load JSON Data
set json_values to readFile(json_target)
tell application "JSON Helper"
try
set weather to read JSON from json_values
on error errMsg
return "Can't create JSON"
end try
end tell
-- Determine data state and set colour variables
set updateTime to (LastDataRead of weather as string)
set updateTimeString to "Valid at " & updateTime
set timeArray to my splice(LastDataRead of weather as string, ":")
set currentTime to getTimeInHoursAndMinutes()
-- Set overall appearance based on data freshness
if (first item of timeArray as number) is not equal to (first item of currentTime as number) then
set bg_main to bg_expired
set text_main to text_expired
set bg_button to bg_expired
set text_button to text_expired
else if ((second item of currentTime as number) - (second item of timeArray as number)) is greater than 15 then
set bg_main to bg_stale
set text_main to text_stale
set bg_button to bg_stale
set text_button to text_stale
else
set bg_main to "0,0,0,255"
set text_main to text_fresh
set bg_button to bg_fresh
set text_button to text_fresh
end if
-- Retrieve Data
-- RD: Temperatures
set data_current_temperature_rounded to round (outdoorTemp of weather as real)
set data_current_temperature to (outdoorTemp of weather as real)
set data_temperature_unit to (TempUnit of weather as string) as string
set data_temperature_trend to (TempTrend of weather as real)
if data_temperature_trend is greater than 0 then
set data_temperature_trend_string to "Trend: +" & data_temperature_trend & data_temperature_unit
else
set data_temperature_trend_string to "Trend: " & data_temperature_trend & data_temperature_unit
end if
set data_temperature_daily_high to HighTempToday of weather as number
set data_temperature_daily_low to LowTempToday of weather as number
-- RD: Wind
set data_wind_rounded to round (WindAverage of weather as number)
set data_wind_gust_rounded to round (Recentmaxgust of weather as number)
set data_wind_unit to (WindUnit of weather as string)
if (data_wind_rounded is less than 5) and (data_wind_gust_rounded is less than 10) then
set data_wind_overview_string to "Calm"
else if (data_wind_rounded is less than 5) and (data_wind_gust_rounded is greater than 9) then
set data_wind_overview_string to "Up to " & data_wind_gust_rounded & data_wind_unit
else
set data_wind_overview_string to (data_wind_rounded as string) & "G" & data_wind_gust_rounded & " " & data_wind_unit
end if
set data_wind_bearing to (Avgbearing of weather as number)
set data_wind_compassDirections to {"Nil", "N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW"}
set data_wind_bearing to round ((data_wind_bearing mod 360) / 22.5) + 1
set data_wind_bearing to (item data_wind_bearing of data_wind_compassDirections)
set data_wind_detailed_current to "Current: " & data_wind_bearing & " " & data_wind_rounded & " gusting " & data_wind_gust_rounded & " " & data_wind_unit
set data_wind_daily_peak_sustained to HighWindToday of weather as number
set data_wind_daily_peak_gust to HighGustToday of weather as number
set data_wind_dominant_direction to DominantWindDirection of weather as string
-- RD: Precipitation
set data_daily_rain to (RainToday of weather as real)
set data_precip_unit to (RainUnit of weather as string)
set data_precip_rate_unit to data_precip_unit & "/hr"
set data_precip_rate_current to RainRate of weather as number
set data_precip_amount_last_hour to RainLastHour of weather as number
set data_precip_amount_today to RainToday of weather as number
set data_precip_rate_daily_max to HighRainRateToday of weather as number
set data_precip_amount_twentyfour_hours to RainLast24Hour of weather as number
set data_precip_amount_yesterday to RainYesterday of weather as number
set data_precip_amount_storm to StormRain of weather as number
-- RD: Humidity
set data_humidity_dewpoint_current to OutdoorDewpoint of weather as real
set data_humidity_dewpoint_current_rounded to round (OutdoorDewpoint of weather as number)
set data_humidity_dew_point_daily_max to HighDewpointToday of weather as number
set data_humidity_dew_point_daily_min to LowDewpointToday of weather as number
set data_humidity_rh_current to OutdoorHum of weather as number
set data_rh_unit to "%"
set data_humidity_rh_daily_max to HighHumToday of weather as number
set data_humidity_rh_daily_min to LowHumToday of weather as number
set data_current_pressure to Pressure of weather as number
set data_current_pressure_rounded to round (Pressure of weather as number)
set data_pressure_unit to PressUnit of weather as string
-- Set Thresholds
set threshold_wind_sustained_elevated to 15
set threshold_wind_sustained_alert to 25
set threshold_wind_gust_elevated to 35
set threshold_wind_gust_alert to 50
-- Update UI Elements
tell application "BetterTouchTool"
-- Primary TB Display
-- Contextual string modification to display rain emoji if the PWS is reporting a rain rate
if data_precip_rate_current is greater than 0 then
update_touch_bar_widget main_temperature text ("π§ " & data_current_temperature_rounded & data_temperature_unit) as string background_color bg_main shared_secret my_shared_secret
else
update_touch_bar_widget main_temperature text (data_current_temperature_rounded & data_temperature_unit) as string background_color bg_main shared_secret my_shared_secret
end if
-- PWS Overview Group
update_touch_bar_widget overview_temperature text (data_current_temperature & data_temperature_unit) as string background_color bg_button shared_secret my_shared_secret
-- Highlight Winds Based on Sustained or Gust Thresholds
if (data_wind_rounded is greater than threshold_wind_sustained_elevated) or (data_wind_gust_rounded is greater than threshold_wind_gust_elevated) then
update_touch_bar_widget overview_wind text data_wind_overview_string background_color bg_elevated shared_secret my_shared_secret
else if (data_wind_rounded is greater than threshold_wind_sustained_alert) or (data_wind_gust_rounded is greater than threshold_wind_gust_alert) then
update_touch_bar_widget overview_wind text data_wind_overview_string background_color bg_alert shared_secret my_shared_secret
else
update_touch_bar_widget overview_wind text data_wind_overview_string background_color bg_button shared_secret my_shared_secret
end if
update_touch_bar_widget overview_precip text (data_daily_rain & data_precip_unit) as string background_color bg_button shared_secret my_shared_secret
update_touch_bar_widget overview_dewpoint text (data_humidity_dewpoint_current_rounded & data_temperature_unit) as string background_color bg_button shared_secret my_shared_secret
update_touch_bar_widget overview_humidity text (data_humidity_rh_current & data_rh_unit) as string background_color bg_button shared_secret my_shared_secret
update_touch_bar_widget overview_pressure text (data_current_pressure_rounded & data_pressure_unit) as string background_color bg_button shared_secret my_shared_secret
-- Detailed Temperature Group
update_touch_bar_widget detailed_temperature_current text "Current: " & (data_current_temperature & data_temperature_unit) as string background_color bg_button shared_secret my_shared_secret
update_touch_bar_widget detailed_temperature_trend text data_temperature_trend_string as string background_color bg_button shared_secret my_shared_secret
update_touch_bar_widget detailed_temperature_daily_high text "High: " & (data_temperature_daily_high & data_temperature_unit) as string background_color bg_button shared_secret my_shared_secret
update_touch_bar_widget detailed_temperature_daily_low text "Low: " & (data_temperature_daily_low & data_temperature_unit) as string background_color bg_button shared_secret my_shared_secret
-- Detailed Wind Group
update_touch_bar_widget detailed_wind_current text data_wind_detailed_current background_color bg_button shared_secret my_shared_secret
update_touch_bar_widget detailed_wind_peak_sustained text "Peak Sustained: " & (data_wind_daily_peak_sustained & " " & data_wind_unit) as string background_color bg_button shared_secret my_shared_secret
update_touch_bar_widget detailed_wind_peak_gust text "Peak Gust: " & (data_wind_daily_peak_gust & " " & data_wind_unit) as string background_color bg_button shared_secret my_shared_secret
update_touch_bar_widget detailed_wind_dominant_direction text ("Dominant Direction: " & data_wind_dominant_direction) background_color bg_button shared_secret my_shared_secret
-- Detailed Precipitaiton Group
update_touch_bar_widget detailed_precip_rate_current text ("Current Rate: " & data_precip_rate_current & " " & data_precip_rate_unit) as string background_color bg_button shared_secret my_shared_secret
update_touch_bar_widget detailed_precip_amount_last_hour text ("Last Hour: " & data_precip_amount_last_hour & " " & data_precip_unit) as string background_color bg_button shared_secret my_shared_secret
update_touch_bar_widget detailed_precip_amount_today text ("Rain Today: " & data_precip_amount_today & " " & data_precip_unit) as string background_color bg_button shared_secret my_shared_secret
update_touch_bar_widget detailed_precip_rate_daily_max text ("Max Rain Rate Today: " & data_precip_rate_daily_max & " " & data_precip_rate_unit) as string background_color bg_button shared_secret my_shared_secret
update_touch_bar_widget detailed_precip_amount_twentyfour_hours text ("24hr. Rain: " & data_precip_amount_twentyfour_hours & " " & data_precip_unit) as string background_color bg_button shared_secret my_shared_secret
update_touch_bar_widget detailed_precip_amount_yesterday text ("Rain Yesterday: " & data_precip_amount_yesterday & " " & data_precip_unit) as string background_color bg_button shared_secret my_shared_secret
update_touch_bar_widget detailed_precip_amount_storm text ("Rain Today: " & data_precip_amount_storm & " " & data_precip_unit) as string background_color bg_button shared_secret my_shared_secret
-- Detailed Humidity Group
update_touch_bar_widget detailed_humidity_dew_point_current text ("Current: " & data_humidity_dewpoint_current & data_temperature_unit) as string background_color bg_button shared_secret my_shared_secret
update_touch_bar_widget detailed_humidity_dew_point_daily_max text ("Max Today: " & data_humidity_dew_point_daily_max & data_temperature_unit) as string background_color bg_button shared_secret my_shared_secret
update_touch_bar_widget detailed_humidity_dew_point_daily_min text ("Min Today: " & data_humidity_dew_point_daily_min & data_temperature_unit) as string background_color bg_button shared_secret my_shared_secret
repeat with widget in valid_time
update_touch_bar_widget widget text updateTimeString background_color bg_main shared_secret my_shared_secret
end repeat
end tell
-- Custom Functions
on splice(textString, delimiter)
set oldDelimiters to AppleScript's text item delimiters
set AppleScript's text item delimiters to delimiter
set spliceArray to every text item of textString
set AppleScript's text item delimiters to oldDelimiters
return spliceArray
end splice
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
set hourString to ""
repeat with letter in theHour
set hourString to (hourString & letter)
end repeat
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
if theSfx is "PM" and (hourString as number is not 12) then
set hourString to ((hourString as number) + 12) as string
else if theSfx is "AM" and (hourString as number is 12) then
set hourString to ((hourString as number) - 12) as string
end if
return {hourString, theMin}
end getTimeInHoursAndMinutes
on readFile(unixPath)
set foo to (open for access (POSIX file unixPath))
set txt to (read foo for (get eof foo) as Β«class utf8Β»)
close access foo
return txt
end readFile