/ ESP8266_MicroPython_Holiday_Lights / lights.html
lights.html
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="utf-8"> 5 <title>ESP8266 MicroPython Smart Holiday Lights</title> 6 <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> 7 </head> 8 9 <body> 10 <div class="container"> 11 <div class="row"> 12 <div class="col-lg-8 col-lg-offset-2"> 13 <div class="jumbotron"> 14 <h1>MicroPython Smart Holiday Lights</h1> 15 <p class="lead">Control your holiday lights using MicroPython and the 16 ESP8266 WiFi microcontroller.</p> 17 </div> 18 </div> 19 </div> 20 <div class="row"> 21 <div class="col-lg-4 col-lg-offset-4"> 22 <form> 23 <div class="form-group"> 24 <label for="boardURL">Board URL</label> 25 <input type="text" class="form-control" id="boardURL" value="ws://192.168.4.1:8266"> 26 </div> 27 <div class="form-group"> 28 <label for="password">Password</label> 29 <input type="password" class="form-control" id="password" placeholder="Password"> 30 </div> 31 <div class="form-group"> 32 <label for="animation">Animation</label> 33 <select class="form-control" id="animation"> 34 <option value="solid">Solid</option> 35 <option value="chase">Chase</option> 36 <option value="smooth">Smooth</option> 37 <option value="blank">Blank (off)</option> 38 </select> 39 </div> 40 <div class="form-group"> 41 <label for="periodMS">Animation Period (milliseconds)</label> 42 <input type="text" class="form-control" id="periodMS" value="250"> 43 </div> 44 <div class="form-group"> 45 <label for="colors">Colors</label> 46 <select class="form-control" id="colors"> 47 </select> 48 </div> 49 <div class="checkbox"> 50 <label> 51 <input type="checkbox" id="mirror" checked> 52 Mirror Colors 53 </label> 54 </div> 55 <button class="btn btn-lg btn-primary" type="button" id="update">Update Lights</button> 56 </form> 57 </div> 58 </div> 59 </div> 60 </body> 61 62 <script 63 src="https://code.jquery.com/jquery-3.1.1.min.js" 64 integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" 65 crossorigin="anonymous"></script> 66 <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> 67 <script> 68 // Global configuration: 69 var colors = [ 70 { name: 'Blue - Red', value: [[0,0,255], [16,0,128], [32,0,64], [64,0,32], [128,0,16], [255,0,0]] }, 71 { name: 'Red - Green', value: [[255,0,0], [128,16,0], [64,32,0], [32,64,0], [16,128,0], [0,255,0]] }, 72 { name: 'Blue - White', value: [[0,0,255], [16,16,255], [32,32,255], [64,64,255], [128,128,255], [255,255,255]] } 73 ]; 74 75 // Function to connect to the WebREPL on the specified board URL and with the 76 // specified password. Once connected the onConnect callback will be called 77 // and a websocket object passed in. If an error occurs the onError callback 78 // is called with the error event object as a parameter. 79 function webreplConnect(url, password, onConnect, onError) { 80 var ws = new WebSocket(url); 81 ws.onopen = function() { 82 // Print messages received from the WebREPL. Uncomment this to help with 83 // debugging. 84 ws.onmessage = function(e) { 85 console.log(e.data); 86 } 87 // First send the password immediately since it's required to use WebREPL. 88 ws.send(password + '\r\n'); // Send password and CR LF (like pressing enter). 89 // Next send a Ctrl-C to stop any running main loop. 90 ws.send('\x03'); 91 // Fire the connected callback. 92 onConnect(ws); 93 }; 94 ws.onerror = function(e) { 95 // Something went wrong! Call the user's error handler. 96 onError(e); 97 }; 98 } 99 100 // Send a file to a board using the WebREPL. WS should be a websocket connection 101 // to a board, filename is the name of the file to save on the board, and data 102 // should be a Uint8Array of data for the file. 103 function putFile(ws, fileName, data) { 104 // Construct a header to specify a file put operation. 105 var size = data.length; 106 var rec = new Uint8Array(2 + 1 + 1 + 8 + 4 + 2 + 64); 107 rec[0] = 'W'.charCodeAt(0); 108 rec[1] = 'A'.charCodeAt(0); 109 rec[2] = 1; // put 110 rec[3] = 0; 111 rec[4] = 0; rec[5] = 0; rec[6] = 0; rec[7] = 0; rec[8] = 0; rec[9] = 0; rec[10] = 0; rec[11] = 0; 112 rec[12] = size & 0xff; rec[13] = (size >> 8) & 0xff; rec[14] = (size >> 16) & 0xff; rec[15] = (size >> 24) & 0xff; 113 rec[16] = fileName.length & 0xff; rec[17] = (fileName.length >> 8) & 0xff; 114 for (var i = 0; i < 64; ++i) { 115 if (i < fileName.length) { 116 rec[18 + i] = fileName.charCodeAt(i); 117 } else { 118 rec[18 + i] = 0; 119 } 120 } 121 // Send put file request header that was constructed above. 122 ws.send(rec); 123 // Next send the file data. 124 ws.send(data); 125 } 126 127 $(document).ready(function() { 128 // Main code that runs when the page is loaded. 129 // Populate the color selection list. 130 colors.forEach(function(color, i) { 131 $('#colors').append($('<option></option>').attr('value', i).text(color.name)); 132 }); 133 134 // Update the board state when the update button is clicked. 135 $('#update').click(function() { 136 // Build the board's new configuration. 137 var config = { 138 colors: colors[$('#colors').val()].value, 139 period_ms: Number($('#periodMS').val()), 140 mirror_colors: $('#mirror').prop('checked'), 141 animation: $('#animation').val() 142 } 143 var boardURL = $('#boardURL').val(); 144 var password = $('#password').val(); 145 // Connect to the board's REPL. 146 webreplConnect(boardURL, password, function(ws) { 147 console.log('Connected!'); 148 // Connected, now convert config state to JSON bytes. 149 var configJSON = JSON.stringify(config); 150 var configBytes = new Uint8Array(configJSON.length); 151 for (var i = 0; i < configJSON.length; ++i) { 152 configBytes[i] = configJSON.charCodeAt(i); 153 } 154 // Send the new configuration file. 155 putFile(ws, 'config.json', configBytes); 156 // Reset the board so the new configuration takes effect. 157 // Note that sending a Ctrl-B doesn't seem to work as the WebREPL won't 158 // restart on soft reset. 159 ws.send('import machine\r\nmachine.reset()\r\n'); 160 // Close the connection. 161 ws.close(); 162 console.log('Updated lights!'); 163 }, 164 function(e) { 165 console.log('Error connecting to MicroPython board!'); 166 }) 167 }); 168 }); 169 </script> 170 </html>