<?php
/*
NetAtmo to MySQL v. 0.1.8
Kyrre Baker @ 24.01.2017 04:55:12 | http://kyrrebaker.com/

Get data from your NetAtmo weather stations with PHP and display the array if
it's excecuted vie HTTP- or insert the data into MySQL if it's executed via CLI

Comment out line 12 before running the code. It's primarily here to make sure that
the code isn't executed if the server changes to execute .phps as .php
*/
die("Comment out line nr. 12 in the code before executing!");

// Userinfo for the MySQL server
    
$sql_servername "";
    
$sql_username "";
    
$sql_password "";
    
$sql_databasename "";

// Userinfo for the API
    
$app_id "";
    
$app_secret "";
    
$app_username "";
    
$app_password "";
    
$scope "read_station";

// Module names and types for reference
    // NAMain = Base station
    // NAModule1 = Outdoor module
    // NAModule2 = Wind gauge
    // NAModule3 = Rain gauge
    // NAModule4 = Optional indoor module

// MySQL dump for reference
    /*
    CREATE TABLE `weather_netatmo` (
      `ID` int(10) UNSIGNED NOT NULL,
      `update_time` datetime NOT NULL,
      `observation_time` varchar(128) DEFAULT NULL,
      `station_id` varchar(128) DEFAULT NULL,
      `temp` decimal(10,3) NOT NULL,
      `temp_min` decimal(10,3) NOT NULL,
      `temp_max` decimal(10,3) NOT NULL,
      `temp_trend` decimal(10,3) NOT NULL,
      `humidity` decimal(10,3) NOT NULL,
      `precip` decimal(10,3) NOT NULL,
      `precip_1` decimal(10,3) NOT NULL,
      `precip_24` decimal(10,3) NOT NULL,
      `wind` decimal(10,3) NOT NULL,
      `wind_gust` decimal(10,3) NOT NULL,
      `wind_angle` decimal(10,3) NOT NULL,
      `wind_gust_angle` decimal(10,3) NOT NULL,
      `wind_strength_max` decimal(10,3) NOT NULL,
      `pressure` decimal(10,3) NOT NULL,
      `pressure_trend` decimal(10,3) NOT NULL,
      `sunrise` varchar(5) DEFAULT NULL,
      `sunset` varchar(5) DEFAULT NULL,
      `battery_outdoor_module` decimal(10,3) NOT NULL,
      `battery_wind_gauge` decimal(10,3) NOT NULL,
      `battery_rain_gauge` decimal(10,3) NOT NULL
    ) ENGINE=MyISAM DEFAULT CHARSET=latin1;

    ALTER TABLE `weather_netatmo`
      ADD PRIMARY KEY (`ID`);

    ALTER TABLE `weather_netatmo`
      MODIFY `ID` int(10) UNSIGNED NOT NULL AUTO_INCREMENT;
    */

// Connects to the databaseserver
    
$sql mysqli_connect(
        
$sql_servername,
        
$sql_username,
        
$sql_password,
        
$sql_databasename
    
);

// Start API-code
    
$token_url "https://api.netatmo.net/oauth2/token";
    
$postdata http_build_query(
        array(
            
"grant_type" => "password",
            
"client_id" => $app_id,
            
"client_secret" => $app_secret,
            
"username" => $app_username,
            
"password" => $app_password,
            
"scope" => $scope
        
)
    );

    
$opts = array("http" =>
        array(
            
"method"  => "POST",
            
"header"  => "Content-type: application/x-www-form-urlencoded",
            
"content" => $postdata
        
)
    );

    
$context  stream_context_create($opts);

    
$response file_get_contents($token_urlfalse$context);
    
$params json_decode($responsetrue);

    
$api_url "https://api.netatmo.net/api/getstationsdata?access_token=".$params["access_token"];

    
$data file_get_contents($api_urlfalse);
    
$data json_decode($datatrue);

// All data is here, start private code
    
$devices $data["body"]["devices"];
    
$update_time date("Y-m-d H:i:s");

// Function to format date and time from standard UNIX timestamp
    
function format_datetime($string NULL) {
        return 
date("D, d M H:i:s O"$string);
    }

// Creates the station ID for separating data in the MySQL-tables
    
function format_create_station_id($string NULL) {
        return 
substr(metaphone($string), 03);
    }

// No negative values allowed
    
function format_nonegs($string NULL) {
        if (
preg_match("/\-/"$string)) {
            
$string "0";
        } else {
            return 
$string;
        }
    }

// Writes up, down and whatever as -1, 0 and 1
    
function format_directions_to_values($string NULL) {
        if (
$string == "up") {
            return 
"1";
        } elseif (
$string == "down") {
            return 
"-1";
        } else {
            return 
"0";
        }
    }

// Looks up sunrise / sunset from the coordinates given
    
function format_sunriseandset($way NULL$lat NULL$lon NULL) {
        
$zenith 90 + (50 60);
        
$gmtoffset date("Z") / 3600;
        if (
$way == "sunrise") {
            
$string date_sunrise(time(), SUNFUNCS_RET_STRING$lat$lon$zenith$gmtoffset);
        } elseif (
$way == "sunset") {
            
$string date_sunset(time(), SUNFUNCS_RET_STRING$lat$lon$zenith$gmtoffset);
        } else {
            
$string $lat.", ".$lon;
        }
        return 
$string;
    }

// Get info from the array() returned
    
foreach ($devices AS $device) {
        
// Nullify variables
        
$station_id NULL;
        
$observation_time NULL;
        
$temp NULL;
        
$temp_min NULL;
        
$temp_max NULL;
        
$temp_trend NULL;
        
$humidity NULL;
        
$precip NULL;
        
$precip_1 NULL;
        
$precip_24 NULL;
        
$wind NULL;
        
$wind_gust NULL;
        
$wind_angle NULL;
        
$wind_gust_angle NULL;
        
$wind_strength_max NULL;
        
$pressure NULL;
        
$pressure_trend NULL;
        
$sunrise NULL;
        
$sunset NULL;
        
$battery_outdoor_module NULL;
        
$battery_wind_gauge NULL;
        
$battery_rain_gauge NULL;

        
// Set default timezone from info in array();
        
date_default_timezone_set($device["place"]["timezone"]);

        
// Stuff that needs rewriting / extra functions
        
$station_id format_create_station_id($device["place"]["city"])."_".$device["place"]["country"];
        
$pressure_trend format_directions_to_values($device["dashboard_data"]["pressure_trend"]);
        
$sunrise format_sunriseandset("sunrise"$device["place"]["location"][1], $device["place"]["location"][0]);
        
$sunset format_sunriseandset("sunset"$device["place"]["location"][1], $device["place"]["location"][0]);

        
// Raw code from the API
        
$observation_time $device["last_status_store"];
        
$pressure $device["dashboard_data"]["Pressure"];

        foreach (
$device["modules"] AS $module) {
            
// NAModule1 = Outdoor module
            
if ($module["type"] == "NAModule1") {
                
$temp $module["dashboard_data"]["Temperature"];
                
$temp_min $module["dashboard_data"]["min_temp"];
                
$temp_max $module["dashboard_data"]["max_temp"];
                
$temp_trend format_directions_to_values($module["dashboard_data"]["temp_trend"]);
                
$humidity $module["dashboard_data"]["Humidity"];
                
$battery_outdoor_module $module["battery_percent"];
            
// NAModule2 = Wind gauge
            
} elseif ($module["type"] == "NAModule2") {
                
$wind $module["dashboard_data"]["WindStrength"];
                
$wind_gust $module["dashboard_data"]["GustStrength"];
                
$wind_angle $module["dashboard_data"]["WindAngle"];
                
$wind_gust_angle $module["dashboard_data"]["GustAngle"];
                
$wind_strength_max $module["dashboard_data"]["max_wind_str"];
                
$battery_wind_gauge $module["battery_percent"];
            
// NAMOdule3 = Rain gauge
            
} elseif ($module["type"] == "NAModule3") {
                
$precip $module["dashboard_data"]["Rain"];
                
$precip_1 $module["dashboard_data"]["sum_rain_1"];
                
$precip_24 $module["dashboard_data"]["sum_rain_24"];
                
$battery_rain_gauge $module["battery_percent"];
            }
        }

        
// Return array for debuging if it's executed via http, or insert data to MySQL if it's executed as CLI.
        
if (@$_SERVER["REQUEST_METHOD"] == "GET") {
            echo 
"<pre>";
            
print_r($device);
            echo 
"</pre>";
        } else {
            
// SQL here!
            
$query mysqli_query($sql"
                INSERT INTO weather_netatmo (update_time, observation_time, station_id, temp, temp_min, temp_max, temp_trend, humidity, precip, precip_1, precip_24, wind, wind_gust, wind_angle, wind_gust_angle, wind_strength_max, pressure, pressure_trend, sunrise, sunset, battery_outdoor_module, battery_wind_gauge, battery_rain_gauge)
                VALUES ('"
.$update_time."', '".$observation_time."', '".$station_id."', '".$temp."', '".$temp_min."', '".$temp_max."', '".$temp_trend."', '".format_nonegs($humidity)."', '".format_nonegs($precip)."', '".format_nonegs($precip_1)."', '".format_nonegs($precip_24)."', '".format_nonegs($wind)."', '".format_nonegs($wind_gust)."', '".format_nonegs($wind_angle)."', '".format_nonegs($wind_gust_angle)."', '".format_nonegs($wind_strength_max)."', '".format_nonegs($pressure)."', '".$pressure_trend."', '".$sunrise."', '".$sunset."', '".format_nonegs($battery_outdoor_module)."', '".format_nonegs($battery_wind_gauge)."', '".format_nonegs($battery_rain_gauge)."')
            "
);
        }
    }
?>