1 <?php |
|
2 /** |
|
3 * @file archives.php |
|
4 * @brief Display as chart or download a fermentation logfile. |
|
5 * @author Michiel Broek <mbroek at mbse dot eu> |
|
6 * |
|
7 * Copyright (C) 2015-2018 |
|
8 * |
|
9 * This is free software; you can redistribute it and/or modify it |
|
10 * under the terms of the GNU General Public License as published by the |
|
11 * Free Software Foundation; either version 2, or (at your option) any |
|
12 * later version. |
|
13 * |
|
14 * ThermFerm is distributed in the hope that it will be useful, but |
|
15 * WITHOUT ANY WARRANTY; without even the implied warranty of |
|
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
17 * General Public License for more details. |
|
18 * |
|
19 * You should have received a copy of the GNU General Public License |
|
20 * along with ThermFerm; see the file COPYING. If not, write to the Free |
|
21 * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
|
22 */ |
|
23 |
|
24 |
|
25 require_once('utilities.php'); |
|
26 $my_style = 'ui-redmond'; |
|
27 |
|
28 if (isset($_GET['action'])) { |
|
29 switch ($_GET['action']) { |
|
30 case 'dl': archive_dl(); |
|
31 break; |
|
32 case 'view': archive_view(); |
|
33 break; |
|
34 default: break; |
|
35 } |
|
36 } else { |
|
37 archive_dir(); |
|
38 } |
|
39 |
|
40 exit; |
|
41 |
|
42 /**************************************************************************** |
|
43 * |
|
44 */ |
|
45 |
|
46 /* |
|
47 * View an archived file in graph format |
|
48 */ |
|
49 function archive_view() { |
|
50 |
|
51 global $my_style; |
|
52 |
|
53 $name = urldecode($_GET['name']); |
|
54 $return = urldecode($_GET['return']); |
|
55 |
|
56 $answer = send_cmd('GLOBAL GET'); |
|
57 $arr = explode("\r\n", $answer); |
|
58 $version = "?"; |
|
59 |
|
60 if (startsWith($arr[0], "213")) { |
|
61 $j = 1; |
|
62 while (1) { |
|
63 if (strcmp($arr[$j], ".") == 0) |
|
64 break; |
|
65 $f = explode(",", $arr[$j]); |
|
66 |
|
67 if ($f[0] == "RELEASE") |
|
68 $version = $f[1]; |
|
69 $j++; |
|
70 } |
|
71 } |
|
72 |
|
73 $outstr = '<!DOCTYPE html>'.PHP_EOL; |
|
74 $outstr .= '<html>'.PHP_EOL; |
|
75 $outstr .= ' <head>'.PHP_EOL; |
|
76 $outstr .= ' <meta http-equiv="content-type" content="text/html; charset=utf-8" />'.PHP_EOL; |
|
77 $outstr .= ' <title>Archive View '.$name.'</title>'.PHP_EOL; |
|
78 $outstr .= ' <link type="text/css" href="css/style.css" rel="stylesheet" media="all" />'.PHP_EOL; |
|
79 $outstr .= ' <link type="text/css" href="jqwidgets/styles/jqx.base.css" rel="stylesheet" />'.PHP_EOL; |
|
80 $outstr .= ' <link type="text/css" href="jqwidgets/styles/jqx.'.$my_style.'.css" rel="stylesheet" />'.PHP_EOL; |
|
81 $outstr .= ' <script type="text/javascript" src="js/jquery-2.1.1.min.js"></script>'.PHP_EOL; |
|
82 $outstr .= ' <script type="text/javascript" src="jqwidgets/jqxcore.js"></script>'.PHP_EOL; |
|
83 $outstr .= ' <script type="text/javascript" src="jqwidgets/jqxwindow.js"></script>'.PHP_EOL; |
|
84 $outstr .= ' <script type="text/javascript" src="jqwidgets/jqxbuttons.js"></script>'.PHP_EOL; |
|
85 $outstr .= ' <script type="text/javascript" src="jqwidgets/jqxchart.core.js"></script>'.PHP_EOL; |
|
86 $outstr .= ' <script type="text/javascript" src="jqwidgets/jqxdraw.js"></script>'.PHP_EOL; |
|
87 $outstr .= ' <script type="text/javascript" src="jqwidgets/jqxdata.js"></script>'.PHP_EOL; |
|
88 $outstr .= ' <script type="text/javascript" src="jqwidgets/jqxdata.export.js"></script>'.PHP_EOL; |
|
89 $outstr .= ' </head>'.PHP_EOL; |
|
90 |
|
91 $outstr .= ' <body class="default">'.PHP_EOL; |
|
92 $outstr .= ' <div id="jqxWidget">'.PHP_EOL; |
|
93 $outstr .= ' <div id="header">'.PHP_EOL; |
|
94 $outstr .= ' <div id="title">'.PHP_EOL; |
|
95 $outstr .= ' ThermFerm '.$version.PHP_EOL; |
|
96 $outstr .= ' </div>'.PHP_EOL; |
|
97 if ("$return" == "archives") { |
|
98 $outstr .= ' <form action="archives.php" style="margin:30px; float:right">'.PHP_EOL; |
|
99 $outstr .= ' <input type="submit" id="archives" value="Archives directory" />'.PHP_EOL; |
|
100 } else { |
|
101 $outstr .= ' <form action="index.php" style="margin:30px; float:right">'.PHP_EOL; |
|
102 $outstr .= ' <input type="submit" id="archives" value="Dashboard" />'.PHP_EOL; |
|
103 } |
|
104 $outstr .= ' </form>'.PHP_EOL; |
|
105 $outstr .= ' </div> <!-- header -->'.PHP_EOL; |
|
106 $outstr .= ' <div id="content">'.PHP_EOL; |
|
107 |
|
108 $outstr .= ' <script type="text/javascript">'.PHP_EOL; |
|
109 $outstr .= ' $(document).ready(function () {'.PHP_EOL; |
|
110 |
|
111 $outstr .= ' function getExportServer() {'.PHP_EOL; |
|
112 $outstr .= ' return "https://www.jqwidgets.com/export_server/export.php";'.PHP_EOL; |
|
113 $outstr .= ' }'.PHP_EOL; |
|
114 |
|
115 $outstr .= ' var sourceA ='.PHP_EOL; |
|
116 $outstr .= ' {'.PHP_EOL; |
|
117 $outstr .= ' datatype: "json",'.PHP_EOL; |
|
118 $outstr .= ' datafields: ['.PHP_EOL; |
|
119 $outstr .= ' { name: "Date", type: "date", format: "yyyy-MM-dd HH:mm" },'.PHP_EOL; |
|
120 $outstr .= ' { name: "Mode" },'.PHP_EOL; |
|
121 $outstr .= ' { name: "Air", type: "float" },'.PHP_EOL; |
|
122 $outstr .= ' { name: "Beer", type: "float" },'.PHP_EOL; |
|
123 $outstr .= ' { name: "Target_lo", type: "float" },'.PHP_EOL; |
|
124 $outstr .= ' { name: "Target_hi", type: "float" },'.PHP_EOL; |
|
125 $outstr .= ' { name: "Heater", type: "int" },'.PHP_EOL; |
|
126 $outstr .= ' { name: "Cooler", type: "int" },'.PHP_EOL; |
|
127 $outstr .= ' { name: "HeatUse", type: "int" },'.PHP_EOL; |
|
128 $outstr .= ' { name: "CoolUse", type: "int" },'.PHP_EOL; |
|
129 $outstr .= ' { name: "Room", type: "float" },'.PHP_EOL; |
|
130 $outstr .= ' { name: "Chiller", type: "float" }'.PHP_EOL; |
|
131 $outstr .= ' ],'.PHP_EOL; |
|
132 $outstr .= ' url: \'getalog.php?name='.urlencode($name).'.log\''.PHP_EOL; |
|
133 $outstr .= ' };'.PHP_EOL; |
|
134 |
|
135 $outstr .= ' var dataAdapter = new $.jqx.dataAdapter(sourceA,'.PHP_EOL; |
|
136 $outstr .= ' {'.PHP_EOL; |
|
137 $outstr .= ' autoBind: true,'.PHP_EOL; |
|
138 $outstr .= ' async: false,'.PHP_EOL; |
|
139 $outstr .= ' downloadComplete: function () { },'.PHP_EOL; |
|
140 $outstr .= ' loadComplete: function () { },'.PHP_EOL; |
|
141 $outstr .= ' loadError: function () { }'.PHP_EOL; |
|
142 $outstr .= ' });'.PHP_EOL; |
|
143 |
|
144 $outstr .= ' var settings = {'.PHP_EOL; |
|
145 $outstr .= ' title: "'.$name.'",'.PHP_EOL; |
|
146 $outstr .= ' description: "",'.PHP_EOL; |
|
147 $outstr .= ' padding: { left: 5, top: 5, right: 5, bottom: 5 },'.PHP_EOL; |
|
148 $outstr .= ' titlePadding: { left: 0, top: 0, right: 0, bottom: 10 },'.PHP_EOL; |
|
149 $outstr .= ' source: dataAdapter,'.PHP_EOL; |
|
150 $outstr .= ' xAxis:'.PHP_EOL; |
|
151 $outstr .= ' {'.PHP_EOL; |
|
152 $outstr .= ' dataField: \'Date\','.PHP_EOL; |
|
153 $outstr .= ' type: \'date\','.PHP_EOL; |
|
154 $outstr .= ' formatFunction: function (value) {'.PHP_EOL; |
|
155 $outstr .= ' return value.getDate() + \'-\' + (value.getMonth() + 1) + \'-\' + value.getFullYear()'.PHP_EOL; |
|
156 $outstr .= ' },'.PHP_EOL; |
|
157 $outstr .= ' toolTipFormatFunction: function (value) {'.PHP_EOL; |
|
158 $outstr .= ' var h = value.getHours();'.PHP_EOL; |
|
159 $outstr .= ' var m = value.getMinutes();'.PHP_EOL; |
|
160 $outstr .= ' return value.getDate() + \'-\' + (value.getMonth() + 1) + \'-\' + value.getFullYear()'; |
|
161 $outstr .= ' + \' \' + (h < 10 ? \'0\' + h : h) + \':\' + (m < 10 ? \'0\' + m : m);'.PHP_EOL; |
|
162 $outstr .= ' },'.PHP_EOL; |
|
163 $outstr .= ' textRotationAngle: 45,'.PHP_EOL; |
|
164 $outstr .= ' showGridLines: false'.PHP_EOL; |
|
165 $outstr .= ' },'.PHP_EOL; |
|
166 $outstr .= ' colorScheme: \'scheme01\','.PHP_EOL; |
|
167 $outstr .= ' seriesGroups:'.PHP_EOL; |
|
168 $outstr .= ' [{'.PHP_EOL; |
|
169 $outstr .= ' type: "line",'.PHP_EOL; |
|
170 $outstr .= ' valueAxis:'.PHP_EOL; |
|
171 $outstr .= ' {'.PHP_EOL; |
|
172 $outstr .= ' minValue: 0,'.PHP_EOL; |
|
173 $outstr .= ' maxValue: 100,'.PHP_EOL; |
|
174 $outstr .= ' displayValueAxis: false,'.PHP_EOL; |
|
175 $outstr .= ' description: "Heat/Cool %"'.PHP_EOL; |
|
176 $outstr .= ' },'.PHP_EOL; |
|
177 $outstr .= ' series: ['.PHP_EOL; |
|
178 $outstr .= ' { dataField: "CoolUse", lineWidth: 1, displayText: "Cool %", opacity: 0.3 },'.PHP_EOL; |
|
179 $outstr .= ' { dataField: "HeatUse", lineWidth: 1, displayText: "Heat %", opacity: 0.3 }'.PHP_EOL; |
|
180 $outstr .= ' ]'.PHP_EOL; |
|
181 $outstr .= ' },'.PHP_EOL; |
|
182 $outstr .= ' {'.PHP_EOL; |
|
183 $outstr .= ' type: \'spline\','.PHP_EOL; |
|
184 $outstr .= ' valueAxis:'.PHP_EOL; |
|
185 $outstr .= ' {'.PHP_EOL; |
|
186 $outstr .= ' minValue: 0,'.PHP_EOL; |
|
187 $outstr .= ' description: \'Degrees C\''.PHP_EOL; |
|
188 $outstr .= ' },'.PHP_EOL; |
|
189 $outstr .= ' series: ['.PHP_EOL; |
|
190 $outstr .= ' { dataField: "Air", lineWidth: 1, displayText: "Air" },'.PHP_EOL; |
|
191 $outstr .= ' { dataField: "Beer", lineWidth: 2, displayText: "Beer" },'.PHP_EOL; |
|
192 $outstr .= ' { dataField: "Target_lo", lineWidth: 1, displayText: "Target Lo", opacity: 0.7 },'.PHP_EOL; |
|
193 $outstr .= ' { dataField: "Target_hi", lineWidth: 1, displayText: "Target Hi", opacity: 0.7 },'.PHP_EOL; |
|
194 $outstr .= ' { dataField: "Room", lineWidth: 1, displayText: "Room", opacity: 0.5 },'.PHP_EOL; |
|
195 $outstr .= ' { dataField: "Chiller", lineWidth: 1, displayText: "Chiller", color: \'#0000bb\' }'.PHP_EOL; |
|
196 $outstr .= ' ]'.PHP_EOL; |
|
197 $outstr .= ' }]'.PHP_EOL; |
|
198 $outstr .= ' };'.PHP_EOL; |
|
199 $outstr .= ' $("#fermentor_chart").jqxChart(settings);'.PHP_EOL; |
|
200 |
|
201 $outstr .= ' $("#print").click(function () {'.PHP_EOL; |
|
202 $outstr .= ' var content = $("#fermentor_chart")[0].outerHTML;'.PHP_EOL; |
|
203 $outstr .= ' var newWindow = window.open("", "", "width=865, height=425"),'.PHP_EOL; |
|
204 $outstr .= ' document = newWindow.document.open(),'.PHP_EOL; |
|
205 $outstr .= ' pageContent ='.PHP_EOL; |
|
206 $outstr .= ' \'<!DOCTYPE html>\' +'.PHP_EOL; |
|
207 $outstr .= ' \'<html>\' +'.PHP_EOL; |
|
208 $outstr .= ' \'<head>\' +'.PHP_EOL; |
|
209 $outstr .= ' \'<link rel="stylesheet" href="jqwidgets/styles/jqx.base.css" type="text/css" />\' +'.PHP_EOL; |
|
210 $outstr .= ' \'<meta charset="utf-8" />\' +'.PHP_EOL; |
|
211 $outstr .= ' \'<title>jQWidgets Chart</title>\' +'.PHP_EOL; |
|
212 $outstr .= ' \'</head>\' +'.PHP_EOL; |
|
213 $outstr .= ' \'<body>\' + content + \'</body></html>\';'.PHP_EOL; |
|
214 $outstr .= ' document.write(pageContent);'.PHP_EOL; |
|
215 $outstr .= ' document.close();'.PHP_EOL; |
|
216 $outstr .= ' newWindow.print();'.PHP_EOL; |
|
217 $outstr .= ' });'.PHP_EOL; |
|
218 $outstr .= ' $("#print").jqxButton({ width: 100, height: 25, theme: "ui-redmond" });'.PHP_EOL; |
|
219 |
|
220 $outstr .= ' $("#pdfButton").click(function () {'.PHP_EOL; |
|
221 $outstr .= ' $("#fermentor_chart").jqxChart("saveAsPDF", "Chart_'.$name.'.pdf", getExportServer());'.PHP_EOL; |
|
222 $outstr .= ' });'.PHP_EOL; |
|
223 $outstr .= ' $("#pdfButton").jqxButton({ width: 100, height: 25, theme: "ui-redmond" });'.PHP_EOL; |
|
224 |
|
225 $outstr .= ' });'.PHP_EOL; |
|
226 $outstr .= ' </script>'.PHP_EOL; |
|
227 $outstr .= ' <div id="fermentor">'.PHP_EOL; |
|
228 $outstr .= ' <div id="fermentor_chart" style="width:850px; height:410px; float:left"></div>'.PHP_EOL; |
|
229 $outstr .= ' <div style="margin-top: 2px; margin-left: 10px;">'.PHP_EOL; |
|
230 $outstr .= ' <input style="float: left; margin-left: 10px;" id="print" type="button" value="Print Graph" />'.PHP_EOL; |
|
231 $outstr .= ' <input style="float: left; margin-left: 10px; margin-top: 10px;" id="pdfButton" type="button" value="Save as PDF" />'.PHP_EOL; |
|
232 $outstr .= ' </div>'.PHP_EOL; |
|
233 $outstr .= ' </div> <!-- fermentor -->'.PHP_EOL; |
|
234 |
|
235 $outstr .= ' <script type="text/javascript">'.PHP_EOL; |
|
236 $outstr .= ' $(document).ready(function () {'.PHP_EOL; |
|
237 $outstr .= ' $("#archives").jqxButton({ width: 150, height: 25, theme: \'ui-redmond\' });'.PHP_EOL; |
|
238 $outstr .= ' });'.PHP_EOL; |
|
239 $outstr .= ' </script>'.PHP_EOL; |
|
240 $outstr .= build_footer(); |
|
241 echo $outstr; |
|
242 } |
|
243 |
|
244 |
|
245 |
|
246 /* |
|
247 * Download popup. The file contents is dynamic generated from |
|
248 * the thermferm server. |
|
249 */ |
|
250 function archive_dl() { |
|
251 |
|
252 $name = urldecode($_GET['name']) . ".log"; |
|
253 |
|
254 header('Content-Type: text/plain'); |
|
255 header('Content-Disposition: attachment; filename="'.$name.'"'); |
|
256 |
|
257 $answer = send_cmd('ARCHIVE GET '.$name); |
|
258 $arr = explode("\r\n", $answer); |
|
259 |
|
260 $outstr = ''; |
|
261 if (startsWith($arr[0], "212")) { |
|
262 $j = 1; |
|
263 while (1) { |
|
264 if (strcmp($arr[$j], ".") == 0) |
|
265 break; |
|
266 $outstr .= $arr[$j].PHP_EOL; |
|
267 $j++; |
|
268 } |
|
269 } |
|
270 echo $outstr; |
|
271 exit(); |
|
272 } |
|
273 |
|
274 |
|
275 |
|
276 /* |
|
277 * Show directory |
|
278 */ |
|
279 function archive_dir() { |
|
280 |
|
281 $answer = send_cmd("ARCHIVE DIR"); |
|
282 $reply = explode("\r\n", $answer); |
|
283 |
|
284 $outstr = build_header("Archived logfiles"); |
|
285 $outstr .= ' <div id="errors">'.PHP_EOL; |
|
286 $outstr .= ' </div> <!-- errors -->'.PHP_EOL; |
|
287 $outstr .= ' <div id="etable">'.PHP_EOL; |
|
288 $outstr .= ' <table class="setup">'.PHP_EOL; |
|
289 $outstr .= ' <tr class="trhead">'.PHP_EOL; |
|
290 $outstr .= ' <td class="setup" style="width: 340px;">File name</td>'.PHP_EOL; |
|
291 $outstr .= ' <td class="setup" style="width: 90px;">Mode</td>'.PHP_EOL; |
|
292 $outstr .= ' <td class="setup" style="width: 100px;">Size</td>'.PHP_EOL; |
|
293 $outstr .= ' <td class="setup" style="width: 140px;">Date</td>'.PHP_EOL; |
|
294 $outstr .= ' <td class="setup" style="width: 110px;">Action</td>'.PHP_EOL; |
|
295 $outstr .= ' </tr>'.PHP_EOL; |
|
296 |
|
297 if (startsWith($reply[0], "212")) { |
|
298 $j = 1; |
|
299 while (1) { |
|
300 if (strcmp($reply[$j], ".") == 0) |
|
301 break; |
|
302 $f = explode(",", $reply[$j]); |
|
303 $name = urlencode(basename($f[0], ".log")); |
|
304 $outstr .= ' <tr class="setup">'.PHP_EOL; |
|
305 $outstr .= ' <td class="setup">'.$f[0].'</td>'.PHP_EOL; |
|
306 $outstr .= ' <td class="setup">'.$f[1].'</td>'.PHP_EOL; |
|
307 $outstr .= ' <td class="setup">'.$f[2].'</td>'.PHP_EOL; |
|
308 $outstr .= ' <td class="setup">'.$f[3].'</td>'.PHP_EOL; |
|
309 $outstr .= ' <td class="setup"><a href="archives.php?action=dl&name='.$name.'">Download</a>'; |
|
310 $outstr .= ' <a href="archives.php?action=view&return=archives&name='.$name.'">View</a></td>'.PHP_EOL; |
|
311 $outstr .= ' </tr>'.PHP_EOL; |
|
312 $j++; |
|
313 } |
|
314 } |
|
315 |
|
316 $outstr .= ' </table>'.PHP_EOL; |
|
317 $outstr .= ' </div> <!-- etable -->'.PHP_EOL; |
|
318 $outstr .= ' <script type="text/javascript">'.PHP_EOL; |
|
319 $outstr .= ' $(document).ready(function () {'.PHP_EOL; |
|
320 $outstr .= ' $("#maintenance").jqxButton({ width: 150, height: 25, theme: \'ui-redmond\' });'.PHP_EOL; |
|
321 $outstr .= ' });'.PHP_EOL; |
|
322 $outstr .= ' </script>'.PHP_EOL; |
|
323 $outstr .= build_footer(); |
|
324 echo $outstr; |
|
325 } |
|
326 |
|
327 |
|
328 |
|