ESP8266 SHT21 sensor
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

client-script.js 9.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. // This is the client-side Javascript that receives the IPs of all available
  2. // local ESP-Weather modules, reads their values using the Websocket interface
  3. // and renders the graphs to visualize them.
  4. //
  5. // ----------------------------------------------------------------------------
  6. // "THE BEER-WARE LICENSE" (Revision 42):
  7. // <xythobuz@xythobuz.de> & <ghost-ghost@web.de> wrote this file. As long as
  8. // you retain this notice you can do whatever you want with this stuff. If we
  9. // meet some day, and you think this stuff is worth it, you can buy us a beer
  10. // in return. Thomas Buck & Christian Högerle
  11. // ----------------------------------------------------------------------------
  12. var arrSensor = Array();
  13. textAvailableSensors = "Available Sensors";
  14. textButtonNext = "Continue";
  15. homeTabName = "Home";
  16. sensorTabName = "Sensor";
  17. errorMessage = "Couldn't read sensor with IP: ";
  18. errorTitle = "Error: ";
  19. temperatureLabel = 'Temperature [C]';
  20. humidityLabel = 'Humidity [%RH]';
  21. temperatureHeading = "Temperature";
  22. humidityHeading = "Humidity";
  23. $(document).ready(function() {
  24. $('#main-part').append(`
  25. <div class="row" id="contentDiv">
  26. <div class="col-md-5 col-lg-5">
  27. <div class="panel panel-primary">
  28. <div class="panel-heading" id="listSensorsHeading">
  29. ` + textAvailableSensors + ` (0/0)
  30. </div>
  31. <div class="panel-body">
  32. <ul class="list-group" id="listSensors"></ul>
  33. <div id="alertDiv"></div>
  34. <button class="btn btn-primary" disabled="" id="btnSubmit">
  35. ` + textButtonNext + `
  36. </button>
  37. </div>
  38. </div>
  39. </div>
  40. </div>`);
  41. // Get current client-time for the graph X-axis labels
  42. var actTime = new Date();
  43. actTime = actTime.getHours() + ":" + (actTime.getMinutes() < 10 ? '0':'') + actTime.getMinutes();
  44. $('#listSensorsHeading').empty();
  45. $('#listSensorsHeading').html(textAvailableSensors + " (0/" + clients.length + ")");
  46. // Iterate all given client IPs and get their data using Websocket
  47. var count = [0];
  48. jQuery.each(clients, function(index, client) {
  49. webSocket(client, "2391", count, clients.length);
  50. });
  51. // Button to continue to graph view
  52. $("#btnSubmit").click(function(event) {
  53. $('#contentDiv').empty();
  54. generateView(arrSensor, actTime);
  55. });
  56. });
  57. function webSocket(wsUri, wsPort, count, clientsCount) {
  58. websocket = new WebSocket("ws://" + wsUri + ":" + wsPort + "/");
  59. websocket.onopen = function(evt) {};
  60. websocket.onclose = function(evt) {};
  61. websocket.onmessage = function(evt) {
  62. var jsonData = jQuery.parseJSON(evt.data);
  63. count[0]++;
  64. var sensor = {id: count[0], ip: wsUri, currentTemp: jsonData['T'], currentHum: jsonData['H']};
  65. var arrEEPROM = Array();
  66. jQuery.each(jsonData['EEPROM'], function(index, data) {
  67. arrEEPROM.push(data);
  68. });
  69. sensor.arrEEPROM = arrEEPROM;
  70. arrSensor.push(sensor);
  71. $('#listSensorsHeading').html(textAvailableSensors + " (" + sensor.id + "/" + clientsCount + ")");
  72. $('#listSensors').append('<li class="list-group-item">' +
  73. ' Sensor ' + sensor.id +
  74. ' | IP: ' + sensor.ip +
  75. ' | Temperature: ' + sensor.currentTemp +
  76. ' | Humidity: ' + sensor.currentHum +
  77. '</li>');
  78. // Enable continue buttons when all modules have been reached
  79. if(count[0] == clientsCount) {
  80. $('#btnSubmit').prop("disabled", false);
  81. }
  82. };
  83. websocket.onerror = function(evt) {
  84. if($('#websocketError').length ) {
  85. $('.alert-danger').append(errorMessage + wsUri + '<br>');
  86. } else {
  87. $('#alertDiv').append('<div class="alert alert-danger" id="websocketError">' +
  88. '<strong>' + errorTitle
  89. + '</strong><br>' + errorMessage
  90. + wsUri + '<br></div>');
  91. }
  92. console.log(evt.data);
  93. };
  94. }
  95. function generateView(arrSensor, actTime) {
  96. $('#contentDiv').append(`<div class="col-md-12 col-lg-12">
  97. <div class="panel panel-primary">
  98. <ul class="nav nav-pills">
  99. <li class="active"><a class="navtab" data-toggle="tab" href="#home">` + homeTabName + `</a></li>
  100. </ul>
  101. <div class="panel-body">
  102. <div id="contentPanel">
  103. </div>
  104. </div>
  105. </div>
  106. </div>`);
  107. jQuery.each(arrSensor, function(index, sensor) {
  108. $('.nav-pills').append('<li><a class="navtab" data-toggle="tab" href="#' + sensor.id + '">' + sensorTabName + ' ' + sensor.id + '</a></li>');
  109. });
  110. // flag for combined plot -> true
  111. generateGraph(true, arrSensor, actTime);
  112. $(".navtab").click(function(event) {
  113. $('#contentPanel').empty();
  114. if(event.target.text == homeTabName) {
  115. // flag for combined plot -> true
  116. generateGraph(true, arrSensor, actTime);
  117. } else {
  118. generateGraph(false, arrSensor[(event.target.text.split(" ")[1] - 1)], actTime);
  119. }
  120. });
  121. }
  122. function generateGraph(flag, sensor, actTime) {
  123. $('#contentPanel').append(`<div class="row">
  124. <div class="col-sm-12 col-md-12 col-lg-6">
  125. <canvas id="temperaturChart"></canvas>
  126. </div>
  127. <div class="col-sm-12 col-md-12 col-lg-6">
  128. <canvas id="humidityChart"></canvas>
  129. </div>
  130. </div>`);
  131. if (flag) {
  132. // one plot for all sensors
  133. var length = 0;
  134. jQuery.each(sensor, function(index, tmp) {
  135. if(length < tmp.arrEEPROM.length) {
  136. length = tmp.arrEEPROM.length;
  137. }
  138. });
  139. var labels = Array();
  140. actHour = actTime.split(":")[0];
  141. for(var i = length; i > 0; i--) {
  142. labels.unshift(actHour + ":00");
  143. actHour = (actHour - 1).mod(24);
  144. }
  145. labels.push(actTime);
  146. var dataTemperature = Array();
  147. var dataHumidity = Array();
  148. var tmpDataTemperature = Array();
  149. var tmpDataHumidity = Array();
  150. jQuery.each(sensor, function(index, tmp) {
  151. for (var i = 0; i < (length - tmp.arrEEPROM.length); i++) {
  152. tmpDataTemperature.push([]);
  153. tmpDataHumidity.push([]);
  154. }
  155. jQuery.each(tmp.arrEEPROM, function(index, value) {
  156. tmpDataTemperature.push(value['T']);
  157. tmpDataHumidity.push(value['H']);
  158. });
  159. tmpDataTemperature.push(tmp.currentTemp);
  160. tmpDataHumidity.push(tmp.currentHum);
  161. var lineColor = getRandomColor();
  162. dataTemperature.push({label: sensorTabName + " " + tmp.id, data: tmpDataTemperature, fill: false,
  163. borderWidth: 3, borderColor : lineColor,});
  164. dataHumidity.push({label: sensorTabName + " " + tmp.id, data: tmpDataHumidity, fill: false,
  165. borderWidth: 3, borderColor : lineColor,});
  166. tmpDataTemperature = [];
  167. tmpDataHumidity = [];
  168. });
  169. } else {
  170. // plot for one sensor
  171. var labels = Array();
  172. var tmpDataTemperature = Array();
  173. var tmpDataHumidity = Array();
  174. actHour = actTime.split(":")[0];
  175. actHour = (actHour - sensor.arrEEPROM.length).mod(24);
  176. jQuery.each(sensor.arrEEPROM, function(index, value) {
  177. actHour = (actHour + 1).mod(24);
  178. labels.push(actHour + ":00");
  179. tmpDataTemperature.push(value['T']);
  180. tmpDataHumidity.push(value['H']);
  181. });
  182. labels.push(actTime);
  183. tmpDataTemperature.push(sensor.currentTemp);
  184. tmpDataHumidity.push(sensor.currentHum);
  185. var dataTemperature = [{label: temperatureLabel, data: tmpDataTemperature,
  186. fill: false, borderWidth: 3, borderColor: '#337ab7',}];
  187. var dataHumidity = [{label: humidityLabel, data: tmpDataHumidity,
  188. fill: false, borderWidth: 3, borderColor: '#337ab7',}];
  189. }
  190. var tempCtx = $('#temperaturChart');
  191. var humCtx = $('#humidityChart');
  192. var tempChart = new Chart(tempCtx, {
  193. type: 'line',
  194. data: {
  195. labels: labels,
  196. datasets: dataTemperature,
  197. },
  198. options: {
  199. title: {
  200. display: true,
  201. text: temperatureHeading
  202. }
  203. }
  204. });
  205. var humCharts = new Chart(humCtx, {
  206. type: 'line',
  207. data: {
  208. labels: labels,
  209. datasets: dataHumidity,
  210. },
  211. options: {
  212. title: {
  213. display: true,
  214. text: humidityHeading
  215. }
  216. }
  217. });
  218. }
  219. // Modulo-Bug: http://javascript.about.com/od/problemsolving/a/modulobug.htm
  220. Number.prototype.mod = function(n) {
  221. return ((this%n)+n)%n;
  222. }
  223. function getRandomColor() {
  224. var letters = '0123456789ABCDEF'.split('');
  225. var color = '#';
  226. for (var i = 0; i < 6; i++ ) {
  227. color += letters[Math.floor(Math.random() * 16)];
  228. }
  229. return color;
  230. }