2 % my $url = url_for 'weather';
7 <title>DWeather</title>
9 <meta http-equiv="X-UA-Compatible" content="IE=edge">
10 <meta name="viewport" content="width=device-width, initial-scale=1">
12 <!-- Latest compiled and minified CSS -->
13 <link rel="stylesheet" href="css/bootstrap.min.css">
15 <!-- Optional theme -->
16 <link rel="stylesheet" href="css/bootstrap-theme.min.css">
18 <!-- auto refresh (really only for the yr.no forecast) -->
19 <meta content="3600" http-equiv="Refresh">
24 <center><h1>High View Weather</h1></center>
29 var daychart_days = <%= $main::histdays %>;
31 var windrose_mins = <%= $main::windmins %>;
34 var updatespermin = <%= $main::updatepermin %>;
39 "Wind" : function (speed) { return (speed * 2.236936).toFixed(1); },
40 "Wind_1m" : function (speed) { return (speed * 2.236936).toFixed(1); },
41 "Wind_Max": function (speed) { return (speed * 2.236936).toFixed(1); }
45 function do_debug(text) {
46 document.getElementById("do_debug").innerHTML = text;
49 function update_h(key, value) {
53 function fill_html(key,value) {
54 var d = document.getElementById(key);
57 if (f && typeof(f) === "function") {
58 d.innerHTML = trans[key](value);
65 function traverse(o, func) {
68 if (o[i] !== null && typeof(o[i])==="object") {
82 ws = new WebSocket('<%= $url->to_abs %>');
84 if (typeof(ws) !== null) {
85 ws.onmessage = function (event) {
86 var js = JSON.parse(event.data);
87 if (js !== null && typeof(js) === 'object') {
88 traverse(js, fill_html);
89 // traverse(js, update_h);
90 // document.getElementById("hh").innerHTML = JSON.stringify(h);
92 fill_daychart(js, daychart_days);
94 if ("r" in js || "m" in js) {
101 fill_windrose(rr, windrose_mins * updatespermin);
109 ws.onopen = function (event) {
110 document.getElementById("wsconnect").innerHTML = 'ws connected to: <%= $url->to_abs %>';
111 ws.send('WebSocket support works!');
113 ws.onclose = function(event) {
114 document.getElementById("wsconnect").innerHTML = 'ws disconnected, refresh to restart';
118 document.body.innerHTML += 'Webserver only works with Websocket aware browsers';
122 function start_daychart() {
123 daychart = new Highcharts.Chart({
125 renderTo: 'daychart',
129 text: 'Last Five Days'
136 yAxis: [{ // Temperature +(ve)
156 color: Highcharts.getOptions().colors[0]
160 format: '{value} mm',
162 color: Highcharts.getOptions().colors[0]
169 text: 'Sea-Level Pressure',
175 format: '{value} mb',
198 }, { // Temperature -(ve)
206 // text: 'Temperature',
218 // layout: 'vertical',
221 // verticalAlign: 'top',
224 // backgroundColor: (Highcharts.theme && Highcharts.theme.legendBackgroundColor) || '#FFFFFF'
237 color: Highcharts.getOptions().colors[0],
240 // format: '{point.y:.1f}', // one decimal
246 for (@main::last5daysh) {
247 my $r = $main::json->decode($_);
248 $s .= "[" . $r->{t}*1000 . "," . $r->{h}->{Rain_1h} . "]," if $r && exists $r->{t} && exists $r->{h}->{Rain_1h};
250 chop $s if length $s;
258 name: 'Sea-Level Pressure',
264 for (@main::last5daysh) {
265 my $r = $main::json->decode($_);
266 $s .= "[" . $r->{t}*1000 . "," . $r->{h}->{Pressure} . "]," if $r && exists $r->{t} && exists $r->{h}->{Pressure};
268 chop $s if length $s;
274 dashStyle: 'shortdot',
280 name: 'Temperature +(ve)',
285 <% $s = ""; undef $lasttemp;
286 for (@main::last5daysh) {
287 my $r = $main::json->decode($_);
288 if ($r && exists $r->{t} && exists $r->{h}->{Temp_Out}) {
289 my $temp = $r->{h}->{Temp_Out};
290 my $tm = $r->{t}*1000;
291 $lasttemp = $temp unless defined $lasttemp;
293 $s .= sprintf "[%s,0],", $tm-1 if $lasttemp <= 0;
294 $s .= sprintf "[%s,%s],", $tm, $temp;
296 $s .= sprintf "[%s,%s],", $tm, $lasttemp > 0 ? 0 : "null";
301 chop $s if length $s;
314 for (@main::last5daysh) {
315 my $r = $main::json->decode($_);
316 $s .= "[" . $r->{t}*1000 . "," . $r->{h}->{Humidity_Out} . "]," if $r && exists $r->{t} && exists $r->{h}->{Humidity_Out};
318 chop $s if length $s;
324 dashStyle: 'shortdot',
329 name: 'Temperature -(ve)',
334 <% $s = ""; undef $lasttemp;
335 for (@main::last5daysh) {
336 my $r = $main::json->decode($_);
337 if ($r && exists $r->{t} && exists $r->{h}->{Temp_Out}) {
338 my $temp = $r->{h}->{Temp_Out};
339 my $tm = $r->{t}*1000;
340 $lasttemp = $temp unless defined $lasttemp;
342 $s .= sprintf "[%s,0],", $tm-1 if $lasttemp > 0;
343 $s .= sprintf "[%s,%s],", $tm, $temp;
345 $s .= sprintf "[%s,%s],", $tm, $lasttemp <= 0 ? 0 : "null";
350 chop $s if length $s;
360 function start_windrose() {
363 Highcharts.createElement('link', {
364 href: '//fonts.googleapis.com/css?family=Dosis:400,600',
367 }, null, document.getElementsByTagName('head')[0]);
370 colors: ["#7cb5ec", "#f7a35c", "#90ee7e", "#7798BF", "#aaeeee", "#ff0066", "#eeaaee",
371 "#55BF3B", "#DF5353", "#7798BF", "#aaeeee"],
373 backgroundColor: null,
375 fontFamily: "Dosis, sans-serif"
382 textTransform: 'uppercase'
387 backgroundColor: 'rgba(219,219,216,0.8)',
405 minorTickInterval: 'auto',
408 textTransform: 'uppercase'
425 background2: '#F0F0EA'
430 Highcharts.setOptions(Highcharts.theme);
432 windrose = new Highcharts.Chart({
452 formatter: function () {
453 return this.value + '°';
487 for (@main::last10minsr) {
488 my $r = $main::json->decode($_);
490 $r->{r}->{Dir} ||= $d;
491 $r->{r}->{Wind} ||= $w;
492 $s .= "[" . $r->{r}->{Dir} . "," . main::nearest(0.1, $r->{r}->{Wind}*2.23694) . "],";
494 $w = $r->{r}->{Wind};
497 chop $s if length $s;
504 function start_windspeed() {
505 windspeed = new Highcharts.Chart({
508 renderTo: 'windspeed',
509 plotBackgroundColor: null,
510 plotBackgroundImage: null,
524 linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
534 linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
543 // default background
545 backgroundColor: '#DDD',
557 minorTickInterval: 'auto',
560 minorTickPosition: 'inside',
561 minorTickColor: '#666',
563 tickPixelInterval: 30,
565 tickPosition: 'inside',
578 color: '#55BF3B' // green
582 color: '#DDDF0D' // yellow
586 color: '#DF5353' // red
607 function start_winddir() {
608 winddir = new Highcharts.Chart({
612 plotBackgroundColor: null,
613 plotBackgroundImage: null,
619 text: 'Wind Direction'
627 linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
637 linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
646 // default background
648 backgroundColor: '#DDD',
660 minorTickInterval: 'auto',
663 minorTickPosition: 'inside',
664 minorTickColor: '#666',
666 tickPixelInterval: 15,
668 tickPosition: 'inside',
691 valueSuffix: ' ° deg'
697 function fill_daychart(js, days) {
698 var rainfall = daychart.series[0].data.length > (days * 48);
699 var pressure = daychart.series[1].data.length > (days * 48);
700 var temppos = daychart.series[2].data.length > (days * 48);
701 var tempneg = daychart.series[4].data.length > (days * 48);
702 var humidity = daychart.series[3].data.length > (days * 48);
706 var ra = [t, hr.Rain_1h];
707 var pr = [t, hr.Pressure];
708 var te = [t, hr.Temp_Out];
709 var hu = [t, hr.Humidity_Out];
711 // do_debug(js.tm + " " + t + " " + te + "<br>");
712 daychart.series[0].addPoint(ra, true, rainfall);
713 daychart.series[1].addPoint(pr, true, pressure);
714 if (lasttemp <= -100) {
715 lasttemp = hr.Temp_Out;
717 if (hr.Temp_Out > 0) {
719 daychart.series[2].addPoint([t, 0], true, temppos);
721 daychart.series[2].addPoint([t, hr.Temp_Out], true, temppos);
723 daychart.series[2].addPoint([t, (lasttemp > 0) ? 0 : null], true, temppos);
725 if (hr.Temp_Out <= 0) {
727 daychart.series[4].addPoint([t, 0], true, tempneg);
729 daychart.series[4].addPoint([t, hr.Temp_Out], true, tempneg);
731 daychart.series[4].addPoint([t, (lasttemp <= 0) ? 0 : null], true, tempneg);
733 lasttemp = hr.Temp_Out;
734 daychart.series[3].addPoint(hu, true, humidity);
739 function fill_windrose(rr, points) {
740 var p = windrose.series[0].data.length > points;
741 var v = [rr.Dir, (rr.Wind*conv)];
742 windrose.series[0].addPoint(v, true, p);
745 function fill_windspeed(rr) {
746 var point = windspeed.series[0].points[0];
747 point.update(Math.round(rr.Wind*conv));
750 function fill_winddir(rr) {
751 var point = winddir.series[0].points[0];
752 point.update(rr.Dir);
755 window.onload = function() {
761 window.setInterval(function() {
771 <h4>Two Day Forecast</h2>
772 <a href="http://www.yr.no/place/United_Kingdom/England/Graffham~2648243/hour_by_hour.html"><img src="http://www.yr.no/place/United_Kingdom/England/Graffham~2648243/avansert_meteogram.png" alt="meteogram" title="" height="295" width="810"></a>
777 <div id="daychart" style="min-width: 400px; height: 400px; margin: 0 auto"> </div>
781 <table border="0" align="center">
783 <td id="windrose" style="min-width: 350px; max-width: 400px; height: 330px; margin: 0 auto"> </td>
784 <td id="windspeed" style="min-width: 280px; max-width: 400px; height: 270px; margin: 0 auto"> </td>
785 <td id="winddir" style="min-width: 280px; max-width: 400px; height: 270px; margin: 0 auto"> </td>
791 <div id="start-template">
793 <table class="table">
795 <th width="7%">Time:</th><td width="7%"><span id="tm"> </span></td>
796 <th width="7%">Sunrise:</th><td width="7%"><span id="Sunrise"> </span></td>
797 <th width="7%">Sunset:</th><td width="7%"><span id="Sunset"> </span></td>
798 <th width="7%">Console Volts:</th><td width="7%"><span id="Batt_Console"> </span></td>
799 <th width="7%">TX Battery OK:</th><td width="7%"><span id="Batt_TX_OK"> </span></td>
802 <th>Pressure:</th><td><span id="Pressure"> </span> mb</td>
803 <th>Trend:</th><td><span id="Pressure_Trend_txt"> </span></td>
806 <th>Temperature in:</th><td> <span id="Temp_In"> </span> °C</td>
807 <th>Humidity:</th><td> <span id="Humidity_In"> </span> %</td>
809 <tr><th>Temperature out:</th><td> <span id="Temp_Out"> </span> °C</td>
810 <th>Min:</th><td> <span id="Temp_Out_Min"> </span> °C @ <span id="Temp_Out_Min_T"> </span></td>
811 <th>Max:</th><td> <span id="Temp_Out_Max"> </span> °C @ <span id="Temp_Out_Max_T"> </span></td>
812 <th>Humidity:</th><td> <span id="Humidity_Out"> </span> %</td>
813 <th>Dew Point:</th><td> <span id="Dew_Point"> </span> °C</td>
815 <tr><th>Wind:</th><td><span id="Dir"> </span> ° @ <span id="Wind"> </span> mph</td>
816 <th>Wind Minute Avg:</th><td> <span id="Dir_1m"> </span> ° @ <span id="Wind_1m"> </span> mph </td>
817 <th>Day Max Speed:</th><td> <span id="Wind_Max"> </span> mph @ <span id="Wind_Max_T"> </span></td>
818 <th>Wind Chill:</th><td> <span id="WindChill"> °C</span></td>
821 <th>Rain 30mins:</th><td> <span id="Rain_1h"> </span> mm</td>
822 <th>Day:</th><td> <span id="Rain_Day"> </span> mm</td>
823 <th>24hrs:</th><td> <span id="Rain_24h"> </span> mm</td>
824 <th>Month:</th><td> <span id="Rain_Month"> </span> mm</td>
825 <th>Year:</th><td> <span id="Rain_Year"> </span> mm</td>
831 <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
832 <script src="js/jquery.min.js"></script>
833 <!-- Latest compiled and minified JavaScript -->
834 <script src="js/bootstrap.min.js"></script>
835 <!-- High Chart stuff -->
836 <script src="js/highcharts.js"></script>
837 <script src="js/highcharts-more.js"></script>
838 <script src="js/modules/exporting.js"></script>