Skip to content

Instantly share code, notes, and snippets.

@donpdonp
Last active January 10, 2019 01:46
Show Gist options
  • Save donpdonp/d431d8f73f4792d250b7e8bf8fa40ae0 to your computer and use it in GitHub Desktop.
Save donpdonp/d431d8f73f4792d250b7e8bf8fa40ae0 to your computer and use it in GitHub Desktop.
gluon darksky
(function() {
// setup
setup()
// descriptor
return {name:"darksky"}
})
var api_key
function setup() {
db.get('darksky:key', function(key){
if(key) {
api_key = key
bot.say(bot.admin_channel, "darksky: api key loaded")
} else {
bot.say(bot.admin_channel, "darksky: api key missing")
}
})
}
function go(msg) {
if (msg.method == "irc.privmsg") {
var cmd = /^!darksky/.exec(msg.params.message)
if(cmd) {
apiSince(msg.params.nick, function(api_since){
if(api_since > 60*5) {
rainTrack(msg.params.nick, msg.params.channel)
} else {
var until_min = 5 - (api_since/60)
bot.say(msg.params.channel, msg.params.nick+': darksky api cooldown for '+until_min.toFixed(1)+' min')
}
})
}
}
if(msg.method == "icecondor.location") {
var location = msg.params
apiSince(location.username, function(api_since){
bot.say(bot.admin_channel, "darksky "+location.username+" api since "+(api_since/60).toFixed(0)+" mins ["+location.id+"]")
if(api_since > 60*5) {
var forecast = forecastFor(location)
api(location.username)
var stormChance = stormApproaches(forecast.minutely.data)
var minutely = forecast.minutely.data.map(function(d){return d.precipProbability})
bot.say(bot.admin_channel, "darksky "+location.username+
" stormChance "+(stormChance*100).toFixed(0)+"%. ["+minutely.join(' ')+"]")
if(stormChance > 0.5) {
bot.say('#pdxbots', "darksky "+location.username+" 15min storm approaches! "+stormChance+" probability.")
alertSince(location.username, function(alert_since) {
bot.say(bot.admin_channel, "darksky "+location.username+" storm alert since "+(alert_since/60/60).toFixed(0)+" hours")
if(alert_since > 60*60*24) {
alert(location.username)
}
})
}
}
})
}
}
function rainTrack(username, channel) {
db.get('icecondor:user'+':'+username+':track', function(trackJson){
if(trackJson) {
var track = JSON.parse(trackJson)
var location = track.location
var date = new Date(location.date)
var ago_min = (new Date() - date)/1000/60
var forecast = forecastFor(location)
api(username)
var minutely = forecast.minutely.data.map(function(d){
//return d.precipProbability+"/"+d.precipIntensity
return d.precipProbability
})
var parts = [username+":", location.longitude.toFixed(4), location.latitude.toFixed(4),
ago_min.toFixed(0), 'min ago.', 'rain probabilities:', minutely.join(' ')]
bot.say(channel, parts.join(' '))
} else {
bot.say(channel, "no icecondor track for "+username)
}
})
}
function forecastFor(location) {
var url = 'https://api.darksky.net/forecast/'+api_key+'/'+location.latitude+','+location.longitude
var json = http.get(url)
return JSON.parse(json)
}
function stormApproaches(data) {
var highwater = 0
if(data[0].precipProbability < 0.5) {
for(var i=0; i < 15; i++) {
if(data[i].precipProbability >= highwater) {
highwater = data[i].precipProbability
} else {
return 0 // strictly increasing check
}
}
} else {
// already in a storm
}
return highwater
}
function apiSince(username, cb) {
var dbkey = 'darksky:api:'+username
return dbSince(dbkey, username, cb)
}
function alertSince(username, cb) {
var dbkey = 'darksky:alert:'+username
return dbSince(dbkey, username, cb)
}
function dbSince(dbkey,value,cb) {
db.get(dbkey, function(last_call){
if(!last_call) {
last_call = new Date("1980-01-01")
} else {
last_call = new Date(last_call)
}
var since = (new Date() - last_call)/1000
cb(since)
})
}
function api(username) {
var dbkey = 'darksky:api:'+username
return dbNow(dbkey)
}
function alert(username) {
var dbkey = 'darksky:alert:'+username
return dbNow(dbkey)
}
function dbNow(dbkey) {
var now = new Date()
db.set(dbkey, now.toISOString())
return now
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment