'. t('Openweather logs and graphs weather station readings from open2300 compatible stations.').'

'; return $output; case 'admin/modules#description': return t("Open2300 weather station logger."); case 'node/add#openweather': return t("Add a new weather station to monitor."); } } /** * Implementation of hook_perm(). */ function openweather_perm() { return array('create weather station'); } /** * Implementation of hook_access(). */ function openweather_access($op, $node) { if ($op == 'create') { return user_access('create weather station'); } } /** * Implementation of hook_block(). * * Generates a block containing the latest poll. */ function openweather_block($op = 'list', $delta = 0) { } /** * Implementation of hook_delete(). */ function openweather_delete($node) { db_query("DELETE FROM {openweather_readings} WHERE nid = %d", $node->nid); } /** * Implementation of hook_form(). */ function openweather_form(&$node) { $admin = user_access('administer nodes'); $form['title'] = array('#type' => 'textfield', '#title' => t('Station name'), '#required' => TRUE, '#default_value' => $node->title, '#weight' => -5); /* $form['suburb'] = array('#type' => 'textfield', '#title' => t('Suburb'), '#required' => TRUE, '#default_value' => "", '#weight' => -5); $form['lat'] = array('#type' => 'textfield', '#title' => t('Latitude'), '#required' => TRUE, '#default_value' => $node->title, '#weight' => -5); $form['long'] = array('#type' => 'textfield', '#title' => t('Longitude'), '#required' => TRUE, '#default_value' => $node->title, '#weight' => -5); */ return $form; } /** * Implementation of hook_menu(). */ function openweather_menu($may_cache) { $items = array(); if ($may_cache) { $items[] = array('path' => 'node/add/openweather', 'title' => t('weather station'), 'access' => user_access('create weather station')); $items[] = array('path' => 'openweather', 'title' => t('openweather stations'), 'callback' => 'openweather_page', 'access' => user_access('access content'), 'type' => MENU_SUGGESTED_ITEM); $items[] = array('path' => 'admin/settings/openweather', 'title' => t('openweather'), 'callback' => 'drupal_get_form', 'callback arguments' => 'openweather_admin_settings', 'access' => user_access('administer site configuration'), 'type' => MENU_CALLBACK); } else { if (arg(0) == 'node' && is_numeric(arg(1))) { $node = node_load(arg(1)); if ($node->type == 'openweather'){ $items[] = array('path' => 'node/'. arg(1) .'/csv_readings', 'title' => t('readings'), 'callback' => 'openweather_csv_readings', 'access' => user_access('access content'), 'weight' => 3, 'type' => MENU_LOCAL_TASK); $items[] = array('path' => 'node/'. arg(1) .'/graph', 'title' => t('graph'), 'callback' => 'openweather_graph', 'access' => user_access('access content'), 'weight' => 3, 'type' => MENU_CALLBACK); } } } return $items; } function openweather_link($type, $node=0, $main=0){ if ($type == 'node' && $node->type == 'openweather'){ $links = module_invoke_all('openweather', 'node', $node, 1); $links[] = array('title'=>t('export readings'), 'href'=>'node/'.$node->nid.'/csv_readings','attributes'=>array('title'=>'Export the openweather readings as CSV')); } return $links; } /** * Implementation of hook_node_info(). */ function openweather_node_info() { return array( 'openweather' => array( 'name' => t("openweather"), 'base' => 'openweather', 'module' => 'openweather', )); } /** * _page hook * Display official stats, and a list of weather stations w/ stats */ function openweather_page() { global $user; $output = ''; // If there is official weather get it $radarURL = variable_get('openweather_radar', null); if ($radarURL != null) $output .= ""; if (module_exists("weather")){ $b = weather_block('view'); $output .= $b['content']; } // List all of my openweathers by category $sql = "SELECT n.nid, n.title FROM {node} n WHERE n.type='openweather'"; $result = db_query($sql); $output .= ''; $output .= theme("pager", NULL, 15); return $output; } function openweather_admin_settings() { $form['openweather_radar'] = array( '#type'=>'textfield', '#title'=>t('URL for weather radar'), '#default_value'=>variable_get('openweather_radar', '')); return system_settings_form($form); } /** * Creates a simple teaser that lists all the choices. */ function openweather_teaser($node) { $teaser = NULL; if (is_array($node->choice)) { foreach ($node->choice as $k => $choice) { $teaser .= '* '. $choice['chtext'] .'\n'; } } return $teaser; } function openweather_to_direction($angle){ if ($angle < 11.25) return 'N'; else if ($angle < 33.75) return 'NNE'; else if ($angle < 56.25) return 'NE'; else if ($angle < 78.75) return 'ENE'; else if ($angle < 101.25) return 'E'; else if ($angle < 123.75) return 'ESE'; else if ($angle < 146.25) return 'SE'; else if ($angle < 168.75) return 'SSE'; else if ($angle < 191.25) return 'S'; else if ($angle < 213.75) return 'SSW'; else if ($angle < 236.25) return 'SW'; else if ($angle < 258.75) return 'WSW'; else if ($angle < 281.25) return 'W'; else if ($angle < 303.75) return 'WNW'; else if ($angle < 326.25) return 'NW'; else if ($angle < 348.75) return 'NNW'; else return 'N'; } /** * Gets (and caches) the latest readings */ function openweather_get_latest($nid){ static $cache = array(); if (array_key_exists($nid,$cache)) return $cache[$nid]; else { $data = db_query("SELECT * FROM {openweather_readings} WHERE nid = $nid ORDER BY `timestamp` DESC LIMIT 1"); $data = db_fetch_object($data); $cache[$nid] = $data; return $data; } } /** * Summary table of weather station feed */ function openweather_summary($nid){ $data = openweather_get_latest($nid); $output .= ""; $output .= ""; $output .= ""; $output .= ""; $output .= "
Temperature$data->temp_out °CHumidity$data->rel_hum_out %
Wind speed$data->windspeed kmhWind direction".openweather_to_direction($data->wind_angle)."($data->wind_angle °)
Relative pressure$data->rel_pressureTimestamp$data->timestamp
"; return $output; } /** * Implementation of hook_view(). * * @param $block */ function openweather_view($node, $teaser = FALSE, $page = FALSE, $block = FALSE) { global $user; $node->content['summary'] = array('#weight'=>0, '#value'=>openweather_summary($node->nid)); $node->content['graphs'] = array('#weight'=>1, '#value'=>"". "". "". ""); return $node; } /** * Export the openweather readings as a CSV file */ function openweather_csv_readings() { $nid = arg(1); $node = node_load($nid); drupal_set_header('Content-Type: text/csv; charset=utf-8'); drupal_set_header('Content-Disposition: attachment; filename="openweather.csv";'); print "Time, temp_out, rel_hum_out, windspeed, wind_angle, wind_chill, rain_1h, rel_pressure, dewpoint\n"; $results = db_query("SELECT * FROM {openweather_readings} WHERE nid = %d ORDER BY timestamp DESC", $node->nid); while ($row = db_fetch_object($results)){ 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"; } } /** * Query the DB for the reading values */ function openweather_get_values($node){ $res = array(); $results = db_query("SELECT * FROM {openweather_readings} WHERE nid = %d ORDER BY timestamp DESC", $node->nid); while ($row = db_fetch_object($results)){ $res[] = $row; } return $res; } /** * Implementation of hook_user(). */ function openweather_user($op, &$edit, &$user) { if ($op == 'delete') { db_query('UPDATE {openweather_readings} SET uid = 0 WHERE uid = %d', $user->uid); } } function openweather_xmlrpc(){ return array( array( 'openweather.addEntry', 'openweather_add_entry', array('boolean','string','string', 'string', 'struct'), t('Add data entry from remote device'), ), ); } /* * timestamp * temp_in * temp_out * rel_hum_in * rel_hum_out * windspeed * wind_angle * wind_chill * rain_1h * rel_pressure * dewpoint */ function openweather_add_entry($nid, $username, $password, $data){ $user = user_authenticate($username, $password); if ($user->uid) { $node = node_load($nid); if ($node->type != 'openweather') return false; // Check person owns or can write to entry 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']); } else { return false; } } /** * Produce a PNG graph of the $type data for the last 24 hours */ function openweather_graph() { $nid = arg(1); $type = arg(3); $node = node_load($nid); $title = ''; $units = ''; $autoScale = false; $decimals = 0; switch ($type){ case null: case 'temp_out': $type = 'temp_out'; $title = t("Outdoor temperature"); $autoScale = true; $units = 'deg C'; $decimals = 1; break; case 'rel_pressure': $title = t("Relative pressure"); $units = 'hpa'; $autoScale = true; break; case 'rel_hum_out': $title = t("Outdoor relative humidity"); $autoScale = true; $units = '%'; break; case 'windspeed': $title = t("Windspeed"); $autoScale = false; $units = 'kmh'; $decimals = 1; break; case 'rain_1h': $title = t("Rainfall in previous hour"); $autoScale = false; $units = 'mm'; $decimals = 1; break; case 'rain_total': $title = t("Rainfall total"); $autoScale = false; $units = 'mm'; $decimals = 1; break; default: return; } $data = openweather_get_latest($nid); $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" ); drupal_set_header('Content-Type: image/png'); include 'graph.php'; $g = new graph(400, 240); $g->parameter['path_to_fonts'] = 'modules/openweather/fonts/'; $g->parameter['title'] = $title; $g->parameter['x_label'] = 'Time'; $g->parameter['y_label_left'] = $units; $g->parameter['y_decimal_left'] = $decimals; $g->parameter['x_axis_text'] = 12; $g->x_data = array(); $g->y_data = array( $type=>array() ); $minY = null; $count = 0; while ($e = db_fetch_object($r)) { $count++; $g->x_data = array_merge($g->x_data, array($e->timevalue=>$e->utimestamp)); $g->y_data[$type][] = $e->$type; if ($minY == null || $e->$type < $minY) $minY = $e->$type; } $g->x_data = array_reverse($g->x_data); $g->y_data[$type] = array_reverse($g->y_data[$type]); $g->y_format[$type] = array('colour'=>'red', 'line'=>'brush', 'brush_size'=>2); $g->y_order = array($type); if ($autoScale) $g->parameter['y_min_left'] = $minY; $g->parameter['x_axis_text'] = $count/12; $g->draw(); }