|
1 <?php |
|
2 $my_style = 'android'; |
|
3 require_once('version.php'); |
|
4 ?> |
|
5 <!DOCTYPE html> |
|
6 <html lang="en"> |
|
7 <head>' |
|
8 <meta http-equiv="content-type" content="text/html; charset=utf-8" /> |
|
9 <title id='Description'>Brewery Managment System v<?php echo $my_version; ?></title> |
|
10 <link type="text/css" href="css/style.css" rel="stylesheet" media="all" /> |
|
11 <link type="text/css" href="jqwidgets/styles/jqx.base.css" rel="stylesheet" /> |
|
12 <link type="text/css" href="jqwidgets/styles/jqx.<?php echo $my_style; ?>.css" rel="stylesheet" /> |
|
13 <meta name="viewport" content="width=device-width, initial-scale=1 maximum-scale=1 minimum-scale=1" /> |
|
14 <script src="js/jquery-1.11.1.min.js"></script> |
|
15 <script src="jqwidgets/jqxcore.js"></script> |
|
16 <script src="jqwidgets/jqxbuttons.js"></script> |
|
17 <script src="jqwidgets/jqxscrollbar.js"></script> |
|
18 <script src="jqwidgets/jqxpanel.js"></script> |
|
19 <script src="jqwidgets/jqxtree.js"></script> |
|
20 <script src="jqwidgets/jqxexpander.js"></script> |
|
21 <script src="jqwidgets/jqxsplitter.js"></script> |
|
22 <script src="jqwidgets/jqxdata.js"></script> |
|
23 <script src="jqwidgets/jqxcheckbox.js"></script> |
|
24 <script src="jqwidgets/jqxradiobutton.js"></script> |
|
25 <script src="jqwidgets/jqxchart.core.js"></script> |
|
26 <script src="jqwidgets/jqxgauge.js"></script> |
|
27 <script src="jqwidgets/jqxdraw.js"></script> |
|
28 <script src="jqwidgets/jqxtooltip.js"></script> |
|
29 <script> |
|
30 $(document).ready(function () { |
|
31 /* |
|
32 * Different right panel pages |
|
33 */ |
|
34 var refreshIntervalId = 0; |
|
35 $("#fermenter_thermometers").hide(); |
|
36 $("#splitter").jqxSplitter({ theme: "<?php echo $my_style; ?>", width: 1278, height: 618, panels: [{ size: 250}] }); |
|
37 $("#jqxTree").jqxTree({ theme: "<?php echo $my_style; ?>", height: "100%", width: "100%" }); |
|
38 /* |
|
39 * Build the nodes subtree |
|
40 */ |
|
41 var nodeByID = $("#jqxTree").find("#Nodes")[0]; |
|
42 $.getJSON("getnodes.php", function(data) { |
|
43 for( i = 0; i < data.length; i++ ) { |
|
44 $("#jqxTree").jqxTree("addTo", { id: 'node-' + data[i].uuid, label: data[i].node, icon: 'images/folder.png' }, nodeByID); |
|
45 } |
|
46 }); |
|
47 /* |
|
48 * Build the fermenters subtree |
|
49 */ |
|
50 var fermenterByID = $("#jqxTree").find("#Fermenters")[0]; |
|
51 $.getJSON("getfermenters.php", function(data) { |
|
52 for( i = 0; i < data.length; i++ ) { |
|
53 $("#jqxTree").jqxTree("addTo", { id: 'fermenter-' + data[i].uuid, label: data[i].node + "/" + data[i].alias, icon: 'images/folder.png' }, fermenterByID); |
|
54 } |
|
55 }); |
|
56 |
|
57 $("#jqxTree").css("visibility", "visible"); |
|
58 |
|
59 $("#jqxTree").on("select", function (event) { |
|
60 /* |
|
61 * Cancel a running refresh loop. |
|
62 */ |
|
63 if (refreshIntervalId > 0) { |
|
64 console.log( "RefreshIIntervald: " + refreshIntervalId + " stopped" ); |
|
65 clearInterval(refreshIntervalId); |
|
66 refreshIntervalId = 0; |
|
67 } |
|
68 $("#fermenter_thermometers").hide(); |
|
69 $("#gaugeContainer_air").hide(); |
|
70 $("#gaugeContainer_beer").hide(); |
|
71 $("#gaugeContainer_chiller").hide(); |
|
72 /* |
|
73 * Process the selected id from the left panel tree and show the correct page in the right panel. |
|
74 */ |
|
75 var estr = event.args.element.id; |
|
76 if (estr == "Root") { |
|
77 $("#ContentPanel").html("<div style='margin: 10px;'><a href='index.php'>Hoofdmenu</a></div>"); |
|
78 |
|
79 } else if (estr.indexOf("node-", 0) == 0) { |
|
80 // Load and show a node. |
|
81 // The parameter is: node-36d4d030-4d62-4f2f-a96b-472e643687f7 |
|
82 var uuid = estr.substr(5); |
|
83 var url = "getnode.php?uuid='" + uuid + "'"; |
|
84 var source = { |
|
85 datatype: "json", |
|
86 datafields: [ |
|
87 { name: 'record', type: 'int' }, |
|
88 { name: 'uuid', type: 'string' }, |
|
89 { name: 'node', type: 'string' }, |
|
90 { name: 'online', type: 'bool' }, |
|
91 { name: 'group_id', type: 'string' }, |
|
92 { name: 'hardwaremake', type: 'string' }, |
|
93 { name: 'hardwaremodel', type: 'string' }, |
|
94 { name: 'os', type: 'string' }, |
|
95 { name: 'os_version', type: 'string' }, |
|
96 { name: 'firmware', type: 'string' }, |
|
97 { name: 'firstseen', type: 'string' }, |
|
98 { name: 'lastseen', type: 'string' }, |
|
99 { name: 'temperature', type: 'float' }, |
|
100 { name: 'humidity', type: 'float' }, |
|
101 { name: 'barometer', type: 'float' }, |
|
102 { name: 'gps_latitude', type: 'float' }, |
|
103 { name: 'gps_longitude', type: 'float' }, |
|
104 { name: 'gps_altitude', type: 'float' }, |
|
105 { name: 'net_address', type: 'string' }, |
|
106 { name: 'net_ifname', type: 'string' }, |
|
107 { name: 'net_rssi', type: 'int' } |
|
108 ], |
|
109 id: 'record', |
|
110 url: url |
|
111 }; |
|
112 var dataAdapter = new $.jqx.dataAdapter(source, { |
|
113 loadComplete: function (records) { |
|
114 var record = dataAdapter.records[0]; |
|
115 var html = "<div style='background: #252526; margin: 50px;'>"; |
|
116 html += "<table style='width: 100%; padding: 10px;'>"; |
|
117 html += "<tr><th colspan=2>Systeem overzicht</th></tr>"; |
|
118 html += "<tr><td>Uuid</td><td>" + record.uuid + "</td></tr>"; |
|
119 html += "<tr><td>Systeem</td><td>" + record.node + "</td></tr>"; |
|
120 html += "<tr><td>Online</td><td>" + record.online + "</td></tr>"; |
|
121 html += "<tr><td>Type</td><td>" + record.group_id + "</td></tr>"; |
|
122 html += "<tr><td>Eerst gezien</td><td>" + record.firstseen + "</td></tr>"; |
|
123 html += "<tr><td>Laatst gezien</td><td>" + record.lastseen + "</td></tr>"; |
|
124 html += "<tr><td>Hardware maker</td><td>" + record.hardwaremake+ "</td></tr>"; |
|
125 html += "<tr><td>Hardware model</td><td>" + record.harwaremodel+ "</td></tr>"; |
|
126 html += "<tr><td>OS</td><td>" + record.os + " versie: " + record.os_version + "</td></tr>"; |
|
127 html += "<tr><td>Firmware</td><td>" + record.firmware + "</td></tr>"; |
|
128 if (record.online) { |
|
129 html += "<tr><td>Temperatuur</td><td>" + record.temperature + "°C</td></tr>"; |
|
130 if (record.humidity > 0) { |
|
131 html += "<tr><td>Vochtigheid</td><td>" + record.humidity + "%</td></tr>"; |
|
132 } |
|
133 if (record.barometer > 0) { |
|
134 html += "<tr><td>Luchtdruk</td><td>" + record.barometer + "</td></tr>"; |
|
135 } |
|
136 if ((record.gps_latitude != 0) && (record.gps_longitude != 0)) { |
|
137 html += "<tr><td>GPS</td><td>"+ record.gps_latitude + " " + record.gps_longitude + " " + record.gps_altitude + "</td></tr>"; |
|
138 } |
|
139 html += "<tr><td>Netwerk</td><td>"+ record.net_ifname + " " + record.net_address + "</td></tr>"; |
|
140 } |
|
141 html += "</<table>"; |
|
142 html += "</div>"; |
|
143 $("#ContentPanel").html(html); |
|
144 } |
|
145 }); |
|
146 // Get the data immediatly and then at regular intervals to refresh. |
|
147 dataAdapter.dataBind(); |
|
148 refreshIntervalId = setInterval(function(){ |
|
149 dataAdapter.dataBind(); |
|
150 }, 30000); |
|
151 |
|
152 } else if (estr.indexOf("fermenter-", 0) == 0) { |
|
153 // Load and show a fermenter. |
|
154 // The parameter is: fermenter-36d4d030-4d62-4f2f-a96b-472e643687f7 |
|
155 var gaugeoptions = { |
|
156 min: -5, max: 35, width: 275, height: 275, |
|
157 ranges: [{ startValue: -5, endValue: 0, style: { fill: '#3399FF', stroke: '#3399FF' }, endWidth: 10, startWidth: 10 }, |
|
158 { startValue: 0, endValue: 16, style: { fill: '#00CC33', stroke: '#00CC33' }, endWidth: 10, startWidth: 10 }, |
|
159 { startValue: 16, endValue: 24, style: { fill: '#FCA76A', stroke: '#FCA76A' }, endWidth: 10, startWidth: 10 }, |
|
160 { startValue: 24, endValue: 35, style: { fill: '#FC6A6A', stroke: '#FC6A6A' }, endWidth: 10, startWidth: 10 }], |
|
161 ticksMinor: { interval: 1, size: '5%' }, |
|
162 ticksMajor: { interval: 5, size: '9%' }, |
|
163 labels: { interval: 5 }, |
|
164 style: { fill: '#eeeeee', stroke: '#666666' }, |
|
165 value: 0, |
|
166 colorScheme: 'scheme05', |
|
167 animationDuration: 1200 |
|
168 }; |
|
169 var gaugeSmalloptions = { |
|
170 min: -20, max: 25, width: 150, height: 150, |
|
171 ranges: [{ startValue: -20, endValue: 0, startWidth: 5, endWidth: 5, style: { fill: '#3399FF', stroke: '#3399FF' }}, |
|
172 { startValue: 0, endValue: 25, startWidth: 5, endWidth: 5, style: { fill: '#FC6A6A', stroke: '#FC6A6A' }}], |
|
173 ticksMinor: { interval: 1, size: '5%' }, |
|
174 ticksMajor: { interval: 5, size: '9%' }, |
|
175 labels: { interval: 5 }, |
|
176 style: { fill: '#eeeeee', stroke: '#666666' }, |
|
177 value: 0, |
|
178 colorScheme: 'scheme05', |
|
179 animationDuration: 1200, |
|
180 caption: { value: 'Chiller', position: 'bottom', offset: [0, 10] } |
|
181 }; |
|
182 $("#fermenter_thermometers").show(); |
|
183 $("#gaugeContainer_air").show(); |
|
184 $("#gaugeContainer_air").jqxGauge( gaugeoptions ); |
|
185 $("#gaugeContainer_air").jqxGauge( { caption: { value: 'Air', position: 'bottom', offset: [0, 10] }} ); |
|
186 $("#gaugeContainer_beer").show(); |
|
187 $("#gaugeContainer_beer").jqxGauge( gaugeoptions ); |
|
188 $("#gaugeContainer_beer").jqxGauge( { caption: { value: 'Beer', position: 'bottom', offset: [0, 10] }} ); |
|
189 $("#gaugeContainer_chiller").show(); |
|
190 $("#gaugeContainer_chiller").jqxGauge( gaugeSmalloptions ); |
|
191 var uuid = estr.substr(10); |
|
192 var url = "getfermenter.php?uuid='" + uuid + "'"; |
|
193 var source = { |
|
194 datatype: "json", |
|
195 datafields: [ |
|
196 { name: 'record', type: 'int' }, |
|
197 { name: 'uuid', type: 'string' }, |
|
198 { name: 'alias', type: 'string' }, |
|
199 { name: 'node', type: 'string' }, |
|
200 { name: 'online', type: 'bool' }, |
|
201 { name: 'beercode', type: 'string' }, |
|
202 { name: 'beername', type: 'string' }, |
|
203 { name: 'air_address', type: 'string' }, |
|
204 { name: 'air_state', type: 'string' }, |
|
205 { name: 'air_temperature', type: 'float' }, |
|
206 { name: 'beer_address', type: 'string' }, |
|
207 { name: 'beer_state', type: 'string' }, |
|
208 { name: 'beer_temperature', type: 'float' }, |
|
209 { name: 'chiller_address', type: 'string' }, |
|
210 { name: 'chiller_state', type: 'string' }, |
|
211 { name: 'chiller_temperature', type: 'float' }, |
|
212 { name: 'heater_address', type: 'string' }, |
|
213 { name: 'heater_state', type: 'int' }, |
|
214 { name: 'heater_usage', type: 'int' }, |
|
215 { name: 'cooler_address', type: 'string' }, |
|
216 { name: 'cooler_state', type: 'int' }, |
|
217 { name: 'cooler_usage', type: 'int' }, |
|
218 { name: 'fan_address', type: 'string' }, |
|
219 { name: 'fan_state', type: 'int' }, |
|
220 { name: 'fan_usage', type: 'int' }, |
|
221 { name: 'light_address', type: 'string' }, |
|
222 { name: 'light_state', type: 'int' }, |
|
223 { name: 'light_usage', type: 'int' }, |
|
224 { name: 'door_address', type: 'string' }, |
|
225 { name: 'door_state', type: 'int' }, |
|
226 { name: 'psu_address', type: 'string' }, |
|
227 { name: 'psu_state', type: 'int' }, |
|
228 { name: 'mode', type: 'string' }, |
|
229 { name: 'alarm', type: 'int' }, |
|
230 { name: 'setpoint_high', type: 'float' }, |
|
231 { name: 'setpoint_low', type: 'float' }, |
|
232 { name: 'profile_uuid', type: 'string' }, |
|
233 { name: 'profile_name', type: 'string' }, |
|
234 { name: 'profile_state', type: 'string' }, |
|
235 { name: 'profile_precent', type: 'int' }, |
|
236 { name: 'profile_inittemp_high', type: 'float' }, |
|
237 { name: 'profile_inittemp_low', type: 'float' }, |
|
238 { name: 'profile_steps', type: 'string' }, |
|
239 { name: 'stage', type: 'string' } |
|
240 ], |
|
241 id: 'record', |
|
242 url: url |
|
243 }; |
|
244 var dataAdapter = new $.jqx.dataAdapter(source, { |
|
245 loadComplete: function (records) { |
|
246 var record = dataAdapter.records[0]; |
|
247 var oline = (record.online) ? "On-line" : "Off-line"; |
|
248 var html = "<div id='fermenter_table'>"; |
|
249 html += "<table style='width: 100%; padding: 10px;'>"; |
|
250 html += "<tr><th colspan=2>Klimaatkast overzicht</th></tr>"; |
|
251 html += "<tr><td>Uuid</td><td>" + record.uuid + "</td></tr>"; |
|
252 html += "<tr><td>Systeem</td><td>" + record.node + "/" + record.alias + " " + oline + "</td></tr>"; |
|
253 html += "<tr><td>Bier</td><td>" + record.beercode + " - " + record.beername + "</td></tr>"; |
|
254 html += "<tr><td>Werking</td><td>" + record.mode + "</td></tr>"; |
|
255 html += "<tr><td>Fase</td><td>" + record.stage + "</td></tr>" |
|
256 html += "</<table>"; |
|
257 html += "</div>"; |
|
258 $("#ContentPanel").html(html); |
|
259 $('#gaugeContainer_air').jqxGauge({ value: record.air_temperature }); |
|
260 if (record.online && (record.air_state == "OK")) { |
|
261 $("#gaugeContainer_air").jqxGauge({ disabled: false }); |
|
262 } else { |
|
263 $("#gaugeContainer_air").jqxGauge({ disabled: true }); |
|
264 } |
|
265 $('#gaugeContainer_beer').jqxGauge({ value: record.beer_temperature }); |
|
266 if (record.online && (record.beer_state == "OK")) { |
|
267 $("#gaugeContainer_beer").jqxGauge({ disabled: false }); |
|
268 } else { |
|
269 $("#gaugeContainer_beer").jqxGauge({ disabled: true }); |
|
270 } |
|
271 $("#gaugeContainer_chiller").jqxGauge({ value: record.chiller_temperature }); |
|
272 if (record.online && (record.chiller_state == "OK")) { |
|
273 $("#gaugeContainer_chiller").jqxGauge({ disabled: false }); |
|
274 } else { |
|
275 $("#gaugeContainer_chiller").jqxGauge({ disabled: true }); |
|
276 } |
|
277 html = "<div>SpH <span class='temperature NUM'>" + record.setpoint_high + "</span></div>"; |
|
278 html += "<div>SpL <span class='temperature NUM'>" + record.setpoint_low + "</span></div>"; |
|
279 html += "<div>Air <span class='temperature NUM'>" + record.air_temperature + "</span></div>"; |
|
280 html += "<div>Beer <span class='temperature NUM'>" + record.beer_temperature + "</span></div>"; |
|
281 $("#fermenter_tempdigits").html(html); |
|
282 } |
|
283 }); |
|
284 // Get the data immediatly and then at regular intervals to refresh. |
|
285 dataAdapter.dataBind(); |
|
286 refreshIntervalId = setInterval(function(){ |
|
287 dataAdapter.dataBind(); |
|
288 }, 10000); |
|
289 |
|
290 } else if (event.args.element.id == "Nodes") { |
|
291 $("#ContentPanel").html("<div></div"); |
|
292 } else { |
|
293 $("#ContentPanel").html("<div style='margin: 10px;'>" + event.args.element.id + "</div>"); |
|
294 } |
|
295 }); |
|
296 }); |
|
297 </script> |
|
298 </head> |
|
299 |
|
300 <body class="default"> |
|
301 <div id="jqxWidget"> |
|
302 <div id="header"> |
|
303 <div id="title">BMS <?php echo $my_version; ?></div> |
|
304 </div> <!-- header --> |
|
305 <div id="splitter"> |
|
306 <div> <!-- tree panel --> |
|
307 <div style="visibility: hidden; border: none;" id='jqxTree'> |
|
308 <ul> |
|
309 <li id="Root" item-expanded='true'> |
|
310 <img style='float: left; margin-right: 5px;' src='images/earth.png' /> |
|
311 <span item-title="true">Root</span> |
|
312 <ul> |
|
313 <li id="Nodes"> |
|
314 <img style='float: left; margin-right: 5px;' src='images/folder.png' /> |
|
315 <span item-title="true">Systemen</span> |
|
316 <!-- Subtree nodes --> |
|
317 </li> |
|
318 <li id="Fermenters"> |
|
319 <img style='float: left; margin-right: 5px;' src='images/folder.png' /> |
|
320 <span item-title="true">Klimaatkasten</span> |
|
321 <!-- Subtree fermenters --> |
|
322 </li> |
|
323 <li id="Brewboards"> |
|
324 <img src='images/settings.png' /> |
|
325 <span item-title="true">Brouw apparatuur</span> |
|
326 </li> |
|
327 <li id="Prducing"> |
|
328 <img src='images/system.png' /> |
|
329 <span item-title="true">In productie</span> |
|
330 </li> |
|
331 <li id="Recipes"> |
|
332 <img style='float: left; margin-right: 5px;' src='images/beer.png' /> |
|
333 <span item-title="true">Recepten</span> |
|
334 </li> |
|
335 <li id="Settings"> |
|
336 <img style='float: left; margin-right: 5px;' src='images/setupIcon.png' /> |
|
337 <span item-title="true">Instellingen</span> |
|
338 </li> |
|
339 </ul> |
|
340 </li> |
|
341 </ul> |
|
342 </div> <!-- jqxTree --> |
|
343 </div> <!-- tree panel --> |
|
344 <div id="RightPanel"> |
|
345 <div id="ContentPanel"></div> |
|
346 <div id='fermenter_thermometers'> |
|
347 <div id="gaugeContainer_air" style='float: left; margin-top: 10px; margin-left: 10px;'></div> |
|
348 <div id="gaugeContainer_beer" style="float: right; margin-top: 10px; margin-right: 10px;"></div> |
|
349 <div id="gaugeContainer_chiller" style="float: left; margin-top: 15px;"></div> |
|
350 <div id="fermenter_tempdigits"></div> |
|
351 </div> |
|
352 </div> |
|
353 </div> <!--- splitter --> |
|
354 </div> <!-- jqxWidget --> |
|
355 </body> |
|
356 </html> |