This gist contains the frontend code described in the article Monitor Raspberry Pi® Temp from a Phone on your LAN.
Created
April 2, 2021 21:59
-
-
Save jmp-12/16901d1d221ca3f48f913c32fb5be5e2 to your computer and use it in GitHub Desktop.
Monitor Raspberry Pi® Temp from a Phone on your LAN
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (c) 2020 - 2021 Persanix LLC. All rights reserved. | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
/* Some browsers add margin to the body element, remove it */ | |
body { | |
margin: 0; | |
} | |
.main { | |
min-height: 100vh; | |
padding: 5vh 5vw; | |
box-sizing: border-box; | |
display: flex; | |
flex-direction: column; | |
justify-content: center; | |
align-items: center; | |
} | |
.text-heading { | |
font-family: sans-serif; | |
font-weight: 300; | |
color: #575757; | |
font-size: 3.5rem; | |
} | |
.text-subheading { | |
font-family: sans-serif; | |
font-weight: 300; | |
color: #575757; | |
font-size: 2.2rem; | |
} | |
.text-body-1 { | |
font-family: sans-serif; | |
font-weight: 300; | |
color: #5c5c5c; | |
font-size: 1.2rem; | |
} | |
.text-caption { | |
font-family: sans-serif; | |
font-weight: 600; | |
color: #888888; | |
font-size: 0.8rem; | |
} | |
.font-bold { | |
font-weight: 600; | |
} | |
.font-red { | |
color: #ef5350; | |
} | |
.font-green { | |
color: #66bb6a; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (c) 2020 - 2021 Persanix LLC. All rights reserved. | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
const POLL_INTERVAL_MILLISECONDS = 500; | |
// Updates the status element to either 'online' or 'offline' depending on websocket status | |
function updateStatusElement({ isOnline }) { | |
const statusElement = document.getElementById("status"); | |
if (statusElement) { | |
if (isOnline) { | |
statusElement.innerText = "Online"; | |
statusElement.classList.remove("font-red"); | |
statusElement.classList.add("font-green"); | |
} else { | |
statusElement.innerText = "Offline"; | |
statusElement.classList.remove("font-green"); | |
statusElement.classList.add("font-red"); | |
} | |
} | |
} | |
// Updates the text of the temperature element when the client receives a new websocket message | |
function updateTemperatureElement({ temperature }) { | |
const temperatureElement = document.getElementById("temperature"); | |
if (temperatureElement) { | |
temperatureElement.innerText = `${ temperature }°C`; | |
} | |
} | |
// Wait for the webpage to load before connecting to the websocket | |
window.addEventListener("DOMContentLoaded", _ => { | |
const updateFrequencyElement = document.getElementById("updateFrequency"); | |
if (updateFrequencyElement) { | |
updateFrequencyElement.innerText = `${ POLL_INTERVAL_MILLISECONDS }ms`; | |
} | |
// Open a new WebSocket connection | |
const webSocket = new WebSocket(`ws://${ location.host }`); | |
// Create a new message to send to the WebSocket | |
const data = { "action": "READ_TEMPERATURE" }; | |
const message = JSON.stringify(data); | |
let intervalId = null; | |
// Start sending messages as soon as the websocket opens | |
webSocket.onopen = () => { | |
console.log("Websocket is open"); | |
updateStatusElement({ isOnline: true }); | |
// Keep track of the interval id so that we can cancel the interval on error events | |
intervalId = setInterval(() => { | |
// Ensure the websocket is still in the open state before sending a message | |
if (webSocket.readyState === WebSocket.OPEN) { | |
console.log("Polling for temperature"); | |
webSocket.send(message); | |
} | |
}, POLL_INTERVAL_MILLISECONDS); | |
}; | |
// Clear the interval and set status to 'offline' if the websocket is closed (i.e. endrpi server terminated) | |
webSocket.onclose = () => { | |
console.log("Websocket has been closed"); | |
clearInterval(intervalId); | |
updateStatusElement({ isOnline: false }); | |
}; | |
// Clear the interval and set status to 'offline' if something goes wrong with the websocket | |
webSocket.onerror = (event) => { | |
console.error("WebSocket error: ", event); | |
clearInterval(intervalId); | |
updateStatusElement({ isOnline: false }); | |
}; | |
// Update the temperature text when a message from the server is received | |
webSocket.onmessage = (response) => { | |
// Convert json into an object | |
const endrpiResponse = JSON.parse(response.data); | |
console.log("Websocket received response: ", endrpiResponse); | |
// If the response is successful and matches the action we requested, update the temperature text | |
if (endrpiResponse.success && endrpiResponse.action === "READ_TEMPERATURE") { | |
const { data: temperatureData } = endrpiResponse; | |
const { systemOnChip: { quantity: temperature } } = temperatureData; | |
updateTemperatureElement({ temperature }); | |
} | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- | |
~ Copyright (c) 2020 - 2021 Persanix LLC. All rights reserved. | |
~ | |
~ Licensed under the Apache License, Version 2.0 (the "License"); | |
~ you may not use this file except in compliance with the License. | |
~ You may obtain a copy of the License at | |
~ | |
~ http://www.apache.org/licenses/LICENSE-2.0 | |
~ | |
~ Unless required by applicable law or agreed to in writing, software | |
~ distributed under the License is distributed on an "AS IS" BASIS, | |
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
~ See the License for the specific language governing permissions and | |
~ limitations under the License. | |
--> | |
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>Raspberry Pi Temperature Monitor</title> | |
<link rel="stylesheet" href="public/app.css"> | |
</head> | |
<body> | |
<div class="main"> | |
<div class="prose"> | |
<h1 class="text-heading"> | |
Raspberry Pi Temperature | |
</h1> | |
<p class="text-body-1"> | |
Status: <span id="status" class="font-bold font-red">Offline</span> | |
</p> | |
<p id="temperature" class="text-subheading"></p> | |
<p class="text-caption"> | |
UPDATE FREQUENCY: <span id="updateFrequency">N/A</span> | |
</p> | |
</div> | |
</div> | |
</body> | |
<script src="/public/app.js"></script> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment