Hello, although I have been coding for many years starting with basica, then quick basic, turbo pascal, turbo C etc. etc., I am new at this whole JavaScript thing and I obviously dont have something quite right and need some expert guidance.
I am making a controller for my hot tub using an ESP32, some solid state relays, a DS18B20 and a BME280. I want a webserver to display the water temperature from the DS18B20 and the ambient temperature, humidity and air pressure from the BME280 and also have two buttons to turn on and off two of the solid state relays. So, I found tutorials on the internet for displaying sensor readings and also controlling GPIO pins. Simple, all I need do is put the two together. My HTML, CSS and JavaScript code is shown below. The handleWebSocketMessage function for the ESP32 prints the incoming websocket message to the serial port and so I can see that it receives a getReadings message when I open or refresh the web page on any device on my WiFi network buit when I click either of the two buttons, it does not print anything and so I can assume that the websocket message related to these buttons is not being sent. I have not included the arduino (ESP32) code as it is working correctly.
Where am I going wrong?
Thanks, Steve
index.html;
script.js;
style.css;
I am making a controller for my hot tub using an ESP32, some solid state relays, a DS18B20 and a BME280. I want a webserver to display the water temperature from the DS18B20 and the ambient temperature, humidity and air pressure from the BME280 and also have two buttons to turn on and off two of the solid state relays. So, I found tutorials on the internet for displaying sensor readings and also controlling GPIO pins. Simple, all I need do is put the two together. My HTML, CSS and JavaScript code is shown below. The handleWebSocketMessage function for the ESP32 prints the incoming websocket message to the serial port and so I can see that it receives a getReadings message when I open or refresh the web page on any device on my WiFi network buit when I click either of the two buttons, it does not print anything and so I can assume that the websocket message related to these buttons is not being sent. I have not included the arduino (ESP32) code as it is working correctly.
Where am I going wrong?
Thanks, Steve
index.html;
HTML:
<!DOCTYPE html>
<html>
<head>
<title>Hot Tub Control</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/png" href="favicon.png">
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div class="topnav">
<h1>Hot Tub</h1>
</div>
<div class="content">
<div class="card-grid">
<div class="card">
<p class="card-title"> Water Temperature</p>
<p class="reading"><span id="watertemp"></span> °C</p>
</div>
<div class="card">
<p class="card-title"> Air Temperature</p>
<p class="reading"><span id="airtemp"></span> °C</p>
</div>
<div class="card">
<p class="card-title"> Humidity</p>
<p class="reading"><span id="humidity"></span> %rh</p>
</div>
<div class="card">
<p class="card-title"> Air Pressure</p>
<p class="reading"><span id="pressure"></span> hpa</p>
</div>
</div>
</div>
<div class="button-grid">
<div id="pwrled" class="%STATE%"></div>
<div id="lightsled" class="%STATE%"></div>
<button id="power">Power</button>
<button id="lights">Lights</button>
</div>
<script src="script.js"></script>
</body>
</html>
script.js;
JavaScript:
var gateway = `ws://${window.location.hostname}/ws`;
var websocket;
// Init web socket when the page loads
window.addEventListener('load', onload);
function onload(event) {
initWebSocket();
}
function getReadings(){
websocket.send("getReadings");
}
function initWebSocket() {
console.log('Trying to open a WebSocket connection…');
websocket = new WebSocket(gateway);
websocket.onopen = onOpen;
websocket.onclose = onClose;
websocket.onmessage = onMessage;
}
// When websocket is established, call the getReadings() function
function onOpen(event) {
console.log('Connection opened');
getReadings();
}
function onClose(event) {
console.log('Connection closed');
setTimeout(initWebSocket, 2000);
}
// Function that receives the message from the ESP32 with the readings
function onMessage(event) {
console.log(event.data);
var myObj = JSON.parse(event.data);
var keys = Object.keys(myObj);
for (var i = 0; i < keys.length; i++){
var key = keys[i];
document.getElementById(key).innerHTML = myObj[key];
}
}
// ----------------------------------------------------------------------------
// Button handling
// ----------------------------------------------------------------------------
function initButton() {
document.getElementById('power').addEventListener('click', onPower);
document.getElementById('lights').addEventListener('click', onLights);
}
function onPower(event) {
websocket.send("power");
}
function onLights(event) {
websocket.send("lights");
}
style.css;
CSS:
html {
font-family: Arial, Helvetica, sans-serif;
display: inline-block;
text-align: center;
}
h1 {
font-size: 1.8rem;
color: white;
}
.topnav {
overflow: hidden;
background-color: #0A1128;
}
body {
margin: 0;
}
.content {
padding: 50px;
}
.card-grid {
max-width: 500px;
margin: 0 auto;
display: grid;
grid-gap: 2rem;
grid-template-columns: auto auto;
}
.button-grid {
max-width: 500px;
margin: 0 auto;
display: grid;
grid-gap: 2rem;
grid-template-columns: auto auto;
justify-items: center;
}
.card {
background-color: white;
box-shadow: 2px 2px 12px 1px rgba(140,140,140,.5);
}
.card-title {
font-size: 1.0rem;
font-weight: bold;
color: #034078
}
.reading {
font-size: 1.0rem;
color: #1282A2;
}
.panel {
display: grid;
grid-gap: 3em;
justify-items: center;
}
button {
padding: .5em .75em;
font-size: 2rem;
color: #fff;
text-shadow: 0 -1px 1px #000;
border: 1px solid #000;
border-radius: .5em;
background-image: linear-gradient(#2e3538, #73848c);
box-shadow: inset 0 2px 4px rgba(255, 255, 255, 0.5), 0 0.2em 0.4em rgba(0, 0, 0, 0.4);
outline: none;
}
button:active {
transform: translateY(2px);
}
.led-box {
height: 30px;
width: 25%;
margin: 10px 0;
float: left;
}
.led-green {
margin: 0 auto;
width: 24px;
height: 24px;
background-color: #ABFF00;
border-radius: 50%;
box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 7px 1px, inset #304701 0 -1px 9px, #89FF00 0 2px 12px;
}
#pwrled {
position: relative;
width: 5em;
height: 5em;
border: 2px solid #000;
border-radius: 2.5em;
background-image: radial-gradient(farthest-corner at 50% 20%, #b30000 0%, #330000 100%);
box-shadow: 0 0.5em 1em rgba(102, 0, 0, 0.3);
}
#pwrled.on {
background-image: radial-gradient(farthest-corner at 50% 75%, red 0%, #990000 100%);
box-shadow: 0 1em 1.5em rgba(255, 0, 0, 0.5);
}
#pwrled:after {
content: '';
position: absolute;
top: .3em;
left: 1em;
width: 60%;
height: 40%;
border-radius: 60%;
background-image: linear-gradient(rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0.1));
}
#lightsled {
position: relative;
width: 5em;
height: 5em;
border: 2px solid #000;
border-radius: 2.5em;
background-image: radial-gradient(farthest-corner at 50% 20%, #b30000 0%, #330000 100%);
box-shadow: 0 0.5em 1em rgba(102, 0, 0, 0.3);
}
#lightsled.on {
background-image: radial-gradient(farthest-corner at 50% 75%, red 0%, #990000 100%);
box-shadow: 0 1em 1.5em rgba(255, 0, 0, 0.5);
}
#lightsled:after {
content: '';
position: absolute;
top: .3em;
left: 1em;
width: 60%;
height: 40%;
border-radius: 60%;
background-image: linear-gradient(rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0.1));
}