'. 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 .= '';
while ($node = db_fetch_object($result)) {
$output .= '- '. l($node->title, "node/$node->nid").openweather_summary($node->nid) .'
';
}
$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 .= "| Temperature | $data->temp_out °C | Humidity | $data->rel_hum_out % |
";
$output .= "| Wind speed | $data->windspeed kmh | Wind direction | ".openweather_to_direction($data->wind_angle)."($data->wind_angle °) |
";
$output .= "| Relative pressure | $data->rel_pressure | Timestamp | $data->timestamp |
";
$output .= "
";
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();
}