Skip to content

Instantly share code, notes, and snippets.

@jbeker
Created August 6, 2023 17:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jbeker/dac2e8018b9b0bf1abe01b0d8d336d66 to your computer and use it in GitHub Desktop.
Save jbeker/dac2e8018b9b0bf1abe01b0d8d336d66 to your computer and use it in GitHub Desktop.
Swiftbar Netatmo Script
#!/opt/homebrew/bin/php
<?php
error_reporting(0);
# <bitbar.title>WeatherMenu - Netatmo</bitbar.title>
# <bitbar.version>v1.0</bitbar.version>
# <bitbar.author>Dan Moren</bitbar.author>
# <bitbar.author.github>dbmoren</bitbar.author.github>
# <bitbar.desc>Gets weather from local Netatmo station. Requires configuration for device ID, Netatmo account information, and developer access.</bitbar.desc>
# <bitbar.dependencies>php</bitbar.dependencies>
// Your current timezone, as per this list: https://www.php.net/manual/en/timezones.php
$default_timezone = "America/New_York";
// Your Netatmo module's MAC address.
$device_id = "XXXXXXXXXXXXXXX";
// Client ID, Client Secret, and refresh token obtained from Netatmo Developer setup.
// (https://dev.netatmo.com/apps/)
$oauth_client_id = "";
$oauth_client_secret = "";
$refresh_token = "";
// Setup the cURL session to retrieve oAuth token.
$ch = curl_init();
// Set the options for the oAuth cURL session, as per Netatmo's guidelines:
// https://dev.netatmo.com/apidocumentation/oauth
$postfields = ["grant_type" => "refresh_token",
"Content-Type:" => "application/x-www-form-urlencoded;charset=UTF-8",
"client_id" => $oauth_client_id,
"client_secret" => $oauth_client_secret,
"refresh_token" => $refresh_token];
curl_setopt_array($ch, array(
CURLOPT_URL => "https://api.netatmo.com/oauth2/token",
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => $postfields,
CURLOPT_RETURNTRANSFER => true
)
);
// Execute cURL session; throw any errors.
if( ! $oauth_data = curl_exec($ch)) {
trigger_error(curl_error($ch));
}
curl_close($ch);
// Format results from cURL session into an array.
$oauth_results = json_decode($oauth_data, true);
// Start actual retrieval request, using Netatmo API endpoint and oAuth token from above.
// https://dev.netatmo.com/apidocumentation/weather
$URL = "https://api.netatmo.com/api/getstationsdata?device_id=".urlencode($device_id)."&get_favorites=false";
$opts = ["http" => ["method" => "GET", "header" => "Authorization: Bearer ".$oauth_results["access_token"]]];
$context = stream_context_create($opts);
$weather_data = @file_get_contents($URL, false, $context);
$json = json_decode($weather_data, true);
// Retrieve data from JSON results.
if(is_array($json)) {
//print_r($json);
$base_station = $json['body']['devices'][0];
$outdoor_unit = $base_station['modules'][0];
$office_unit = $base_station['modules'][1];
$base_station_data = $base_station['dashboard_data'];
$outdoor_unit_data = $outdoor_unit['dashboard_data'];
$office_unit_data = $office_unit['dashboard_data'];
// [dashboard_data] => Array
// (
// [time_utc] => 1691322149
// [Temperature] => 25.2
// [CO2] => 642
// [Humidity] => 60
// [min_temp] => 25.1
// [max_temp] => 25.3
// [date_max_temp] => 1691298257
// [date_min_temp] => 1691302820
// [temp_trend] => stable
// )
// )
$temp_celsius = $outdoor_unit_data['Temperature'];
$humidity_percent = $outdoor_unit_data['Humidity'];
$trend = $outdoor_unit_data['temp_trend'];
$rain_last_hr_mm = $outdoor_unit_data['sum_rain_1'];
$battery_percent = $outdoor_unit_data['battery_percent'];
$last_update= $outdoor_unit_data['time_utc'];
$temp_fahrenheit = round(($temp_celsius * 1.8) + 32);
$rain_inches = round($rain_last_hr_mm * 0.03937008, 3);
$date = new DateTime();
$date->setTimestamp($last_update);
$date->setTimezone(new DateTimeZone($default_timezone));
$output_date = $date->format('Y-m-d H:i:s');
switch(true) {
case ($battery_percent >= 50):
$battery_status_icon = "\u{1F7E2}";
break;
case ($battery_percent < 50 && $battery_percent > 10):
$battery_status_icon = "\u{1F7E0}";
break;
case ($battery_percent <= 10):
$battery_status_icon = "\u{1F534}";
break;
}
switch($trend) {
case "up";
$trend_arrow = "\u{2191}";
break;
case "down";
$trend_arrow = "\u{2193}";
break;
case "stable";
$trend_arrow = null;
break;
}
$output = array(
$temp_fahrenheit."°".$trend_arrow,
"Humidity: ".$humidity_percent."%",
"Rain - last hour: ".$rain_inches."in",
"Base Station CO2: ".$base_station_data['CO2']."ppm",
"Office CO2: ".$office_unit_data['CO2']."ppm",
// "Battery: ".$battery_percent."%".$battery_status_icon,
"Last Updated: ".$output_date
);
} else {
$output = array(
"\u{26A0}",
"Invalid data received",
);
}
// Code for a future "feels like" update.
//$feels_like = -42.379 + (2.04901523 * $temp_fahrenheit) + (10.14333127 * $humidity_percent) - (0.22475541 * $temp_fahrenheit * $humidity_percent) - (6.83783 * 10 − 3 * $temp_fahrenheit ** 2) - (5.481717 * 10 − 2 * $humidity_percent ** 2) + (1.22874 * 10 − 3 * $temp_fahrenheit ** 2 * $humidity_percent) + (8.5282 * 10 − 4 * $temp_fahrenheit * $humidity_percent ** 2) - (1.99 * 10 − 6 * $temp_fahrenheit ** 2 * $humidity_percent ** 2);
// Format output for SwiftBar
foreach($output as $key => $value) {
if ($key == 0) {
echo $value."\n---";
} else {
echo "\n".$value." | href='https://my.netatmo.com/app/station'";
}
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment