Weather for scriptable

Any scripts for finding the weather. I am new at this and need some examples.

Example scripts for weather

I wrote this last week, which will hopefully be useful.

It takes the data returned from the Forecast API, parses it, and returns a readable string to the calling Shortcut. I then have Siri speak it. It’s far from perfect, but it works!

I can’t easily share the whole Shortcut I’m using, unfortunately, but here’s the relevant bit.

3 Likes

Thanks. It shows an error saying “error on line 3:25: SyntaxError:JSON parse error:Unexpected identifier “undefined”

You’re probably not passing the data in correctly then. It’s trying to parse the JSON and failing. Would you mind sharing what you’ve got so far?

Alternative, less feature rich version than @JoshFarrant version. Mine runs entirely within Scriptable.

  1. Requires the Dark Sky API key to be in DarkSky_Key.txt file in the Scriptable iCloud Drive directory
  2. Requires png files with the same name as icon values returned by the API: clear-day , clear-night , rain , snow , sleet , wind , fog , cloudy , partly-cloudy-day , partly-cloudy-night. I used the excellent Climacons from Adam Whitcroft, and converted the svg versions to png. These icons go in Icons sub directory of Scriptable directory.
  3. If you don’t want the icon, feel free to comment out/remove lines 26, 30 - 35 and 38

Feedback and opportunities to improve this are welcome.

p.s. Special thanks to @scottfwalter for helping me with HTTP Request: making request from a function

1 Like

Here’s one I wrote. I admit I’m a bit OCD about my weather reports.
—Erik

const apiKey = '___DARK SKY API KEY (FREE AT darksky.net)___';
let loc = await Location.current()

let url = 'https://api.darksky.net/forecast/' + apiKey + '/' + loc.latitude + ',' + loc.longitude + '?exclude=minutely,hourly';
let req = new Request(url);
let report = await req.loadJSON()
let days = report['daily']['data'];
let today = days[0];
let tomorrow = days[1];
let alerts = report['alerts'];

forecastTable(days);

// current weather info
let cTemp = report['currently']['temperature'];
cTemp = Math.round(cTemp);
let cPrecip = report['currently']['precipProbability'];
cPrecip = Math.round(cPrecip);
let cHumidity = report['currently']['humidity'];
cHumidity = Math.round(100*cHumidity);
let cSummary = report['currently']['summary'];
let cTime = new Date(report['currently']['time']*1000);
let sunrise = new Date(today['sunriseTime']*1000);
let sunset = new Date(today['sunsetTime']*1000);
let cText = `It is ${shortTimeStr(cTime)}. The current weather is ${cSummary}. The temperature is ${cTemp} degrees and ${cHumidity} percent humidity. Sunrise is ${shortTimeStr(sunrise)}. Sunset is ${shortTimeStr(sunset)}. `

// day ahead forecast
let fText = 'The forecast for ';
if ( cTime.getHours() <= 18 ) {
  fText += 'today is ' + forecastText(today);
} else {
  fText += 'tomorrow is ' + forecastText(tomorrow);
}

// Week ahead forecast
let wkText = 'Expect ' + report['daily']['summary'];

// Alerts
let alertText = ' ... ';
if ( alerts ) {
  if ( alerts.length > 0 ) {
    alertText += 'There is an active severe weather alert for your area.  ';
    alertText += alerts[0]['description'];
  }
}
  

// Report weather forecast
let text = cText + fText + wkText + alertText;
Speech.speak(text);


function forecastTable(days) {
  let table = new UITable();
  table.showSeparators = true;
  let header = new UITableRow();
  header.addText('Day');
  header.addText('Precip.');
  header.addText('Temp.');
  header.isHeader = true;
  header.hight = 40;
  table.addRow(header);

  for( let day of days) {
    let row = makeDayRow(day);
    table.addRow(row);
  }
  QuickLook.present(table);
}

function shortTimeStr(date) {
  let hr = date.getHours() % 12;
  let mn = date.getMinutes();
  let zmn = mn < 10 ? \"0\" : \"\";
  let ampm = date.getHours() <= 12 ? 'AM' : 'PM';
  return `${hr}:${zmn}${mn} ${ampm}`;
}

function dayOfWeek(dayNum) {
  switch (dayNum) {
    case 0:
      return 'Sunday';
      break;
    case 1:
      return 'Monday';
      break;
    case 2:
      return 'Tuesday';
      break;
    case 3:
      return 'Wednesday';
      break;
    case 4:
      return 'Thursday';
      break;
    case 5:
      return 'Friday';
      break;
    case 6:
      return 'Saturday';
      break;
    default:
      return '——';
      break;
  }
}

function forecastText(day) {
  let high = Math.round(day['temperatureHigh']);
  let highTime = new Date(day['temperatureHighTime']*1000);
  let low = Math.round(day['temperatureLow']);
  let lowTime = new Date(day['temperatureLowTime']*1000);
  let precip = Math.round(day['precipProbability']*100)
  let text = day['summary'];
  text += ` Low ${low} degrees at ${shortTimeStr(lowTime)}.`;
  text += ` High ${high} degrees at ${shortTimeStr(highTime)}.`;
  text += ` The chance of precipitation is ${precip} percent. `;
  if ( precip > 15 ) {
    text += 'Bring an umbrella. ';
  }
  return text
}

function makeDayRow(day) {
  let date = new Date(day['time']*1000);
  let dayOfWk = dayOfWeek(date.getDay());
  let high = Math.round(day['temperatureHigh']);
  let low = Math.round(day['temperatureLow']);
  let precip = Math.round(day['precipProbability']*100);
  let row = new UITableRow();
  let lCell = row.addText(dayOfWk);
  let mCell = row.addText(`${precip}%`);
  let rCell = row.addText(`${low}\\u00B0 – ${high}\\u00B0`);
  row.height = 40;
  return row;
}
2 Likes

Thanks for sharing :raised_hands:

1 Like