Skip to content

Instantly share code, notes, and snippets.

@djdunc
Last active April 28, 2024 22:27
Show Gist options
  • Save djdunc/cf779ade29c483e0cef412f40b19c8f1 to your computer and use it in GitHub Desktop.
Save djdunc/cf779ade29c483e0cef412f40b19c8f1 to your computer and use it in GitHub Desktop.
a web page to control a 12 neopixels ring
<!-- Note: this html / js below is missing the standard html / head / body tags -->
<script src="/assets/js/paho-mqtt-min.js"></script>
<h2>Testing Neopixel from web colour pickers</h2>
<!-- this text will update depending on the value in the dropdown -->
<p id="mqttTopic">Connecting to "student/CASA0014/light/1/pixel/"</p>
<!-- This form displays if the user does not have the MQTT password saved in localstore -->
<div id="passwordForm" style="display:none;">
<form id="passwordSetForm">
<label for="password">Password:</label>
<input type="password" id="password" name="password">
<input type="submit" value="Set Password">
</form>
</div>
<!-- the div displays the colour pickers -->
<div id="colorPickers">
<!-- Color pickers will be dynamically added here -->
</div>
<!-- drop down menu to select which ring you are sending data to -->
<!-- it gets updated in script below to add in 39 more numbers to menu -->
<select id="neopixelid">
<!-- Default option -->
<option value="1" selected>1</option>
</select>
<!-- these are teh buttons to take action the LED colour picker -->
<button onclick="sendColors()">Send Colors</button>
<button onclick="setRandomColors()">Random Colors</button>
<button onclick="setGradient()">Gradient (Red to Green)</button>
<button onclick="clearColors()">Clear Colors</button>
<button onclick="sendAllColors()">Send All Colors</button>
<!-- this div is used to show the message being sent to MQTT -->
<div ID="mqtt_message"></div>
<script>
// Get a reference to the dropdown element
var dropdown = document.getElementById("neopixelid");
// Loop from 2 to 40 and create options
for (var i = 2; i <= 40; i++) {
var option = document.createElement("option");
option.text = i;
option.value = i;
dropdown.appendChild(option);
}
// Get references to the dropdown and paragraph elements
var mqttTopic = document.getElementById("mqttTopic");
// Function to update the paragraph text with the selected value
function updateMqttTopic() {
var selectedValue = neopixelid.value;
mqttTopic.textContent = 'Connecting to "student/CASA0014/light/' + selectedValue + '/pixel/"';
}
// Call the function to update the paragraph text when the page loads
updateMqttTopic();
// Add an event listener to the dropdown to update the paragraph text when the selection changes
dropdown.addEventListener("change", updateMqttTopic);
var mqttClient = null;
// Function to dynamically create color pickers
function createColorPickers() {
var colorPickersDiv = document.getElementById("colorPickers");
for (var i = 0; i < 12; i++) {
var colorPickerContainer = document.createElement("div"); // Container for color picker and payload display
colorPickerContainer.style.display = "flex"; // Use flexbox for layout
var label = document.createElement("label");
label.textContent = "Pixel " + i + ": ";
colorPickerContainer.appendChild(label);
var colorPicker = document.createElement("input");
colorPicker.type = "color";
colorPicker.id = "colorPicker" + i;
colorPickerContainer.appendChild(colorPicker);
var payloadDiv = document.createElement("div");
payloadDiv.id = "payload" + i;
payloadDiv.style.marginLeft = "10px"; // Add some spacing
colorPickerContainer.appendChild(payloadDiv);
colorPickersDiv.appendChild(colorPickerContainer);
colorPickersDiv.appendChild(document.createElement("br")); // Line break for spacing
}
}
// ================================================
// FUNCTIONS FOR SENDING COLOURS IN PAYLOAD ONE AT A TIME
// Function to send colors to MQTT broker
function sendColors() {
if (!mqttClient || !mqttClient.isConnected()) {
mqttConnectAndSendColors();
} else {
sendColorsToBroker();
}
}
// Function to send colors to MQTT broker after connecting
function mqttConnectAndSendColors() {
var password = localStorage.getItem('mqttPassword') || ""; // Get password from localStorage
mqttClient = new Paho.MQTT.Client("mqtt.cetools.org", Number(8091), "clientId_" + parseInt(Math.random() * 100, 10));
var mqttOptions = {
userName: "student",
password: password,
onSuccess: function() {
sendColorsToBroker();
},
useSSL: true // Enable SSL/TLS encryption
};
mqttClient.connect(mqttOptions);
}
// Function to send colors to MQTT broker
function sendColorsToBroker() {
var neopixelvalue = document.getElementById("neopixelid").value;
for (var i = 0; i < 12; i++) {
var colorPicker = document.getElementById("colorPicker" + i);
var colorHex = colorPicker.value.substring(1); // remove '#'
var R = parseInt(colorHex.substring(0, 2), 16);
var G = parseInt(colorHex.substring(2, 4), 16);
var B = parseInt(colorHex.substring(4, 6), 16);
sendColor(neopixelvalue, i, R, G, B);
}
}
// Function to send color to MQTT broker
function sendColor(neoring, pixelId, R, G, B) {
var message = {
"pixelid": pixelId,
"R": R,
"G": G,
"B": B,
"W": 0
};
var topic = "student/CASA0014/light/" + neoring + "/pixel/";
var messageProperties = {
retain: true // Set retain flag to true so if arduino resets it will pick up last value
};
var payloadDiv = document.getElementById("payload" + pixelId);
payloadDiv.textContent = "Payload sent: " + JSON.stringify(message); // Display payload
mqttSend(topic, JSON.stringify(message));
}
// ================================================
// FUNCTIONS FOR SENDING ALL COLOURS IN ONE PAYLOAD
// Function to send all colors to MQTT broker
function sendAllColors() {
if (!mqttClient || !mqttClient.isConnected()) {
mqttConnectAndSendAllColors();
} else {
sendAllColorsToBroker();
}
}
// Function to send all colors to MQTT broker after connecting
function mqttConnectAndSendAllColors() {
var password = localStorage.getItem('mqttPassword') || ""; // Get password from localStorage
mqttClient = new Paho.MQTT.Client("mqtt.cetools.org", Number(8091), "clientId_" + parseInt(Math.random() * 100, 10)); // Use port 8094 for encrypted connection
var mqttOptions = {
userName: "student",
password: password,
onSuccess: function() {
sendAllColorsToBroker();
},
useSSL: true // Enable SSL/TLS encryption
};
mqttClient.connect(mqttOptions);
}
function sendAllColorsToBroker() {
var allColors = []; // Array to hold all 12 sets of RGBW values
var neopixelvalue = document.getElementById("neopixelid").value;
// Loop through each color picker to collect RGBW values
for (var i = 0; i < 12; i++) {
var colorPicker = document.getElementById("colorPicker" + i);
var colorHex = colorPicker.value.substring(1); // remove '#'
var R = parseInt(colorHex.substring(0, 2), 16);
var G = parseInt(colorHex.substring(2, 4), 16);
var B = parseInt(colorHex.substring(4, 6), 16);
// Add RGBW values to the array
allColors.push({
"pixelid": i,
"R": R,
"G": G,
"B": B,
"W": 0 // Assuming W value is always 0 for all colors
});
}
var topic = "student/CASA0014/light/" + neopixelvalue + "/all/";
// Construct MQTT message payload with all colors
var message = {
"allLEDs" : allColors
};
// Convert the message to JSON string
var messageString = JSON.stringify(message);
// Display payload (optional)
var payloadDiv = document.getElementById("mqtt_message");
payloadDiv.textContent = "Payload sent: " + messageString;
// Send MQTT message with the payload
mqttSend(topic, messageString);
}
// Check if password is set locally
function isPasswordSetLocally() {
return localStorage.getItem('mqttPassword') !== null;
}
// Function to show color pickers
function showColorPickers() {
document.getElementById("colorPickers").style.display = "block";
}
// Function to initialize the page
function initializePage() {
if (!isPasswordSetLocally()) {
// Password is not set, show password form
document.getElementById("passwordForm").style.display = "block";
} else {
// Password is set, show color pickers
createColorPickers();
}
}
// Function to set random colors for all color pickers
function setRandomColors() {
for (var i = 0; i < 12; i++) {
var colorPicker = document.getElementById("colorPicker" + i);
var randomColor = '#' + Math.floor(Math.random()*16777215).toString(16); // Generate random hex color
colorPicker.value = randomColor;
}
}
// Function to set random colors for all color pickers
function clearColors() {
for (var i = 0; i < 12; i++) {
var colorPicker = document.getElementById("colorPicker" + i);
colorPicker.value = 0;
}
}
// Function to set gradient from red to green for all color pickers
function setGradient() {
var red = 255;
var green = 0;
for (var i = 0; i < 12; i++) {
var colorPicker = document.getElementById("colorPicker" + i);
var colorHex = rgbToHex(red, green, 0);
colorPicker.value = colorHex;
// Interpolate colors between red and green
red -= 255 / 11;
green += 255 / 11;
}
}
// Function to convert RGB to hexadecimal color code
function rgbToHex(r, g, b) {
return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}
// Function to send MQTT message
function mqttSend(topic, message) {
if (mqttClient && mqttClient.isConnected()) {
//mqttClient.send(topic, message, true);
var mqttMessage = new Paho.MQTT.Message(message);
mqttMessage.destinationName = topic;
message.retained = true;
mqttClient.send(mqttMessage);
}
}
// Function to handle form submission for setting password
document.getElementById("passwordSetForm").addEventListener("submit", function(event) {
event.preventDefault();
var password = document.getElementById("password").value;
localStorage.setItem('mqttPassword', password); // Save password locally
createColorPickers(); // Show color pickers after setting the password
});
// Call initializePage() when the page loads
window.onload = initializePage;
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment