Skip to content

Instantly share code, notes, and snippets.

@Vogeslu
Created July 15, 2021 19:47
Show Gist options
  • Save Vogeslu/bb8dfb42e55f7b774a36f4b02e43f470 to your computer and use it in GitHub Desktop.
Save Vogeslu/bb8dfb42e55f7b774a36f4b02e43f470 to your computer and use it in GitHub Desktop.
scriptable nextbike widget
// Maximum distance to next bike
const defaultDistance = 2000
// List only stations or stationless bikes as well
const onlyStations = true
// Auto update every 20 minutes
const autoUpdate = true
function getLocationApi(position, distance = defaultDistance) {
return `https://api.nextbike.net/maps/nextbike-live.json?lat=${position.latitude}&lng=${position.longitude}&distance=${distance}`;
}
const widget = await createWidget()
if (!config.runsInWidget) {
await widget.presentSmall()
}
Script.setWidget(widget)
Script.complete()
async function createWidget(items) {
const data = await getData()
const list = new ListWidget()
const header = list.addText("🚲 nextbike")
header.font = Font.mediumSystemFont(13)
if(data) {
list.addSpacer()
let nextStation = null;
if(data.countries.length > 0) {
const country = data.countries[0];
if(country.cities.length > 0) {
const city = country.cities[0];
for(const place of city.places) {
if((place.bike && !onlyStations) || !place.bike) {
nextStation = {
name: place.name,
bikesAvailable: place.bikes_available_to_rent,
distance: place.dist
}
break
}
}
}
}
if(nextStation == null) {
const label = list.addText("Keine Stationen / Räder in der Nähe")
label.font = Font.boldSystemFont(16)
label.textColor = Color.red()
} else {
const label = list.addText(nextStation.name)
label.font = Font.mediumSystemFont(10)
list.addSpacer(12)
const count = list.addText(`${nextStation.bikesAvailable} ${nextStation.bikesAvailable === 1 ? 'Rad' : 'Räder'} verfügbar`)
count.font = Font.boldSystemFont(16)
count.textColor = nextStation.bikesAvailable > 0 ? Color.green() : Color.red()
list.addSpacer(6)
const distance = list.addText(nextStation.distance >= 1000 ? `${(nextStation.distance / 1000).toFixed(2)} km entfernt` : `${(nextStation.distance).toFixed(2)} m entfernt`)
distance.font = Font.mediumSystemFont(11)
}
if(autoUpdate) list.refreshAfterDate = new Date(Date.now() + 60*20*1000)
} else {
list.addSpacer()
list.addText("Daten nicht verfügbar")
}
return list
}
async function getData() {
try {
const location = await getLocation()
if(location) {
let data = await new Request(getLocationApi(location)).loadJSON()
return data
} else {
return null
}
} catch(e) {
return null
}
}
async function getLocation() {
try {
if(args.widgetParameter) {
const fixedCoordinates = args.widgetParameter.split(",").map(parseFloat)
return { latitude: fixedCoordinates[0], longitude: fixedCoordinates[1] }
} else {
Location.setAccuracyToThreeKilometers()
return await Location.current()
}
} catch(e) {
return null;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment