1 % my $url = url_for 'weather';
6 <title>DWeather</title>
8 <meta http-equiv="X-UA-Compatible" content="IE=edge">
9 <meta name="viewport" content="width=device-width, initial-scale=1">
11 <!-- Latest compiled and minified CSS -->
12 <link rel="stylesheet" href="css/bootstrap.min.css">
14 <!-- Optional theme -->
15 <link rel="stylesheet" href="css/bootstrap-theme.min.css">
19 <center><h1>High View Weather</h1></center>
24 var daychart_days = <%= $main::histdays %>;
26 var windrose_mins = <%= $main::windmins %>;
29 var updatespermin = <%= $main::updatepermin %>;
34 "Wind" : function (speed) { return (speed * 2.236936).toFixed(1); },
35 "Wind_1m" : function (speed) { return (speed * 2.236936).toFixed(1); },
36 "Wind_Max": function (speed) { return (speed * 2.236936).toFixed(1); }
40 function do_debug(text) {
41 document.getElementById("do_debug").innerHTML = text;
44 function update_h(key, value) {
48 function fill_html(key,value) {
49 var d = document.getElementById(key);
52 if (f && typeof(f) === "function") {
53 d.innerHTML = trans[key](value);
60 function traverse(o, func) {
63 if (o[i] !== null && typeof(o[i])==="object") {
76 ws = new WebSocket('<%= $url->to_abs %>');
78 if (typeof(ws) !== null) {
79 ws.onmessage = function (event) {
80 var js = JSON.parse(event.data);
81 if (js !== null && typeof(js) === 'object') {
82 traverse(js, fill_html);
83 // traverse(js, update_h);
84 // document.getElementById("hh").innerHTML = JSON.stringify(h);
86 fill_daychart(js, daychart_days);
88 if ("r" in js || "m" in js) {
95 fill_windrose(rr, windrose_mins * updatespermin);
103 ws.onopen = function (event) {
104 document.getElementById("wsconnect").innerHTML = 'ws connected to: <%= $url->to_abs %>';
105 ws.send('WebSocket support works!');
107 ws.onclose = function(event) {
108 document.getElementById("wsconnect").innerHTML = 'ws disconnected, refresh to restart';
112 document.body.innerHTML += 'Webserver only works with Websocket aware browsers';
116 function start_daychart() {
117 daychart = new Highcharts.Chart({
119 renderTo: 'daychart',
123 text: 'Five Day Chart'
130 yAxis: [{ // Primary yAxis
145 }, { // Secondary yAxis
150 color: Highcharts.getOptions().colors[0]
154 format: '{value} mm',
156 color: Highcharts.getOptions().colors[0]
160 }, { // Tertiary yAxis
163 text: 'Sea-Level Pressure',
165 color: Highcharts.getOptions().colors[1]
169 format: '{value} mb',
171 color: Highcharts.getOptions().colors[1]
175 }, { // Tertiary yAxis
200 verticalAlign: 'top',
203 backgroundColor: (Highcharts.theme && Highcharts.theme.legendBackgroundColor) || '#FFFFFF'
218 // format: '{point.y:.1f}', // one decimal
224 for (@main::last5daysh) {
225 my $r = $main::json->decode($_);
226 $s .= "[" . $r->{t}*1000 . "," . $r->{h}->{Rain_1h} . "]," if $r && exists $r->{t} && exists $r->{h}->{Rain_1h};
228 chop $s if length $s;
236 name: 'Sea-Level Pressure',
241 for (@main::last5daysh) {
242 my $r = $main::json->decode($_);
243 $s .= "[" . $r->{t}*1000 . "," . $r->{h}->{Pressure} . "]," if $r && exists $r->{t} && exists $r->{h}->{Pressure};
245 chop $s if length $s;
251 dashStyle: 'shortdot',
263 for (@main::last5daysh) {
264 my $r = $main::json->decode($_);
265 $s .= "[" . $r->{t}*1000 . "," . $r->{h}->{Temp_Out} . "]," if $r && exists $r->{t} && exists $r->{h}->{Temp_Out};
267 chop $s if length $s;
280 for (@main::last5daysh) {
281 my $r = $main::json->decode($_);
282 $s .= "[" . $r->{t}*1000 . "," . $r->{h}->{Humidity_Out} . "]," if $r && exists $r->{t} && exists $r->{h}->{Humidity_Out};
284 chop $s if length $s;
290 dashStyle: 'shortdot',
298 function start_windrose() {
301 Highcharts.createElement('link', {
302 href: '//fonts.googleapis.com/css?family=Dosis:400,600',
305 }, null, document.getElementsByTagName('head')[0]);
308 colors: ["#7cb5ec", "#f7a35c", "#90ee7e", "#7798BF", "#aaeeee", "#ff0066", "#eeaaee",
309 "#55BF3B", "#DF5353", "#7798BF", "#aaeeee"],
311 backgroundColor: null,
313 fontFamily: "Dosis, sans-serif"
320 textTransform: 'uppercase'
325 backgroundColor: 'rgba(219,219,216,0.8)',
343 minorTickInterval: 'auto',
346 textTransform: 'uppercase'
363 background2: '#F0F0EA'
368 Highcharts.setOptions(Highcharts.theme);
370 windrose = new Highcharts.Chart({
390 formatter: function () {
391 return this.value + '°';
425 for (@main::last10minsr) {
426 my $r = $main::json->decode($_);
428 $r->{r}->{Dir} ||= $d;
429 $r->{r}->{Wind} ||= $w;
430 $s .= "[" . $r->{r}->{Dir} . "," . main::nearest(0.1, $r->{r}->{Wind}*2.23694) . "],";
432 $w = $r->{r}->{Wind};
435 chop $s if length $s;
442 function start_windspeed() {
443 windspeed = new Highcharts.Chart({
446 renderTo: 'windspeed',
447 plotBackgroundColor: null,
448 plotBackgroundImage: null,
462 linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
472 linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
481 // default background
483 backgroundColor: '#DDD',
495 minorTickInterval: 'auto',
498 minorTickPosition: 'inside',
499 minorTickColor: '#666',
501 tickPixelInterval: 30,
503 tickPosition: 'inside',
516 color: '#55BF3B' // green
520 color: '#DDDF0D' // yellow
524 color: '#DF5353' // red
545 function start_winddir() {
546 winddir = new Highcharts.Chart({
550 plotBackgroundColor: null,
551 plotBackgroundImage: null,
557 text: 'Wind Direction'
565 linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
575 linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
584 // default background
586 backgroundColor: '#DDD',
598 minorTickInterval: 'auto',
601 minorTickPosition: 'inside',
602 minorTickColor: '#666',
604 tickPixelInterval: 15,
606 tickPosition: 'inside',
629 valueSuffix: ' ° deg'
635 function fill_daychart(js, days) {
636 var rainfall = daychart.series[0].data.length > (days * 48);
637 var pressure = daychart.series[1].data.length > (days * 48);
638 var temp = daychart.series[2].data.length > (days * 48);
639 var humidity = daychart.series[3].data.length > (days * 48);
643 var ra = [t, hr.Rain_1h];
644 var pr = [t, hr.Pressure];
645 var te = [t, hr.Temp_Out];
646 var hu = [t, hr.Humidity_Out];
648 // do_debug(js.tm + " " + t + " " + te + "<br>");
649 daychart.series[0].addPoint(ra, true, rainfall);
650 daychart.series[1].addPoint(pr, true, pressure);
651 daychart.series[2].addPoint(te, true, temp);
652 daychart.series[3].addPoint(hu, true, humidity);
657 function fill_windrose(rr, points) {
658 var p = windrose.series[0].data.length > points;
659 var v = [rr.Dir, (rr.Wind*conv)];
660 windrose.series[0].addPoint(v, true, p);
663 function fill_windspeed(rr) {
664 var point = windspeed.series[0].points[0];
665 point.update(Math.round(rr.Wind*conv));
668 function fill_winddir(rr) {
669 var point = winddir.series[0].points[0];
670 point.update(rr.Dir);
673 window.onload = function() {
679 window.setInterval(function() {
688 <div id="daychart" style="min-width: 400px; height: 400px; margin: 0 auto"> </div>
692 <table border="0" align="center">
694 <td id="windrose" style="min-width: 350px; max-width: 400px; height: 330px; margin: 0 auto"> </td>
695 <td id="windspeed" style="min-width: 280px; max-width: 400px; height: 270px; margin: 0 auto"> </td>
696 <td id="winddir" style="min-width: 280px; max-width: 400px; height: 270px; margin: 0 auto"> </td>
702 <div id="start-template">
704 <table class="table">
706 <th width="7%">Time:</th><td width="7%"><span id="tm"> </span></td>
707 <th width="7%">Sunrise:</th><td width="7%"><span id="Sunrise"> </span></td>
708 <th width="7%">Sunset:</th><td width="7%"><span id="Sunset"> </span></td>
709 <th width="7%">Console Volts:</th><td width="7%"><span id="Batt_Console"> </span></td>
710 <th width="7%">TX Battery OK:</th><td width="7%"><span id="Batt_TX_OK"> </span></td>
713 <th>Pressure:</th><td><span id="Pressure"> </span> mb</td>
714 <th>Trend:</th><td><span id="Pressure_Trend_txt"> </span></td>
717 <th>Temperature in:</th><td> <span id="Temp_In"> </span> °C</td>
718 <th>Humidity:</th><td> <span id="Humidity_In"> </span> %</td>
720 <tr><th>Temperature out:</th><td> <span id="Temp_Out"> </span> °C</td>
721 <th>Min:</th><td> <span id="Temp_Out_Min"> </span> °C @ <span id="Temp_Out_Min_T"> </span></td>
722 <th>Max:</th><td> <span id="Temp_Out_Max"> </span> °C @ <span id="Temp_Out_Max_T"> </span></td>
723 <th>Humidity:</th><td> <span id="Humidity_Out"> </span> %</td>
724 <th>Dew Point:</th><td> <span id="Dew_Point"> </span> °C</td>
726 <tr><th>Wind:</th><td><span id="Dir"> </span> ° @ <span id="Wind"> </span> mph</td>
727 <th>Wind Minute Avg:</th><td> <span id="Dir_1m"> </span> ° @ <span id="Wind_1m"> </span> mph </td>
728 <th>Day Max Speed:</th><td> <span id="Wind_Max"> </span> mph @ <span id="Wind_Max_T"> </span></td>
731 <th>Rain 30mins:</th><td> <span id="Rain_1h"> </span> mm</td>
732 <th>Day:</th><td> <span id="Rain_Day"> </span> mm</td>
733 <th>24hrs:</th><td> <span id="Rain_24h"> </span> mm</td>
734 <th>Month:</th><td> <span id="Rain_Month"> </span> mm</td>
735 <th>Year:</th><td> <span id="Rain_Year"> </span> mm</td>
742 <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
743 <script src="js/jquery.min.js"></script>
744 <!-- Latest compiled and minified JavaScript -->
745 <script src="js/bootstrap.min.js"></script>
746 <!-- High Chart stuff -->
747 <script src="js/highcharts.js"></script>
748 <script src="js/highcharts-more.js"></script>
749 <script src="js/modules/exporting.js"></script>