Skip to content

Commit 8a202e1

Browse files
committed
add in tailwind and alpine.js
1 parent 927e4c7 commit 8a202e1

File tree

8 files changed

+2588
-0
lines changed

8 files changed

+2588
-0
lines changed

.DS_Store

6 KB
Binary file not shown.

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2+
tailwindcss

dashboard.html

Lines changed: 317 additions & 0 deletions
Large diffs are not rendered by default.

dashboard.js

Lines changed: 362 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,362 @@
1+
"use strict";
2+
3+
let loc = {
4+
hostname: "www.bannister.id.au",
5+
port:443,
6+
useSSL:true
7+
};
8+
9+
// location options https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/getCurrentPosition
10+
const locationOptions = {
11+
enableHighAccuracy: true,
12+
maximumAge: 10000, // milliseconds
13+
timeout: 700 // milliseconds
14+
};
15+
16+
var zoomLevel = 17;
17+
18+
var mqtt_client, map, breadCrumbLine, locationCircle, locationChart, temperatureChart;
19+
20+
var mqtt_message_count = 0;
21+
22+
23+
let statusText = document.getElementById("status");
24+
let locationText = document.getElementById("location")
25+
26+
let npositions = 0;
27+
28+
29+
function dashboard_init() {
30+
31+
mqtt_init();
32+
map_init();
33+
34+
temp_chart_init();
35+
location_chart_init();
36+
37+
38+
}
39+
40+
41+
42+
function mqtt_init() {
43+
// Create a client instance
44+
mqtt_client = new Paho.MQTT.Client(loc.hostname, Number(loc.port), "clientId");
45+
46+
// set callback handlers
47+
mqtt_client.onConnectionLost = onConnectionLost;
48+
mqtt_client.onMessageArrived = onMessageArrived;
49+
}
50+
51+
52+
53+
function setStatus(msg) {
54+
// statusText.textContent = msg;
55+
console.log("Status changed:", msg);
56+
}
57+
58+
59+
function mqtt_login() {
60+
let username = document.getElementById("username").value;
61+
let password = document.getElementById("password").value;
62+
// For more options, see here: https://www.eclipse.org/paho/files/jsdoc/Paho.MQTT.Client.html
63+
let options = {
64+
timeout:3,
65+
userName:username,
66+
password:password,
67+
onSuccess:onConnect,
68+
onFailure:onConnectionLost,
69+
useSSL:loc.useSSL,
70+
//reconnect:true
71+
}
72+
73+
// setStatus("Connecting...");
74+
$('#debug_logs').append("MQTT Client connecting...");
75+
mqtt_client.connect(options);
76+
return false
77+
78+
}
79+
80+
// called when the mqtt_client connects
81+
function onConnect() {
82+
// Once a connection has been made, make a subscription and send a message.
83+
console.log("onConnect");
84+
mqtt_client.subscribe("ekayak");
85+
// let message = new Paho.MQTT.Message("Hello");
86+
// message.destinationName = "World";
87+
// mqtt_client.send(message);
88+
// setStatus("Connected");
89+
$('#debug_logs').append("MQTT Client Connected!");
90+
$('#login_icon').removeClass('text-red-500');
91+
$('#login_icon').addClass('text-green-500');
92+
}
93+
94+
// called when the mqtt_client loses its connection
95+
function onConnectionLost(responseObject) {
96+
// setStatus(`Connection lost: ${responseObject.errorMessage}`);
97+
if (responseObject.errorCode !== 0) {
98+
console.log("onConnectionLost:"+responseObject.errorMessage);
99+
}
100+
$('#debug_logs').append("onConnectionLost:"+responseObject.errorMessage);
101+
$('#login_icon').removeClass('text-green-500');
102+
$('#login_icon').addClass('text-red-500');
103+
}
104+
105+
106+
107+
function onMessageArrived(message) {
108+
console.log("onMessageArrived:",message.payloadString);
109+
console.log(message)
110+
console.log("Destionation", message.destinationName);
111+
console.log("QoS", message.qos);
112+
console.log("retained", message.retained);
113+
console.log("Duplicate", message.duplicate);
114+
115+
// let out = document.getElementById("lastmessage");
116+
// out.textContent = message.payloadString;
117+
$('#debug_logs').append(message.payloadString);
118+
119+
let data = JSON.parse(message.payloadString);
120+
121+
addData(temperatureChart, mqtt_message_count, [data.internal_temp, data.external_temp, data.relative_humidity])
122+
123+
$('#battery_voltage').html("- V");
124+
$('#controller_temp').html(`${data.external_temp} Deg.`);
125+
126+
mqtt_message_count += 1;
127+
128+
}
129+
130+
131+
132+
133+
function map_init() {
134+
map = L.map('map').fitWorld();
135+
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
136+
maxZoom: 21,
137+
attribution: '© OpenStreetMap'
138+
}).addTo(map);
139+
breadCrumbLine = L.polyline([]).addTo(map);
140+
locationCircle = L.circle([0,0]).addTo(map);
141+
}
142+
143+
144+
function temp_chart_init() {
145+
const temperatureData = {
146+
labels: [],
147+
datasets: [
148+
{
149+
label: 'Internal Temp',
150+
data: [],
151+
borderColor: 'rgba(54, 162, 235, 1)',
152+
backgroundColor: 'rgba(54, 162, 235, 0.2)',
153+
yAxisID: 'y',
154+
},
155+
{
156+
label: 'External Temp',
157+
data: [],
158+
borderColor: 'rgba(0, 99, 182, 1)',
159+
backgroundColor: 'rgba(0, 99, 182, 0.2)',
160+
yAxisID: 'y',
161+
},
162+
{
163+
label: 'Humidity',
164+
data: [],
165+
borderColor: 'rgba(255, 99, 132, 1)',
166+
backgroundColor: 'rgba(255, 99, 132, 0.2)',
167+
yAxisID: 'y1',
168+
}
169+
]
170+
};
171+
172+
173+
const temperatureConfig = {
174+
type: 'line',
175+
data: temperatureData,
176+
options: {
177+
responsive: true,
178+
interaction: {
179+
mode: 'index',
180+
intersect: false,
181+
},
182+
stacked: false,
183+
plugins: {
184+
title: {
185+
display: true,
186+
text: 'Temperature & humidity'
187+
}
188+
},
189+
scales: {
190+
y: {
191+
type: 'linear',
192+
display: true,
193+
position: 'left',
194+
title: {
195+
display:true,
196+
text: 'Temperature (deg)'
197+
}
198+
},
199+
y1: {
200+
type: 'linear',
201+
display: true,
202+
position: 'right',
203+
title: {
204+
display:true,
205+
text: 'Relative humidity (%)'
206+
},
207+
208+
// grid line settings
209+
grid: {
210+
drawOnChartArea: false, // only want the grid lines for one axis to show up
211+
},
212+
},
213+
}
214+
},
215+
};
216+
217+
temperatureChart = new Chart('temperatureChart', temperatureConfig);
218+
219+
}
220+
221+
222+
223+
224+
function location_chart_init() {
225+
const locationData = {
226+
labels: [],
227+
datasets: [
228+
{
229+
label: 'Speed',
230+
data: [],
231+
borderColor: 'rgba(54, 162, 235, 1)',
232+
backgroundColor: 'rgba(54, 162, 235, 0.2)',
233+
yAxisID: 'y',
234+
},
235+
{
236+
label: 'Heading',
237+
data: [],
238+
borderColor: 'rgba(255, 99, 132, 1)',
239+
backgroundColor: 'rgba(255, 99, 132, 0.2)',
240+
yAxisID: 'y1',
241+
}
242+
]
243+
};
244+
245+
246+
const locationConfig = {
247+
type: 'line',
248+
data: locationData,
249+
options: {
250+
responsive: true,
251+
interaction: {
252+
mode: 'index',
253+
intersect: false,
254+
},
255+
stacked: false,
256+
plugins: {
257+
title: {
258+
display: true,
259+
text: 'Location'
260+
}
261+
},
262+
scales: {
263+
y: {
264+
type: 'linear',
265+
display: true,
266+
position: 'left',
267+
title: {
268+
display:true,
269+
text: 'Speed (m/s)'
270+
}
271+
},
272+
y1: {
273+
type: 'linear',
274+
display: true,
275+
position: 'right',
276+
title: {
277+
display:true,
278+
text: 'Heading (deg)'
279+
},
280+
281+
// grid line settings
282+
grid: {
283+
drawOnChartArea: false, // only want the grid lines for one axis to show up
284+
},
285+
},
286+
}
287+
},
288+
};
289+
290+
locationChart = new Chart('locationChart', locationConfig);
291+
292+
}
293+
294+
295+
296+
297+
function locationSuccess(position) {
298+
const c = position.coords;
299+
// locationText.textContent = `lat/long:${c.latitude}/${c.longitude} speed:${c.speed} heading:${c.heading} altitude:${c.altitude} accuracy:${c.accuracy} altaccuracy:${c.altitudeAccuracy} timestamp:${position.timestamp}`;
300+
const latlng = [c.latitude, c.longitude];
301+
if (npositions == 0) {
302+
//map.flyTo(latlng, Number(zoomLevel), {animate:true}); // Flying takes too long and stops when the next location comes in
303+
map.setView(latlng, zoomLevel);
304+
} else {
305+
map.panTo(latlng);
306+
}
307+
breadCrumbLine.addLatLng(latlng);
308+
locationCircle.setLatLng(latlng);
309+
locationCircle.setRadius(c.accuracy);
310+
311+
npositions = npositions + 1;
312+
313+
$('#gps_speed').html(c.speed);
314+
$('#current_trip').html('0 km');
315+
316+
addData(locationChart, npositions, [c.speed, c.heading])
317+
318+
}
319+
320+
function locationError(error) {
321+
// locationText.textContent = `GEOLOCATION ERROR(${error.code}): ${error.message}`;
322+
console.log(`GEOLOCATION ERROR(${error.code}): ${error.message}`)
323+
}
324+
325+
// setup geolocation
326+
if ('geolocation' in navigator) {
327+
const watchID = navigator.geolocation.watchPosition(locationSuccess, locationError, locationOptions);
328+
} else {
329+
// locationText.textContent = "Geolocation not supported in this browser";
330+
}
331+
332+
333+
334+
335+
// Chart update functions: https://www.chartjs.org/docs/latest/developers/updates.html
336+
function addData(chart, label, data) {
337+
chart.data.labels.push(label);
338+
chart.data.datasets.forEach((dataset, i) => {
339+
dataset.data.push(data[i]);
340+
});
341+
chart.update();
342+
}
343+
344+
function removeData(chart) {
345+
chart.data.labels.pop();
346+
chart.data.datasets.forEach((dataset) => {
347+
dataset.data.pop();
348+
});
349+
chart.update();
350+
}
351+
352+
353+
354+
355+
// On Apline ready
356+
document.addEventListener('alpine:init', () => {
357+
dashboard_init();
358+
359+
});
360+
361+
362+

favicon.svg

Lines changed: 1 addition & 0 deletions
Loading

0 commit comments

Comments
 (0)