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):





















