Skip to content
This repository was archived by the owner on Aug 23, 2021. It is now read-only.

Commit a01fb47

Browse files
committed
Create pusher.com based update system - moving away from constant ajax polling
Needs Jbithell/PSCWeather#4 to be done first, as otherwise no new data will come through
1 parent 75481cf commit a01fb47

File tree

6 files changed

+145
-115
lines changed

6 files changed

+145
-115
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
# PSCWeather
2+
Uses a live socket connection to Pusher.com to show live weather for Porthmadog (with initial data sent from server)
23

34
![Screenshot](https://raw.githubusercontent.com/Jbithell/PSCWeatherStation/master/assets/img/github/screenshot1.PNG)

assets/config.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
//CONFIG
2+
var minutesbeforewarn = 10; //How many minutes out of the data be before a warning is shown
3+
var minutesbeforefail = 120; //How many minutes out of date should the data be before not showing it at all
4+
var updateurl = 'https://www.jbithell.com/projects/psc/weatherapi/live.php';
5+
var pusherConnectionCode = '27e40eb1326fedfd3bc4';
6+
7+
Pusher.logToConsole = false;

assets/functions.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
function findBootstrapEnvironment() { //Work ou the current client size
2+
//from https://stackoverflow.com/a/15150381/3088158
3+
var envs = ['xs', 'sm', 'md', 'lg'];
4+
5+
var $el = $('<div>');
6+
$el.appendTo($('body'));
7+
8+
for (var i = envs.length - 1; i >= 0; i--) {
9+
var env = envs[i];
10+
11+
$el.addClass('hidden-'+env);
12+
if ($el.is(':hidden')) {
13+
$el.remove();
14+
return env;
15+
}
16+
}
17+
}
18+
function sizeCharts() { //Calculate the size the charts should be
19+
var environemntSize = findBootstrapEnvironment();
20+
if (environemntSize == "lg" || environemntSize == "md") {
21+
var dimensions = (($('#maindisplayrow').width()))/6;
22+
} else if (environemntSize == "sm") {
23+
var dimensions = (($('#maindisplayrow').width()))/3;
24+
} else {
25+
var dimensions = (($('#maindisplayrow').width()));
26+
}
27+
28+
$('canvas[data-type="radial-gauge"]').attr('data-width', dimensions);
29+
$('canvas[data-type="radial-gauge"]').attr('data-height', dimensions);
30+
}
31+
//How to handle window being resized
32+
$( document ).ready(function() {
33+
sizeCharts();
34+
});
35+
$( window ).resize(function() {
36+
sizeCharts();
37+
});
38+
39+
function drawCharts(callback) { //Draw the charts
40+
gauges["winddirectiongauge"] = document.gauges.get('winddirectiongauge');
41+
gauges["windgauge"] = document.gauges.get('windgauge');
42+
gauges["windaveragegauge"] = document.gauges.get('windaveragegauge');
43+
gauges["windgustgauge"] = document.gauges.get('windgustgauge');
44+
gauges["humiditygauge"] = document.gauges.get('humiditygauge');
45+
gauges["tempgauge"] = document.gauges.get('tempgauge');
46+
47+
if( typeof callback == "function" ) {
48+
callback();
49+
} else {
50+
return true;
51+
}
52+
}
53+
function displayData(dataPacket) { //Update the data in the charts
54+
gauges["winddirectiongauge"].value = dataPacket['windDirection'];
55+
gauges["windgauge"].value = dataPacket['windSpeedMPH'];
56+
gauges["windaveragegauge"].value = dataPacket['windSpeed10MinAverageMPH'];
57+
gauges["windgustgauge"].value = dataPacket['windSpeed10MinGustMPH'];
58+
gauges["tempgauge"].value = dataPacket['temperatureC'];
59+
gauges["humiditygauge"].value = dataPacket['humidity'];
60+
61+
//Update page HTML as required
62+
$("#lastupdate").html("Last updated " + new Date(dataPacket['timestamp']*1000).toUTCString());
63+
64+
$("#compassimage").attr("src", "assets/img/compass/" + (Math.round(dataPacket["windDirection"] / 10) * 10) + ".png");
65+
$(window).trigger('resize'); //To refresh the display handling
66+
}

assets/main.js

Lines changed: 54 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1,148 +1,90 @@
1+
var pusher = new Pusher(pusherConnectionCode, {
2+
cluster: 'eu',
3+
encrypted: true
4+
});
15

2-
var minutesbeforewarn = 10; //How many minutes out of the data be before a warning is shown
3-
var minutesbeforefail = 120; //How many minutes out of date should the data be before not showing it at all
4-
var pollforupdatesseconds = 30; //How often (in seconds) to check for an update on the server
5-
6-
//Initialize some vars
7-
var loadingdialog, nointernetdialog, closeddialog;
8-
var nointernetdialogshown = false;
9-
var gauges = [];
10-
var updateurl = 'https://www.jbithell.com/projects/psc/weatherapi/live.php';
11-
12-
13-
function findBootstrapEnvironment() {
14-
//from https://stackoverflow.com/a/15150381/3088158
15-
var envs = ['xs', 'sm', 'md', 'lg'];
16-
17-
var $el = $('<div>');
18-
$el.appendTo($('body'));
6+
//Pusher Error handling
7+
pusher.connection.bind( 'error', function( err ) {
8+
if( err.error.data.code === 4004 ) {
9+
console.log("Too many clients connected to device") //TODO Handle this
10+
}
11+
});
1912

20-
for (var i = envs.length - 1; i >= 0; i--) {
21-
var env = envs[i];
13+
//Pusher connection management
14+
pusher.connection.bind('state_change', function(states) {
15+
// states = {previous: 'oldState', current: 'newState'}
16+
$('#connectionstatus').text(" | You are " + states.current);
17+
});
2218

23-
$el.addClass('hidden-'+env);
24-
if ($el.is(':hidden')) {
25-
$el.remove();
26-
return env;
27-
}
28-
}
29-
}
30-
function sizeCharts() {
31-
var environemntSize = findBootstrapEnvironment();
32-
if (environemntSize == "lg" || environemntSize == "md") {
33-
var dimensions = (($('#maindisplayrow').width()))/6;
34-
} else if (environemntSize == "sm") {
35-
var dimensions = (($('#maindisplayrow').width()))/3;
36-
} else {
37-
var dimensions = (($('#maindisplayrow').width()));
38-
}
19+
//Connect to channel
20+
var channel = pusher.subscribe('PSCWeatherDataLive');
3921

40-
$('canvas[data-type="radial-gauge"]').attr('data-width', dimensions);
41-
$('canvas[data-type="radial-gauge"]').attr('data-height', dimensions);
42-
}
43-
function drawCharts(callback) {
44-
gauges["winddirectiongauge"] = document.gauges.get('winddirectiongauge');
45-
gauges["windgauge"] = document.gauges.get('windgauge');
46-
gauges["windaveragegauge"] = document.gauges.get('windaveragegauge');
47-
gauges["windgustgauge"] = document.gauges.get('windgustgauge');
48-
gauges["humiditygauge"] = document.gauges.get('humiditygauge');
49-
gauges["tempgauge"] = document.gauges.get('tempgauge');
22+
//Initialize some vars
23+
var gauges = [];
5024

51-
if( typeof callback == "function" ) {
52-
callback();
53-
} else {
54-
return true;
55-
}
56-
}
57-
//Download chart data
58-
function updatedata() {
59-
$("#updatestatus").addClass("fa-spin");
25+
//Download chart data from the server - so that earlier data is available.
26+
function pullServerData() {
6027
$.ajax({
6128
url: updateurl, success: function (response) {
6229
if (response.success) {
6330
if (response.message.closed == true) {
64-
//Winter closure of weather station - although it can be used for any time of year really
65-
$("#loading").hide();
31+
//Maintenence closure of weather station - although it can be used for any time of year really
6632
loadingdialog.modal('hide');
67-
//Remove no-internet modal if it's there
68-
if (nointernetdialogshown) {
69-
nointernetdialog.modal('hide');
70-
}
7133
$(".datadisplay").hide();
7234
$("#stationcloseddialogue").show();
7335
$("#stationclosedmessage").html(response.message.message);
74-
7536
return false;
7637
} else {
7738
$("#stationcloseddialogue").hide();
78-
}
79-
80-
timedifference = response["sent-time"] - response.message["timestamp"]; //timedifference gives you a number in seconds (it's server-server relative so should be acurate) of how upto date the data you're getting is
81-
if ((timedifference/60) > minutesbeforefail) {
82-
//Over 1 hour out of date
83-
$(".datadisplay").hide();
84-
$("#nodata").html('<strong>Error</strong> We have not received data from the Weather Station for ' + Math.round(timedifference/3600) + ' hour' + ((timedifference/3600) != 1 ? 's' : ''));
85-
$("#nodata").fadeIn();
86-
} else if ((timedifference/60) > minutesbeforewarn) {
87-
//5 minutes or more (upto 1 hour) out of date
88-
$("#outofdatedata").html('<strong>Warning</strong> Data is ' + Math.round(timedifference/60) + ' minute' + ((timedifference/60) != 1 ? 's' : '') + ' out of date');
89-
$("#outofdatedata").fadeIn();
90-
$(".datadisplay").show();
91-
} else {
92-
$("#outofdatedata").fadeOut();
93-
$(".datadisplay").show();
94-
}
95-
9639

97-
gauges["winddirectiongauge"].value = response.message['windDirection'];
98-
gauges["windgauge"].value = response.message['windSpeedMPH'];
99-
gauges["windaveragegauge"].value = response.message['windSpeed10MinAverageMPH'];
100-
gauges["windgustgauge"].value = response.message['windSpeed10MinGustMPH'];
101-
gauges["tempgauge"].value = response.message['temperatureC'];
102-
gauges["humiditygauge"].value = response.message['humidity'];
40+
timedifference = response["sent-time"] - response.message["timestamp"]; //timedifference gives you a number in seconds (it's server-server relative so should be acurate) of how upto date the data you're getting is
41+
if ((timedifference/60) > minutesbeforefail) {
42+
//Over 1 hour out of date
43+
$(".datadisplay").hide();
44+
$("#nodata").html('<strong>Error</strong> We have not received data from the Weather Station for ' + Math.round(timedifference/3600) + ' hour' + ((timedifference/3600) != 1 ? 's' : ''));
45+
$("#nodata").fadeIn();
46+
} else if ((timedifference/60) > minutesbeforewarn) {
47+
//5 minutes or more (upto 1 hour) out of date
48+
$("#outofdatedata").html('<strong>Warning</strong> Data is ' + Math.round(timedifference/60) + ' minute' + ((timedifference/60) != 1 ? 's' : '') + ' out of date');
49+
$("#outofdatedata").fadeIn();
50+
$(".datadisplay").show();
51+
} else {
52+
$("#outofdatedata").fadeOut();
53+
$(".datadisplay").show();
54+
}
55+
displayData(response.message);
56+
loadingdialog.modal('hide');
10357

104-
//Update page HTML as required
105-
$("#lastupdate").html("Last updated " + response.message["niceFormatTime"] + ' <i id="updatestatus" class="fa fa-refresh fa-fw"></i>');
106-
$("#compassimage").attr("src", "assets/img/compass/" + (Math.round(response.message["windDirection"] / 10) * 10) + ".png");
107-
$(window).trigger('resize'); //To refresh the display handling
108-
$("#loading").hide();
109-
loadingdialog.modal('hide');
110-
//Remove no-internet modal if it's there
111-
if (nointernetdialogshown) {
112-
nointernetdialog.modal('hide');
58+
//How to handle new live Readings from this starting point onwards
59+
channel.bind('PSCWeatherDataLiveNEWReading', function(data) {
60+
$("#outofdatedata").hide();
61+
$("#nodata").hide();
62+
displayData(data.message.reading);
63+
$(".datadisplay").show();
64+
});
11365
}
11466
}
11567

116-
}, error: function (jqXHR, exception) {
117-
//If can't connect to internet/server show a modal (unless it's already showing)
118-
if (nointernetdialogshown == false) {
119-
nointernetdialog = bootbox.dialog({
120-
message: '<p class="text-center">Error - could not download data updates - please check your internet connection or try again later<br/><br/><i>If this error persists please contact James Bithell using the details at <a href="https://www.jbithell.com" target="_blank">https://www.jbithell.com</a></i><br/><br/></p>',
121-
closeButton: false
122-
});
123-
nointernetdialogshown = true;
124-
}
12568

69+
}, error: function (jqXHR, exception) {
70+
//If can't connect to internet/server show a modal explaining that
71+
nointernetdialog = bootbox.dialog({
72+
message: '<p class="text-center">Error - could not download data updates - please check your internet connection or try again later<br/><br/><i>If this error persists please contact James Bithell using the details at <a href="https://www.jbithell.com" target="_blank">https://www.jbithell.com</a></i><br/><br/></p>',
73+
closeButton: false
74+
});
12675
},
12776
cache: false
12877
});
12978
}
13079

131-
//Loading box
80+
// On boot functions
13281
$( document ).ready(function() {
13382
loadingdialog = bootbox.dialog({
13483
size: "small",
13584
message: '<p class="text-center"><i class="fa fa-spinner fa-5x fa-pulse"></i></p>',
13685
closeButton: false,
13786
});
138-
sizeCharts();
13987
drawCharts(function () {
140-
updatedata();
141-
setInterval(function () {
142-
updatedata();
143-
}, 1000*pollforupdatesseconds);
88+
pullServerData(); //When the charts have been drawn, pull the latest data available from server
14489
});
145-
});
146-
$( window ).resize(function() {
147-
sizeCharts();
14890
});

assets/pusher.min.js

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

index.html

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
<meta name="theme-color" content="#ffffff">
1919

2020
<script src="assets/jquery.min.js" onload="window.$ = window.jQuery;"></script>
21-
<link; rel="stylesheet"; href="assets/bootstrap.min.css"/>
22-
<script; type="text/javascript"; src="assets/bootstrap.min.js"></script>
21+
<link rel="stylesheet" href="assets/bootstrap.min.css" />
22+
<script type="text/javascript" src="assets/bootstrap.min.js"></script>
2323
<!--Bootbox-->
2424
<script src="assets/bootbox.min.js"></script>
2525
<!-- Custom Fonts -->
@@ -31,6 +31,9 @@
3131
<!--Pace JS-->
3232
<link rel="stylesheet" href="assets/pace-theme-minimal.css" />
3333
<script data-pace-options='{ "ajax": true }' src='assets/pace.min.js'></script>
34+
<!--Pusher-->
35+
<script src="assets/pusher.min.js"></script>
36+
3437
<style>
3538
/* This stuff isn't in the stylesheet as there were issues with relative paths */
3639
body {
@@ -41,6 +44,8 @@
4144
background-position: center bottom;
4245
}
4346
</style>
47+
<script src="assets/config.js"></script>
48+
<script src="assets/functions.js"></script>
4449
<script src="assets/main.js"></script>
4550
</head>
4651
<body>
@@ -241,7 +246,7 @@ <h2>Porthmadog Sailing Club Weather Station</h2>
241246
<div class="alert alert-warning" style="display: none;" id="stationcloseddialogue"><h1>Weather Station Closed</h1><p class="text-center" id="stationclosedmessage"></p></div>
242247
<div class="alert alert-warning" style="display: none;" id="outofdatedata"><strong>Warning!</strong> Data below is out of date!</div>
243248
<div class="col-lg-12 datadisplay" style="text-align: right;">
244-
<div id="lastupdate" style="font-style: italic;"><i class="fa fa-refresh fa-spin fa-fw"></i></div>
249+
<div id="lastupdateDiv" style="font-style: italic;"><span id="lastupdate"></span><span id="connectionstatus"></span></div>
245250
</div>
246251
<div class="col-lg-12" style="text-align: center; margin-top: 20px;">
247252
<a href="https://port-tides.com" target="_blank" class="btn btn-default"><i class="fa fa-moon-o"></i> Tide Times</a>

0 commit comments

Comments
 (0)