noaa weather watch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function() { | |
return {name:"noaa"} | |
}) | |
var defaultZone = "ORZ006" | |
var alert_channel = "#pdxweather" | |
var major_alert_channel = "#portlandor" | |
function go(msg) { | |
var zone | |
var override = false | |
var ticktock = false | |
if (msg.method == "clocktower" && (new Date(Date.parse(msg.params.time))).getMinutes() == 30) { | |
ticktock = true | |
zone = defaultZone // db.get('noaa:zone') // bzzt wrong | |
} | |
if (msg.method == "irc.privmsg") { | |
var match = /^!?noaa(\s+(\w+))?$/.exec(msg.params.message) | |
if(match) { | |
override = true; | |
zone = match[2] ? match[2].toUpperCase() : defaultZone | |
} | |
} | |
if (override || ticktock) { | |
var url = "https://alerts.weather.gov/cap/wwaatmget.php?x="+zone.toUpperCase()+"&y=1" | |
var html = http.get(url).replace(/\n/g,"").replace(/\r/g,"") | |
var entry_ex = /<entry>(.*?)<\/entry>/g | |
var lines = html.match(entry_ex) | |
var say | |
if(lines) { | |
var reports = lines.map(xml_eat) | |
if(override) { | |
if(reports.length > 0) { | |
say_reports(msg.params.channel, reports, zone) | |
} else { | |
say = "NOAA has no alerts for zone "+zone | |
} | |
} else { | |
reports.forEach(notifyCheck) | |
} | |
} else { | |
if (html.length > 0) { | |
say = "NOAA return value not parsing correctly :( "+url+" "+html.length+" bytes" | |
} | |
} | |
return say | |
} | |
function say_reports(target, reports, zone) { | |
if (reports.length > 0) { | |
if (reports.length > 1) { | |
bot.say(target, reports.length+" NOAA reports for "+zone) | |
} | |
reports.forEach(function(r){ | |
//bot.say(bot.admin_channel, JSON.stringify(r)) | |
bot.say(target, summarize(r)) | |
}) | |
} | |
} | |
function summarize(data, short_summary){ | |
var msg = [] | |
var short_date = new Date(data.updated).toTimeString().replace(/GMT..... /,"").replace(/:\d\d /, ' ') | |
if(/There are no active/.exec(data.title)) { | |
msg.push(data.title) | |
msg.push("(updated "+short_date+")") | |
} else { | |
msg.push(data.event+"/"+data.severity+":") | |
msg.push(short_date) | |
var summary = data.summary.substr(0,288) | |
var summary_synopsis = /\.\.\.([0-9A-Z :]+)\.\.\./.exec(data.summary) | |
if (short_summary && summary_synopsis) { | |
summary = summary_synopsis[1] | |
} | |
msg.push(summary) | |
} | |
return msg.join(' ') | |
} | |
function notifyCheck(report){ | |
if (report.id) { | |
var db_key = 'noaa:'+report.id | |
db.get(db_key, function(last_date_str){ | |
var last_date = new Date(last_date_str || "2000-01-01") | |
if (last_date < report.updated) { | |
db.set(db_key, report.updated.toISOString()) | |
bot.say(alert_channel, summarize(report, true)) | |
if (report.severity == "Unknown" || report.severity == "Minor") { | |
} else { | |
bot.say(major_alert_channel, summarize(report, true)) | |
} | |
} | |
}) | |
//bot.say(bot.admin_channel, JSON.stringify(report)) | |
} else { | |
} | |
} | |
function xml_eat(xml) { | |
var data = {} | |
var id_url = field_grab(xml, 'id') | |
var id_match = /\?x=([^.]+)\./.exec(id_url) | |
if(id_match) { data.id = id_match[1] } | |
data.title = field_grab(xml, 'title') | |
var date = field_grab(xml, 'updated') | |
if(date) { | |
data.updated = new Date(date) | |
} | |
data.summary = field_grab(xml, 'summary') | |
data.event = field_grab(xml, 'cap:event') | |
data.urgency = field_grab(xml, 'cap:urgency') | |
data.severity = field_grab(xml, 'cap:severity') | |
data.certainty = field_grab(xml, 'cap:certainty') | |
data.category = field_grab(xml, 'cap:category') | |
data.type = field_grab(xml, 'cap:msgType') | |
return data | |
} | |
function field_grab(xml, name) { | |
var re = new RegExp('<'+name+'>(.*)<\/'+name+'>') | |
var match = re.exec(xml) | |
if(match) { | |
return match[1] | |
} | |
} | |
} | |
// *severity | |
// Unknown | |
// Minor | |
// Moderate | |
// Severe | |
// Extreme | |
// *event | |
// Special Weather Statement | |
// Winter Weather Advisory | |
// Flood Watch | |
// *type | |
// ALERT | |
/* | |
<entry> | |
<id>https://alerts.weather.gov/cap/wwacapget.php?x=OR125AC8C99AE8.DenseFogAdvisory.125AC8CC2A60OR.PQRNPWPQR.9eec68588ed4091a60a6334ee832bca5</id> | |
<updated>2018-11-24T17:22:00-08:00</updated> | |
<published>2018-11-24T17:22:00-08:00</published> | |
<author> | |
<name>w-nws.webmaster@noaa.gov</name> | |
</author> | |
<title>Dense Fog Advisory issued November 24 at 5:22PM PST until November 25 at 10:00AM PST by NWS</title> | |
<link href="https://alerts.weather.gov/cap/wwacapget.php?x=OR125AC8C99AE8.DenseFogAdvisory.125AC8CC2A60OR.PQRNPWPQR.9eec68588ed4091a60a6334ee832bca5"/> | |
<summary>...DENSE FOG ADVISORY IN EFFECT UNTIL 10 AM PST SUNDAY... The National Weather Service in Portland has issued a Dense Fog Advisory, which is in effect until 10 AM PST Sunday. * VISIBILITIES...A quarter of a mile or less. * TIMING...Through Sunday morning. * IMPACTS...Motorists are advised to use caution and slow down, as</summary> | |
<cap:event>Dense Fog Advisory</cap:event> | |
<cap:effective>2018-11-24T17:22:00-08:00</cap:effective> | |
<cap:expires>2018-11-25T10:00:00-08:00</cap:expires> | |
<cap:status>Actual</cap:status> | |
<cap:msgType>Alert</cap:msgType> | |
<cap:category>Met</cap:category> | |
<cap:urgency>Expected</cap:urgency> | |
<cap:severity>Minor</cap:severity> | |
<cap:certainty>Likely</cap:certainty> | |
<cap:areaDesc>Central Willamette Valley; Greater Portland Metro Area; Lower Columbia</cap:areaDesc> | |
<cap:polygon></cap:polygon> | |
<cap:geocode> | |
<valueName>FIPS6</valueName> | |
<value>041005 041009 041047 041051 041053 041067 041071</value> | |
<valueName>UGC</valueName> | |
<value>ORZ005 ORZ006 ORZ007</value> | |
</cap:geocode> | |
<cap:parameter> | |
<valueName>VTEC</valueName> | |
<value>/O.NEW.KPQR.FG.Y.0015.181125T0122Z-181125T1800Z/</value> | |
</cap:parameter> | |
</entry> | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment