TKK_E32211801/ds/public/index.js

555 lines
13 KiB
JavaScript

// Import MQTT service
import { MQTTService } from "./mqttService.js";
// Target specific HTML items
const sideMenu = document.querySelector("aside");
const menuBtn = document.querySelector("#menu-btn");
const closeBtn = document.querySelector("#close-btn");
const themeToggler = document.querySelector(".theme-toggler");
// Holds the background color of all chart
var chartBGColor = getComputedStyle(document.body).getPropertyValue(
"--chart-background"
);
var chartFontColor = getComputedStyle(document.body).getPropertyValue(
"--chart-font-color"
);
var chartAxisColor = getComputedStyle(document.body).getPropertyValue(
"--chart-axis-color"
);
/*
Event listeners for any HTML click
*/
menuBtn.addEventListener("click", () => {
sideMenu.style.display = "block";
});
closeBtn.addEventListener("click", () => {
sideMenu.style.display = "none";
});
themeToggler.addEventListener("click", () => {
document.body.classList.toggle("dark-theme-variables");
themeToggler.querySelector("span:nth-child(1)").classList.toggle("active");
themeToggler.querySelector("span:nth-child(2)").classList.toggle("active");
// Update Chart background
chartBGColor = getComputedStyle(document.body).getPropertyValue(
"--chart-background"
);
chartFontColor = getComputedStyle(document.body).getPropertyValue(
"--chart-font-color"
);
chartAxisColor = getComputedStyle(document.body).getPropertyValue(
"--chart-axis-color"
);
updateChartsBackground();
});
/*
Plotly.js graph and chart setup code
*/
var temperatureHistoryDiv = document.getElementById("temperature-history");
var humidityHistoryDiv = document.getElementById("humidity-history");
var pressureHistoryDiv = document.getElementById("pressure-history");
var altitudeHistoryDiv = document.getElementById("altitude-history");
var temperatureGaugeDiv = document.getElementById("temperature-gauge");
var humidityGaugeDiv = document.getElementById("humidity-gauge");
var pressureGaugeDiv = document.getElementById("pressure-gauge");
var altitudeGaugeDiv = document.getElementById("altitude-gauge");
const historyCharts = [
temperatureHistoryDiv,
humidityHistoryDiv,
pressureHistoryDiv,
altitudeHistoryDiv,
];
const gaugeCharts = [
temperatureGaugeDiv,
humidityGaugeDiv,
pressureGaugeDiv,
altitudeGaugeDiv,
];
// History Data
var temperatureTrace = {
x: [],
y: [],
name: "Temperature",
mode: "lines+markers",
type: "line",
};
var humidityTrace = {
x: [],
y: [],
name: "Humidity",
mode: "lines+markers",
type: "line",
};
var pressureTrace = {
x: [],
y: [],
name: "Pressure",
mode: "lines+markers",
type: "line",
};
var altitudeTrace = {
x: [],
y: [],
name: "Altitude",
mode: "lines+markers",
type: "line",
};
var temperatureLayout = {
autosize: true,
title: {
text: "Temperature",
},
font: {
size: 12,
color: chartFontColor,
family: "poppins, san-serif",
},
colorway: ["#05AD86"],
margin: { t: 40, b: 40, l: 30, r: 30, pad: 10 },
plot_bgcolor: chartBGColor,
paper_bgcolor: chartBGColor,
xaxis: {
color: chartAxisColor,
linecolor: chartAxisColor,
gridwidth: "2",
autorange: true,
},
yaxis: {
color: chartAxisColor,
linecolor: chartAxisColor,
gridwidth: "2",
autorange: true,
},
};
var humidityLayout = {
autosize: true,
title: {
text: "Humidity",
},
font: {
size: 12,
color: chartFontColor,
family: "poppins, san-serif",
},
colorway: ["#05AD86"],
margin: { t: 40, b: 40, l: 30, r: 30, pad: 0 },
plot_bgcolor: chartBGColor,
paper_bgcolor: chartBGColor,
xaxis: {
color: chartAxisColor,
linecolor: chartAxisColor,
gridwidth: "2",
},
yaxis: {
color: chartAxisColor,
linecolor: chartAxisColor,
},
};
var pressureLayout = {
autosize: true,
title: {
text: "Pressure",
},
font: {
size: 12,
color: chartFontColor,
family: "poppins, san-serif",
},
colorway: ["#05AD86"],
margin: { t: 40, b: 40, l: 30, r: 30, pad: 0 },
plot_bgcolor: chartBGColor,
paper_bgcolor: chartBGColor,
xaxis: {
color: chartAxisColor,
linecolor: chartAxisColor,
gridwidth: "2",
},
yaxis: {
color: chartAxisColor,
linecolor: chartAxisColor,
},
};
var altitudeLayout = {
autosize: true,
title: {
text: "Altitude",
},
font: {
size: 12,
color: chartFontColor,
family: "poppins, san-serif",
},
colorway: ["#05AD86"],
margin: { t: 40, b: 40, l: 30, r: 30, pad: 0 },
plot_bgcolor: chartBGColor,
paper_bgcolor: chartBGColor,
xaxis: {
color: chartAxisColor,
linecolor: chartAxisColor,
gridwidth: "2",
},
yaxis: {
color: chartAxisColor,
linecolor: chartAxisColor,
},
};
var config = { responsive: true, displayModeBar: false };
// Event listener when page is loaded
window.addEventListener("load", (event) => {
Plotly.newPlot(
temperatureHistoryDiv,
[temperatureTrace],
temperatureLayout,
config
);
Plotly.newPlot(humidityHistoryDiv, [humidityTrace], humidityLayout, config);
Plotly.newPlot(pressureHistoryDiv, [pressureTrace], pressureLayout, config);
Plotly.newPlot(altitudeHistoryDiv, [altitudeTrace], altitudeLayout, config);
// Get MQTT Connection
fetchMQTTConnection();
// Run it initially
handleDeviceChange(mediaQuery);
});
// Gauge Data
var temperatureData = [
{
domain: { x: [0, 1], y: [0, 1] },
value: 0,
title: { text: "Temperature" },
type: "indicator",
mode: "gauge+number+delta",
delta: { reference: 30 },
gauge: {
axis: { range: [null, 50] },
steps: [
{ range: [0, 20], color: "lightgray" },
{ range: [20, 30], color: "gray" },
],
threshold: {
line: { color: "red", width: 4 },
thickness: 0.75,
value: 30,
},
},
},
];
var humidityData = [
{
domain: { x: [0, 1], y: [0, 1] },
value: 0,
title: { text: "Humidity" },
type: "indicator",
mode: "gauge+number+delta",
delta: { reference: 50 },
gauge: {
axis: { range: [null, 100] },
steps: [
{ range: [0, 20], color: "lightgray" },
{ range: [20, 30], color: "gray" },
],
threshold: {
line: { color: "red", width: 4 },
thickness: 0.75,
value: 30,
},
},
},
];
var pressureData = [
{
domain: { x: [0, 1], y: [0, 1] },
value: 0,
title: { text: "Pressure" },
type: "indicator",
mode: "gauge+number+delta",
delta: { reference: 750 },
gauge: {
axis: { range: [null, 1100] },
steps: [
{ range: [0, 300], color: "lightgray" },
{ range: [300, 700], color: "gray" },
],
threshold: {
line: { color: "red", width: 4 },
thickness: 0.75,
value: 30,
},
},
},
];
var altitudeData = [
{
domain: { x: [0, 1], y: [0, 1] },
value: 0,
title: { text: "Altitude" },
type: "indicator",
mode: "gauge+number+delta",
delta: { reference: 60 },
gauge: {
axis: { range: [null, 150] },
steps: [
{ range: [0, 50], color: "lightgray" },
{ range: [50, 100], color: "gray" },
],
threshold: {
line: { color: "red", width: 4 },
thickness: 0.75,
value: 30,
},
},
},
];
var layout = { width: 300, height: 250, margin: { t: 0, b: 0, l: 0, r: 0 } };
Plotly.newPlot(temperatureGaugeDiv, temperatureData, layout);
Plotly.newPlot(humidityGaugeDiv, humidityData, layout);
Plotly.newPlot(pressureGaugeDiv, pressureData, layout);
Plotly.newPlot(altitudeGaugeDiv, altitudeData, layout);
// Will hold the arrays we receive from our BME280 sensor
// Temperature
let newTempXArray = [];
let newTempYArray = [];
// Humidity
let newHumidityXArray = [];
let newHumidityYArray = [];
// Pressure
let newPressureXArray = [];
let newPressureYArray = [];
// Altitude
let newAltitudeXArray = [];
let newAltitudeYArray = [];
// The maximum number of data points displayed on our scatter/line graph
let MAX_GRAPH_POINTS = 12;
let ctr = 0;
// Callback function that will retrieve our latest sensor readings and redraw our Gauge with the latest readings
function updateSensorReadings(jsonResponse) {
console.log(typeof jsonResponse);
console.log(jsonResponse);
let temperature = Number(jsonResponse.temperature).toFixed(2);
let humidity = Number(jsonResponse.humidity).toFixed(2);
let pressure = Number(jsonResponse.pressure).toFixed(2);
let altitude = Number(jsonResponse.altitude).toFixed(2);
updateBoxes(temperature, humidity, pressure, altitude);
updateGauge(temperature, humidity, pressure, altitude);
// Update Temperature Line Chart
updateCharts(
temperatureHistoryDiv,
newTempXArray,
newTempYArray,
temperature
);
// Update Humidity Line Chart
updateCharts(
humidityHistoryDiv,
newHumidityXArray,
newHumidityYArray,
humidity
);
// Update Pressure Line Chart
updateCharts(
pressureHistoryDiv,
newPressureXArray,
newPressureYArray,
pressure
);
// Update Altitude Line Chart
updateCharts(
altitudeHistoryDiv,
newAltitudeXArray,
newAltitudeYArray,
altitude
);
}
function updateBoxes(temperature, humidity, pressure, altitude) {
let temperatureDiv = document.getElementById("temperature");
let humidityDiv = document.getElementById("humidity");
let pressureDiv = document.getElementById("pressure");
let altitudeDiv = document.getElementById("altitude");
temperatureDiv.innerHTML = temperature + " C";
humidityDiv.innerHTML = humidity + " %";
pressureDiv.innerHTML = pressure + " hPa";
altitudeDiv.innerHTML = altitude + " m";
}
function updateGauge(temperature, humidity, pressure, altitude) {
var temperature_update = {
value: temperature,
};
var humidity_update = {
value: humidity,
};
var pressure_update = {
value: pressure,
};
var altitude_update = {
value: altitude,
};
Plotly.update(temperatureGaugeDiv, temperature_update);
Plotly.update(humidityGaugeDiv, humidity_update);
Plotly.update(pressureGaugeDiv, pressure_update);
Plotly.update(altitudeGaugeDiv, altitude_update);
}
function updateCharts(lineChartDiv, xArray, yArray, sensorRead) {
if (xArray.length >= MAX_GRAPH_POINTS) {
xArray.shift();
}
if (yArray.length >= MAX_GRAPH_POINTS) {
yArray.shift();
}
xArray.push(ctr++);
yArray.push(sensorRead);
var data_update = {
x: [xArray],
y: [yArray],
};
Plotly.update(lineChartDiv, data_update);
}
function updateChartsBackground() {
// updates the background color of historical charts
var updateHistory = {
plot_bgcolor: chartBGColor,
paper_bgcolor: chartBGColor,
font: {
color: chartFontColor,
},
xaxis: {
color: chartAxisColor,
linecolor: chartAxisColor,
},
yaxis: {
color: chartAxisColor,
linecolor: chartAxisColor,
},
};
historyCharts.forEach((chart) => Plotly.relayout(chart, updateHistory));
// updates the background color of gauge charts
var gaugeHistory = {
plot_bgcolor: chartBGColor,
paper_bgcolor: chartBGColor,
font: {
color: chartFontColor,
},
xaxis: {
color: chartAxisColor,
linecolor: chartAxisColor,
},
yaxis: {
color: chartAxisColor,
linecolor: chartAxisColor,
},
};
gaugeCharts.forEach((chart) => Plotly.relayout(chart, gaugeHistory));
}
const mediaQuery = window.matchMedia("(max-width: 600px)");
mediaQuery.addEventListener("change", function (e) {
handleDeviceChange(e);
});
function handleDeviceChange(e) {
if (e.matches) {
console.log("Inside Mobile");
var updateHistory = {
width: 323,
height: 250,
"xaxis.autorange": true,
"yaxis.autorange": true,
};
historyCharts.forEach((chart) => Plotly.relayout(chart, updateHistory));
} else {
var updateHistory = {
width: 550,
height: 260,
"xaxis.autorange": true,
"yaxis.autorange": true,
};
historyCharts.forEach((chart) => Plotly.relayout(chart, updateHistory));
}
}
/*
MQTT Message Handling Code
*/
const mqttStatus = document.querySelector(".status");
function onConnect(message) {
mqttStatus.textContent = "Connected";
}
function onMessage(topic, message) {
var stringResponse = message.toString();
var messageResponse = JSON.parse(stringResponse);
updateSensorReadings(messageResponse);
}
function onError(error) {
console.log(`Error encountered :: ${error}`);
mqttStatus.textContent = "Error";
}
function onClose() {
console.log(`MQTT connection closed!`);
mqttStatus.textContent = "Closed";
}
function fetchMQTTConnection() {
fetch("/mqttConnDetails", {
method: "GET",
headers: {
"Content-type": "application/json; charset=UTF-8",
},
})
.then(function (response) {
return response.json();
})
.then(function (data) {
initializeMQTTConnection(data.mqttServer, data.mqttTopic);
})
.catch((error) => console.error("Error getting MQTT Connection :", error));
}
function initializeMQTTConnection(mqttServer, mqttTopic) {
console.log(
`Initializing connection to :: ${mqttServer}, topic :: ${mqttTopic}`
);
var fnCallbacks = { onConnect, onMessage, onError, onClose };
var mqttService = new MQTTService(mqttServer, fnCallbacks);
mqttService.connect();
mqttService.subscribe(mqttTopic);
}