In simple terms, I needed to solve the following problem: given the timetable loaded X minutes ago, find the number of minutes remaining until the bus departures now, and based on that, highlight the buses that are convenient to catch (i.e. which depart roughly when I reach the bus stop if I leave soon).
We remember that the timetable, as loaded, returns its output nicely compartmentalized into distinct <span>'s:
so the idea is to do the following at regular intervals:
- query all #bustime's for departure times;
- determine the time difference between those times and the current time
- update the number of minutes in #busreal's
- re-colour all #bus* according to the number of minutes left, taking into account the time it takes to walk to the bus stop.
function clock(){ var now = new Date(); var h=now.getHours(); var m=now.getMinutes(); var s = now.getSeconds(); $("#nowclock").text(((h>=10)?h:("0"+h)) + ":" + ((m>=10)?m:("0"+m)) + ":" + ((s>=10)?s:("0"+s))); if (s % 10 ==0 ) { var mintogo = 6; // walking distance to stop in minutes var togo = -1; var nextgo = -1; var num=0; var fnum=-1; var dom = $("iframe#miway").contents(); while(num<6) { var token = "#bustime"+num; var nextbus = dom.find(token).text().trim(); nextbus.replace("now","0 min"); var am = (nextbus.indexOf('am')>0); var pm = (nextbus.indexOf('pm')>0) var idx = nextbus.indexOf(' '); if (idx>0) nextbus = nextbus.substr(0,idx); var ddot = nextbus.indexOf(":"); if (ddot<0) return; var hh = parseInt(nextbus.substr(0,ddot)); var mm = parseInt(nextbus.substr(1+ddot,nextbus.length-ddot)); if (am && hh==12) hh=0; if (pm && hh<12) hh+=12; var hcarry=(h<20 && hh>20); var hhcarry=(h>20 && hh<20); if (hcarry) h+=24; if (hhcarry) hh+=24; var diffmin = (mm+hh*60) - (m+1+h*60); togo = diffmin - mintogo; var thiscol = buscolor(togo); var token = "#busnum"+num; if (num==0) token="#bustoken"; dom.find(token).css("background", thiscol); var mintxt = ':'+diffmin+'m'; if (diffmin<0) mintxt = ':-'; if (diffmin==0) mintxt = ':now'; if (num==0) { mintxt = '('+diffmin+' min)'; if (diffmin<0) mintxt = '(--)'; if (diffmin==0) mintxt = '(now)'; } dom.find("#bustime"+num).css("color", thiscol); dom.find("#bustime"+num).text('\xa0'+hh+":"+((mm<10)?"0":"")+mm+'\xa0'); dom.find("#busreal"+num).css("color", thiscol); dom.find("#busreal"+num).text(mintxt); if (togo>=0 && nextgo<0) { nextgo=diffmin; fnum=num+1; } num++; } dom.find("#realtime").text("leave in " + (nextgo-mintogo) + " min"); }}
where the auxiliary function buscolor() is simply
function buscolor(togo){ if (togo<0) return 'rgb(200,180,180)'; if (togo<=2) return 'rgb(255,200,0)'; if (togo<=4) return 'rgb(255,0,0)'; if (togo<=8) return 'rgb(255,64,64)'; if (togo<=15) return 'rgb(255,100,100)'; if (togo<60) return 'rgb(255,128,128)'; if (togo<120) return 'rgb(255,128,255)'; return 'rgb(255,0,255)' // error }
That's it. Note the following:
- The code handles both 12-hour and 24-hour times but the output is forced into 24-hour because it offers smaller footprint.
- The item number 0 has a different, more verbose output format; the additional #realtime contains a hint when to leave home for the "next suitable" bus.
- The container that should be called #busnum0 is called #bustoken instead. This is for historical reasons: the system looks for #bustoken as an indicator that the timetable has loaded.
It remains to be seen whether doing this every 10 seconds will prove feasible for the Playbook in terms of "mean time between refreshes / restarts".
Our mileage may vary even further. For example:
- we may imagine the code to throw out "missed" departures, moving the remaining ones up the queue, and even triggering an extra timetable refresh when there are too few (say <3) left;
- we may intelligently trigger an extra refresh every time we are nearing the "leave home in 2 minutes situation in order to make sure that the upcoming bus is still on schedule;
- we may keep track of how much the real-time departure information is changing between refreshes (provided they happen often enough) and detect when delays start to appear or frequently change (this is indicative of unstable traffic, warranting more frequent refreshes)...
No comments:
Post a Comment