Wednesday, May 20, 2020

Old Phone/Tablet as an Info Board: Update 3 - The elusive sunrises and sunsets

While I was messing up with the infoboard's bus widget, I also decided to touch up on the weather forecast (see the detailed description in the earlier post) and and add a few more visual cues to it.

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. (And your mileage may vary here too, distinguishing weekdays from weekends and even accounting for statutory holidays if need 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():

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