Обработка "полупустых" записей только с типом и ID датчика - актуально для сенсоров...
[weathermon.git] / web / image_minmax.php
1 <?php // content="text/plain; charset=utf-8"
2
3 error_reporting(E_ALL & ~E_STRICT & ~E_NOTICE);
4
5 include ('config_local.php');
6
7 require_once ('jpgraph/jpgraph.php');
8 require_once ('jpgraph/jpgraph_line.php');
9 require_once ('jpgraph/jpgraph_date.php');
10 require_once ('jpgraph/jpgraph_scatter.php');
11 require_once ('jpgraph/jpgraph_regstat.php');
12
13 if (! ($db = new PDO("mysql:host=$mysql_host;port=$mysql_port;dbname=$mysql_schema",$mysql_user,$mysql_pwd,array( PDO::ATTR_PERSISTENT => false)))) {
14
15   die('Не могу подключиться к БД');
16
17 }  
18
19 $supported = imagetypes();
20 if( $supported & IMG_PNG )    $img_format="png";
21 elseif( $supported & IMG_GIF ) $img_format="gif";
22 elseif( $supported & IMG_JPG ) $img_format="jpeg";
23 elseif( $supported & IMG_WBMP ) $img_format="wbmp";
24 elseif( $supported & IMG_XPM ) $img_format="xpm";
25
26 $cachefilename = NULL;
27
28 $db -> exec('SET CHARACTER SET utf8');
29   
30 $type = $_REQUEST['type'];
31 $sensor=$_REQUEST['sensor'];
32 $param=$_REQUEST['param'];
33 $year=$_REQUEST['year'];
34 $month=$_REQUEST['month'];
35
36 if ($type and $param) {
37   
38   $sensor = intval($sensor);
39   $param = intval($param);
40
41   $q = $db -> prepare(
42     'select s_description from sensors where id='.$sensor
43   );
44   $q -> execute();
45
46   while ($row = $q -> fetch(PDO::FETCH_ASSOC)) {
47     $sensor_name = $row['s_description'];
48   }                                                                
49
50   $q = $db -> prepare(
51     'select st.st_fill_color_top,st.st_fill_color_bottom,st.st_description,u.id,u.unit_group from st_parameters st,units u where st.id='.$param.' and st.st_unit=u.id'
52   );
53   $q -> execute();
54
55   while ($row = $q -> fetch(PDO::FETCH_ASSOC)) {
56     $param_name = $row['st_description'];
57     $from_unit = $row['id'];
58     $unit_group = $row['unit_group'];
59     $fill_color_top=$row['st_fill_color_top'];
60     $fill_color_bottom=$row['st_fill_color_bottom'];
61   }                                                                
62
63   if (!empty($_COOKIE['unit_'.$unit_group])) {
64     $to_unit=intval($_COOKIE['unit_'.$unit_group]);
65   } else {
66     $to_unit=$from_unit;
67   }  
68
69   $q = $db -> prepare(
70     'select u.name_short from units u where u.id='.$to_unit
71   );
72   $q -> execute();
73
74   while ($row = $q -> fetch(PDO::FETCH_ASSOC)) {
75     $param_unit = $row['name_short'];
76   }                     
77   
78   $xdata = array();
79   $ydata = array();
80
81   if ($type == 'month') { 
82
83     $next_year = $year;
84     $next_month = $month+1;
85
86     if ($month==12) {
87     
88       $next_year++;
89       $next_month=1;
90
91     }
92
93     $curr = date("Ym");
94     $ym=sprintf('%04d%02d',$next_year,$next_month);
95     
96     if ($curr>$ym) {
97     
98       $cachefilename='meteo.month.'.$sensor.'.'.$param.'.'.$to_unit.'.'.$year.'-'.$month.'.'.$img_format;
99     
100     }
101
102     $datestr=sprintf("%04d%02d01",$year,$month);
103     $nextdatestr=sprintf("%04d%02d01",$next_year,$next_month);
104
105     $q = $db -> prepare(
106      '
107         select 
108           x,
109           unitconv(min(min),'.$from_unit.','.$to_unit.') min_value,
110           unitconv(max(max),'.$from_unit.','.$to_unit.') max_value
111         from  (
112           select 
113             unix_timestamp(day) x,
114             min,
115             max
116           from 
117             sensors_ranges 
118           where 
119             day>=STR_TO_DATE(\''.$datestr.'\',\'%Y%m%d\')
120             and day<STR_TO_DATE(\''.$nextdatestr.'\',\'%Y%m%d\')
121             and sensor='.$sensor.'
122             and parameter='.$param.'
123           ) t group by x
124         order by x'
125     );
126
127   } elseif ($type == "year") {
128
129     $next_year = $year+1;
130
131     $curr = date("Y");
132         
133     if ($curr>$next_year) {
134                 
135         $cachefilename='meteo.year.'.$sensor.'.'.$param.'.'.$year.'.'.$img_format;
136                           
137     }
138
139     $datestr=sprintf("%04d0101",$year);
140     $nextdatestr=sprintf("%04d0101",$next_year);
141
142     $q = $db -> prepare(
143       '
144         select 
145           x,
146           unitconv(min(min),'.$from_unit.','.$to_unit.') min_value,
147           unitconv(max(max),'.$from_unit.','.$to_unit.') max_value
148         from  (
149           select 
150             unix_timestamp(
151               DATE_SUB(day, INTERVAL DAYOFWEEK(day)-1 DAY)
152               ) x,
153             min,
154             max
155           from 
156             sensors_ranges
157           where 
158             day>=STR_TO_DATE(\''.$datestr.'\',\'%Y%m%d\')
159             and day<STR_TO_DATE(\''.$nextdatestr.'\',\'%Y%m%d\')
160             and sensor='.$sensor.'
161             and parameter='.$param.'
162           ) t group by x
163         order by x'
164     );
165   
166   }
167
168   $g = new Graph(640,480);
169
170   if ($cachefilename) {
171       if ($g->cache->IsValid($cachefilename)) {
172   
173           $g->cache->StreamImgFile($g->img,$cachefilename);
174           return;
175   
176       } else {
177   
178           $timeout = 8640000;
179           $g->SetupCache($cachefilename,$timeout);
180
181       }
182   }
183
184
185   $q -> execute();
186     
187   while ($row = $q -> fetch(PDO::FETCH_ASSOC)) {
188     
189     $xdata[] = $row['x'];
190     $mindata[] = $row['min_value'];
191     $maxdata[] = $row['max_value'];
192     
193   }                                                                
194
195   // Create the graph
196   $g->graph_theme = null;
197
198   //$g->img->SetAntiAliasing();
199
200   // We need a linlin scale since we provide both
201   // x and y coordinates for the data points.
202   $g->SetScale('datlin');
203   $g->xaxis->SetLabelAngle(90);
204   $g->xaxis->SetPos("min");
205   $g->xaxis->scale->SetTimeAlign( MINADJ_1 );
206
207   // We use a scatterplot to illustrate the original
208   // contro points.
209
210   $bplot = new LinePlot($maxdata,$xdata);
211   $g->Add($bplot);
212   $bplot->SetColor($fill_color_top);
213   $bplot->SetFillGradient($fill_color_top.'@0.2',$fill_color_bottom.'@0.9',100,TRUE);
214   $bplot->SetFillFromYMin(TRUE);        
215   $bplot->SetWeight(4);
216
217   $aplot = new LinePlot($mindata,$xdata);
218   $g->Add($aplot);
219   $aplot->SetColor($fill_color_bottom);
220   $aplot->SetFillGradient($fill_color_bottom.'@0.2','white@0.9',100,TRUE);
221   $aplot->SetFillFromYMin(TRUE);        
222   $aplot->SetWeight(4);
223
224   $g->SetMargin(60,60,60,130);
225   $g->title->Set($sensor_name.'/'.$param_name.', '.$param_unit);
226   $g->title->SetFont(FF_DV_SANSSERIF,FS_BOLD,12);
227   $g->subtitle->Set('(минимальные и максимальные значения за период)');
228   $g->subtitle->SetColor('darkred');
229   $g->SetMarginColor('silver');
230
231   $g->xgrid->Show();
232   $g->xgrid->SetLineStyle('dotted');
233   $g->ygrid->Show();
234   $g->ygrid->SetLineStyle('dotted');
235         
236   // Add the plots to the graph and stroke
237   $g->Stroke();
238   
239 } else {
240
241   header("Content-Type: text/html; charset=UTF-8");
242   die('Сенсор не выбран!');
243
244 }  
245
246 ?>