I wanted to distinguish day and night, so that it becomes immediately clear how the weather behaves at sunset and during the morning commute, kind of like so:
My first attempt was very simple: I added a function eachTime() that did this:
function eachTime(){ var str = $(this).text(); var hhmm = str.split(":"); var sunrise = 6; var sunset = 22; if (hhmm[0]>=sunset || hhmm[0] < sunrise) { $(this).css("background","rgb(0,0,0)"); $(this).css("color","rgb(255,255,255)"); }}
along with a single line in forecast():
$("#rowTime").find("td").each(eachTime);
However, this seemed a bit artificial to declare night as "anything from 22:00 till 6:00", so I wanted actual sunrise/sunset times to be calculated. Although, with my degree of precision of 1 hour, this seemed like a relatively simple mathematical task, there was no need to reinvent the wheel since PHP already has date_sunrise() and date_sunset() functions. So I geared up a new PHP script as follows:
<?php $remote_dtz = new DateTimeZone('US/Eastern'); $remote_dt = new DateTime("now", $remote_dtz); $offset = ($remote_dtz->getOffset($remote_dt))/3600; $lat=43.6;$lon=-79.6; echo '<html><head></head><body>'; echo '<span id="sunrise">'; echo(ceil(date_sunrise(time(),SUNFUNCS_RET_DOUBLE,$lat,$lon,90,$offset))); echo '</span>'; echo(':'); echo '<span id="sunset">'; echo(ceil(date_sunset(time(),SUNFUNCS_RET_DOUBLE,$lat,$lon,90,$offset))); echo '</span>';echo '</body></html>'; ?>
The only trick here is to get the correct GMT offset; I am also rounding up the result to the nearest hour. It is then very easy to load this script in another hidden iframe like so:
<iframe id="astronomy" style="visibility: hidden; height: 0px !important;" src="astro.php"> </iframe>
and amend eachTime() as follows:
function eachTime(){ var str = $(this).text(); var hhmm = str.split(":"); var dom=$("iframe#astronomy").contents(); var sunrise = 6; var sunset = 22; //fallback sunrise = parseInt(dom.find("#sunrise").text()); sunset = parseInt(dom.find("#sunset").text()); var commute = 8; if (hhmm[0]>=sunset || hhmm[0] < sunrise) { $(this).css("background","rgb(0,0,0)"); $(this).css("color","rgb(255,255,255)"); if (hhmm[0]==commute){ $(this).css("color","rgb(225,255,0)");$(this).css("border","1px solid yellow");} } else{ if (hhmm[0]==commute) {$(this).css("border","1px solid black"); $(this).css("background","rgb(255, 213, 171)");}} }
There is no need to bother about refreshing astro.php because the entire system refreshes at 2 am every day anyway, and even if we happen to be 1 day off we are well within the desired accuracy margin. In addition I have added a cue mark for the morning commute, which is (unfortunately) independent of where the Sun happens to be.
BONUS: As an addition, notably after a strong wind storm in our area, I wanted to colour code wind as well, along with rain and temperature. Here's what I changed about eachWind():
So the colour intensity and hue can independently give some information about how strong and how gusty the wind is, more or less like so (yes I did it on Wolfram Cloud for a quick illustration):
function windgradient(base,gust){ var b=(base>=80)?1.0:(base/80.0); var g=((gust-base)>=25)?1.0:((gust-base)/25.0); if (g<0) g=0; b=Math.pow(b,0.75);g=Math.pow(g,1.0); return "rgb(" + Math.round(255.0) + "," + Math.round(255.0*(1.0-b*g)) + "," + Math.round(255.0*(1.0-b)) + ")"; } function eachWind(){ var rawstr = str = $(this).text().trim(); var str = rawstr.split(String.fromCharCode(160)); var result = "rgb(255,255,255)"; var speed = 0; try { speed = parseInt(str[1]);} catch(ignore){speed=0;} var gust=speed; if(rawstr.indexOf("gust")!=-1) {try { gust = parseInt(str[2]);} catch(ignore){gust=speed;}} result=windgradient(Math.round((speed+gust)/2.0),gust); $(this).css("background",result); $(this).text(rawstr.replace("gust",">")); }
So the colour intensity and hue can independently give some information about how strong and how gusty the wind is, more or less like so (yes I did it on Wolfram Cloud for a quick illustration):
No comments:
Post a Comment