source: openweather/openweather.module @ 103

Revision 103, 12.4 KB checked in by nigel, 5 years ago (diff)
  • fixed admin form
Line 
1<?php
2// $Id: openweather.module,v 1.195 2006/04/14 09:05:19 killes Exp $
3
4/**
5 * @file
6 * Enables your site to capture votes on different topics in the form of multiple
7 * choice questions.
8 */
9
10
11/**
12 * Implementation of hook_help().
13 */
14function openweather_help($section) {
15  switch ($section) {
16    case 'admin/help#openweather':
17      $output = '<p>'. t('Openweather logs and graphs weather station readings from open2300 compatible stations.').'</p>';
18      return $output;
19    case 'admin/modules#description':
20      return t("Open2300 weather station logger.");
21    case 'node/add#openweather':
22      return t("Add a new weather station to monitor.");
23  }
24}
25
26/**
27 * Implementation of hook_perm().
28 */
29function openweather_perm() {
30  return array('create weather station');
31}
32
33/**
34 * Implementation of hook_access().
35 */
36function openweather_access($op, $node) {
37  if ($op == 'create') {
38    return user_access('create weather station');
39  }
40}
41
42/**
43 * Implementation of hook_block().
44 *
45 * Generates a block containing the latest poll.
46 */
47function openweather_block($op = 'list', $delta = 0) {
48}
49
50/**
51 * Implementation of hook_delete().
52 */
53function openweather_delete($node) {
54  db_query("DELETE FROM {openweather_readings} WHERE nid = %d", $node->nid);
55}
56
57/**
58 * Implementation of hook_form().
59 */
60function openweather_form(&$node) {
61 
62  $admin = user_access('administer nodes');
63
64  $form['title'] = array('#type' => 'textfield', '#title' => t('Station name'), '#required' => TRUE, '#default_value' => $node->title, '#weight' => -5);
65/*  $form['suburb'] = array('#type' => 'textfield', '#title' => t('Suburb'), '#required' => TRUE, '#default_value' => "", '#weight' => -5);
66  $form['lat'] = array('#type' => 'textfield', '#title' => t('Latitude'), '#required' => TRUE, '#default_value' => $node->title, '#weight' => -5);
67  $form['long'] = array('#type' => 'textfield', '#title' => t('Longitude'), '#required' => TRUE, '#default_value' => $node->title, '#weight' => -5);
68*/
69  return $form;
70}
71
72/**
73 * Implementation of hook_menu().
74 */
75function openweather_menu($may_cache) {
76  $items = array();
77
78  if ($may_cache) {
79    $items[] = array('path' => 'node/add/openweather', 'title' => t('weather station'),
80      'access' => user_access('create weather station'));
81    $items[] = array('path' => 'openweather', 'title' => t('openweather stations'),
82      'callback' => 'openweather_page',
83      'access' => user_access('access content'),
84      'type' => MENU_SUGGESTED_ITEM);
85
86    $items[] = array('path' => 'admin/settings/openweather',
87          'title' => t('openweather'),
88          'callback' => 'drupal_get_form',
89          'callback arguments' => 'openweather_admin_settings',
90          'access' => user_access('administer site configuration'),
91          'type' => MENU_CALLBACK);
92 
93  }
94  else {
95    if (arg(0) == 'node' && is_numeric(arg(1))) {
96      $node = node_load(arg(1));
97      if ($node->type == 'openweather'){
98        $items[] = array('path' => 'node/'. arg(1) .'/csv_readings',
99          'title' => t('readings'),
100          'callback' => 'openweather_csv_readings',
101          'access' => user_access('access content'),
102          'weight' => 3,
103          'type' => MENU_LOCAL_TASK);
104
105        $items[] = array('path' => 'node/'. arg(1) .'/graph',
106          'title' => t('graph'),
107          'callback' => 'openweather_graph',
108          'access' => user_access('access content'),
109          'weight' => 3,
110          'type' => MENU_CALLBACK);
111
112      }
113    }
114  }
115
116  return $items;
117}
118
119function openweather_link($type, $node=0, $main=0){
120  if ($type == 'node' && $node->type == 'openweather'){
121    $links = module_invoke_all('openweather', 'node', $node, 1);
122    $links[] = array('title'=>t('export readings'), 'href'=>'node/'.$node->nid.'/csv_readings','attributes'=>array('title'=>'Export the openweather readings as CSV'));
123  }
124  return $links;
125}
126
127
128/**
129 * Implementation of hook_node_info().
130 */
131function openweather_node_info() {
132  return array(
133    'openweather' => array(
134      'name' => t("openweather"),
135      'base' => 'openweather',
136      'module' => 'openweather',
137      ));
138}
139
140/**
141 * _page hook
142 * Display official stats, and a list of weather stations w/ stats
143 */
144function openweather_page() {
145  global $user;
146
147  $output = '';
148
149  // If there is official weather get it
150  $radarURL = variable_get('openweather_radar', null);
151  if ($radarURL != null) $output .= "<img src='$radarURL'/>";
152
153  if (module_exists("weather")){
154    $b = weather_block('view');
155    $output .= $b['content'];
156    }
157
158  // List all of my openweathers by category
159  $sql = "SELECT n.nid, n.title FROM {node} n WHERE n.type='openweather'";
160
161  $result = db_query($sql);
162  $output .= '<ul>';
163  while ($node = db_fetch_object($result)) {
164    $output .= '<li>'. l($node->title, "node/$node->nid").openweather_summary($node->nid) .'</li>';
165  }
166  $output .= '</ul>';
167  $output .= theme("pager", NULL, 15);
168  return $output;
169}
170
171function openweather_admin_settings() {
172  $form['openweather_radar'] = array(
173    '#type'=>'textfield',
174    '#title'=>t('URL for weather radar'),
175    '#default_value'=>variable_get('openweather_radar', ''));
176
177  return system_settings_form($form);
178}
179
180
181/**
182 * Creates a simple teaser that lists all the choices.
183 */
184function openweather_teaser($node) {
185  $teaser = NULL;
186  if (is_array($node->choice)) {
187    foreach ($node->choice as $k => $choice) {
188      $teaser .= '* '. $choice['chtext'] .'\n';
189    }
190  }
191  return $teaser;
192}
193
194function openweather_to_direction($angle){
195  if ($angle < 11.25)
196    return 'N';
197  else if ($angle < 33.75)
198    return 'NNE';
199  else if ($angle < 56.25)
200    return 'NE';
201  else if ($angle < 78.75)
202    return 'ENE';
203  else if ($angle < 101.25)
204    return 'E';
205  else if ($angle < 123.75)
206    return 'ESE';
207  else if ($angle < 146.25)
208    return 'SE';
209  else if ($angle < 168.75)
210    return 'SSE';
211  else if ($angle < 191.25)
212    return 'S';
213  else if ($angle < 213.75)
214    return 'SSW';
215  else if ($angle < 236.25)
216    return 'SW';
217  else if ($angle < 258.75)
218    return 'WSW';
219  else if ($angle < 281.25)
220    return 'W';
221  else if ($angle < 303.75)
222    return 'WNW';
223  else if ($angle < 326.25)
224    return 'NW';
225  else if ($angle < 348.75)
226    return 'NNW';
227  else
228    return 'N';
229}
230
231/**
232 * Gets (and caches) the latest readings
233 */
234function openweather_get_latest($nid){
235  static $cache = array();
236  if (array_key_exists($nid,$cache))
237    return $cache[$nid];
238  else {
239    $data = db_query("SELECT * FROM {openweather_readings} WHERE nid = $nid ORDER BY `timestamp` DESC LIMIT 1");
240    $data = db_fetch_object($data);
241    $cache[$nid] = $data;
242    return $data;
243  }
244}
245
246
247/**
248  * Summary table of weather station feed
249  */
250function openweather_summary($nid){
251  $data = openweather_get_latest($nid);
252
253  $output .= "<table>";
254  $output .= "<tr><th>Temperature</th><td>$data->temp_out &#176;C</td><th>Humidity</th><td>$data->rel_hum_out %</td></tr>";
255  $output .= "<tr><th>Wind speed</th><td>$data->windspeed kmh</td><th>Wind direction</th><td>".openweather_to_direction($data->wind_angle)."($data->wind_angle &#176;)</td></tr>";
256  $output .= "<tr><th>Relative pressure</th><td>$data->rel_pressure</td><th>Timestamp</th><td>$data->timestamp</td></tr>";
257  $output .= "</table>";
258  return $output;
259}
260
261/**
262 * Implementation of hook_view().
263 *
264 * @param $block
265 */
266function openweather_view($node, $teaser = FALSE, $page = FALSE, $block = FALSE) {
267  global $user;
268  $node->content['summary'] = array('#weight'=>0,
269    '#value'=>openweather_summary($node->nid));
270
271  $node->content['graphs'] =  array('#weight'=>1,
272    '#value'=>"<img src='?q=node/".$node->nid."/graph/temp_out' />".
273        "<img src='?q=node/".$node->nid."/graph/rel_hum_out' />".
274        "<img src='?q=node/".$node->nid."/graph/rel_pressure' />".
275        "<img src='?q=node/".$node->nid."/graph/windspeed' />");
276
277  return $node;
278}
279
280/**
281  * Export the openweather readings as a CSV file
282  */
283function openweather_csv_readings() {
284  $nid = arg(1);
285  $node = node_load($nid);
286  drupal_set_header('Content-Type: text/csv; charset=utf-8');
287  drupal_set_header('Content-Disposition: attachment; filename="openweather.csv";');
288  print "Time, temp_out, rel_hum_out, windspeed, wind_angle, wind_chill, rain_1h, rel_pressure, dewpoint\n";
289 
290  $results = db_query("SELECT * FROM {openweather_readings} WHERE nid = %d ORDER BY timestamp DESC", $node->nid);
291  while ($row = db_fetch_object($results)){
292    print "$row->timestamp, $row->temp_out, $row->rel_hum_out, $row->windspeed, $row->wind_angle, $row->wind_chill, $row->rain_1h, $row->rel_pressure, $row->dewpoint\n";
293  }
294}
295
296/**
297  * Query the DB for the reading values
298  */
299function openweather_get_values($node){
300  $res = array();
301  $results = db_query("SELECT * FROM {openweather_readings} WHERE nid = %d ORDER BY timestamp DESC", $node->nid);
302
303  while ($row = db_fetch_object($results)){
304    $res[] = $row;
305  }
306  return $res;
307}
308
309/**
310 * Implementation of hook_user().
311 */
312function openweather_user($op, &$edit, &$user) {
313  if ($op == 'delete') {
314    db_query('UPDATE {openweather_readings} SET uid = 0 WHERE uid = %d', $user->uid);
315  }
316}
317
318function openweather_xmlrpc(){
319  return array(
320    array(
321      'openweather.addEntry',
322      'openweather_add_entry',
323      array('boolean','string','string', 'string', 'struct'),
324      t('Add data entry from remote device'),
325    ),
326  );
327}
328
329/*
330 * timestamp
331 * temp_in
332 * temp_out
333 * rel_hum_in
334 * rel_hum_out
335 * windspeed
336 * wind_angle
337 * wind_chill
338 * rain_1h
339 * rel_pressure
340 * dewpoint
341 */
342function openweather_add_entry($nid, $username, $password, $data){
343  $user = user_authenticate($username, $password);
344
345  if ($user->uid) {
346    $node = node_load($nid);
347    if ($node->type != 'openweather')
348        return false;
349    // Check person owns or can write to entry
350
351    return db_query("INSERT INTO {openweather_readings} (nid, `timestamp`, temp_out, rel_hum_out, windspeed, wind_angle, wind_chill, rain_1h, rel_pressure, dewpoint, rain_total) VALUES (%d, '%s', %s, %s, %s, %s, %s, %s, %s, %s, %s)", $nid, $data['timestamp'], $data['temp'], $data['rel_hum'], $data['windspeed'], $data['wind_angle'], $data['wind_chill'], $data['rain_1h'], $data['rel_pressure'], $data['dewpoint'], $data['rain_total']);
352  } else {
353    return false;
354  }
355}
356
357/**
358  * Produce a PNG graph of the $type data for the last 24 hours
359  */
360function openweather_graph() {
361  $nid = arg(1);
362  $type = arg(3);
363  $node = node_load($nid);
364  $title = '';
365  $units = '';
366  $autoScale = false;
367  $decimals = 0;
368
369  switch ($type){
370  case null:
371  case 'temp_out':
372    $type = 'temp_out';
373    $title = t("Outdoor temperature");
374    $autoScale = true;
375    $units = 'deg C';
376    $decimals = 1;
377    break;
378 
379  case 'rel_pressure':
380    $title = t("Relative pressure");
381    $units = 'hpa';
382    $autoScale = true;
383    break;
384 
385  case 'rel_hum_out':
386    $title = t("Outdoor relative humidity");
387    $autoScale = true;
388    $units = '%';
389    break;
390
391  case 'windspeed':
392    $title = t("Windspeed");
393    $autoScale = false;
394    $units = 'kmh';
395    $decimals = 1;
396    break;
397
398  case 'rain_1h':
399    $title = t("Rainfall in previous hour");
400    $autoScale = false;
401    $units = 'mm';
402    $decimals = 1;
403    break;
404
405  case 'rain_total':
406    $title = t("Rainfall total");
407    $autoScale = false;
408    $units = 'mm';
409    $decimals = 1;
410    break;
411
412  default:
413    return;
414  }
415
416  $data = openweather_get_latest($nid);
417
418  $r = db_query("SELECT time(`timestamp`) AS `timevalue`, unix_timestamp(`timestamp`) as `utimestamp`, $type FROM {openweather_readings} WHERE nid = $nid AND unix_timestamp(timestamp) > ".(strtotime($data->timestamp)-24*60*60)." ORDER BY `timestamp` DESC LIMIT 500" );
419
420  drupal_set_header('Content-Type: image/png');
421  include 'graph.php';
422  $g = new graph(400, 240);
423  $g->parameter['path_to_fonts'] = 'modules/openweather/fonts/';
424  $g->parameter['title'] = $title;
425  $g->parameter['x_label'] = 'Time';
426  $g->parameter['y_label_left'] = $units;
427  $g->parameter['y_decimal_left'] = $decimals;
428
429  $g->parameter['x_axis_text'] = 12;
430
431  $g->x_data = array();
432  $g->y_data = array( $type=>array() );
433  $minY = null;
434  $count = 0;
435  while ($e = db_fetch_object($r)) {
436    $count++;
437    $g->x_data = array_merge($g->x_data, array($e->timevalue=>$e->utimestamp));
438    $g->y_data[$type][] = $e->$type;
439    if ($minY == null || $e->$type < $minY) $minY = $e->$type;
440  }
441  $g->x_data = array_reverse($g->x_data);
442  $g->y_data[$type] = array_reverse($g->y_data[$type]);
443
444  $g->y_format[$type] = array('colour'=>'red', 'line'=>'brush', 'brush_size'=>2);
445  $g->y_order = array($type);
446
447  if ($autoScale) $g->parameter['y_min_left'] = $minY;
448
449  $g->parameter['x_axis_text'] = $count/12;
450 
451  $g->draw();
452}
Note: See TracBrowser for help on using the repository browser.