Skip to content

Instantly share code, notes, and snippets.

@jiserra
Created September 20, 2020 04:38
Show Gist options
  • Save jiserra/01ee7262aba7bc180fb3904834c3fdb2 to your computer and use it in GitHub Desktop.
Save jiserra/01ee7262aba7bc180fb3904834c3fdb2 to your computer and use it in GitHub Desktop.
Scriptable widget for recycling days in NYC

How to obtain the FID for where you live

These are instructions to get the FID to use on the recycling.js Scriptable widget.

This is a bit of a complicated process, so bear with me!

  1. Go to https://www1.nyc.gov/assets/dsny/site/collectionSchedule/ and put your address to see your collection days. (If this is all you need, then you might not even need my widget! But I tend to forgot the day, or in case they change it…)
  2. Notice the "Sanitation District" name, e.g. BROOKLYN District 04
  3. Go to the visualization explorer of the API at https://data.cityofnewyork.us/d/rv63-53db/visualization
  4. Click on the MAP icon. It's like a globe and it's on the top center of the page.
  5. On the right, there's a "Filters" pane. Add a "DISTRICT" filter and look for your District (in the previous case is BKN 04)
  6. On the left, on the Map Layers pane, select "Flyout Details" and on "Flyout Title" choose FID
  7. Now try to find the zone where your home is. If you mouse over the zone, it will tell you which FID corresponds to.
  8. Now you can use the Scriptable widget by entering the FID variable on line 6!
// Variables used by Scriptable.
// These must be at the very top of the file. Do not edit.
// icon-color: green; icon-glyph: trash;
// This is the ID for your collection zone. I explain how to obtain this in the other recycling-data.md gist
let FID = REPLACE THIS WITH YOUR FID;
Date.prototype.addDays = function(days) {
var date = new Date(this.valueOf());
date.setDate(date.getDate() + days);
return date;
}
// Call the API
let items = await loadItems()
// Create widget
let widget = await createWidget(items)
// Check if the script is running in
// a widget. If not, show a preview of
// the widget to easier debug it.
if (!config.runsInWidget) {
await widget.presentSmall()
}
// Tell the system to show the widget.
Script.setWidget(widget)
Script.complete()
async function createWidget(items) {
let today = new Date()
//let today = new Date(2020, 08, 15) //I know that this day they pick up recycling. Modify to a known day and uncomment to test
let tomorrow = today.addDays(1)
// The way the DSNY API gives the days is in a string like "Tue, Thu, Sat", so I need to reduce the date to a string to match a day like that.
today = today.toDateString().substring(0, 3)
tomorrow = tomorrow.toDateString().substring(0, 3)
// Get the days from the JSON that the API gave us
// let commonTrash = JSON.stringify(items[0].freq_bulk) //This is not used, but if you want to know when they pick up the common trash, you can do something with this.
let recycling = JSON.stringify(items[0].freq_recycling)
// Checks if the today or tomorrow are included in the string that the API gave us
let todayRecycling = recycling.includes(today)
let tomorrowRecycling = recycling.includes(tomorrow)
// Gradient to make it nicer
let gradient = new LinearGradient()
gradient.locations = [0, 1]
gradient.colors = [
new Color("#ffffff4c"),
new Color("#ffffff00")
]
let w = new ListWidget()
// Check if we're going to write text
let noText = false
if(todayRecycling || tomorrowRecycling) {
// A nice green to call our attention that Today or Tomorrow is recycling day!
w.backgroundColor = new Color("#026B47")
} else {
// No text and a boring gray indicating no activity today or tomorrow
noText = true
w.backgroundColor = new Color("#444")
}
w.backgroundGradient = gradient
w.addSpacer()
// Print some text! (Double negative, I know…)
if(!noText) {
let recycleDay
if(todayRecycling) {
recycleDay = "TODAY"
} else if(tomorrowRecycling) {
recycleDay = "TOMORROW"
}
let title = w.addText(recycleDay)
title.font = Font.boldSystemFont(17)
title.textColor = Color.white()
title.textOpacity = 0.9
title.centerAlignText()
w.addSpacer(4)
}
// You need to save the image "recycle.png" on your Scriptable folder in iCloud. You can download the file here: https://www.dropbox.com/s/zx0608bxngc63ev/recycle.png?dl=0
var fm = FileManager.iCloud()
var dir = fm.documentsDirectory()
let path = dir + '/recycle.png'
await fm.downloadFileFromiCloud(path)
let recycleImg = fm.readImage(path)
let logo = w.addImage(recycleImg)
logo.centerAlignImage()
logo.imageOpacity = 0.5
w.addSpacer()
return w
}
// Call the API and return only what we want. If you don't filter the API with the $select, it gives you a bunch of other data. You can check it out at https://data.cityofnewyork.us/City-Government/DSNY-Frequencies/rv63-53db/data
async function loadItems() {
let url = "https://data.cityofnewyork.us/resource/rv63-53db.json?fid=" + FID + "&$select=freq_bulk,freq_recycling";
let req = new Request(url)
req.headers = {
'Content-Type': 'application/json'
}
let json = await req.loadJSON()
//console.log(json)
return json
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment