Skip to content

added Air Pollution API for Carbon Monoxide #138

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Oct 31, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 85 additions & 2 deletions Cmfcmf/OpenWeatherMap.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@

namespace Cmfcmf;

use Cmfcmf\OpenWeatherMap\AirPollution;
use Cmfcmf\OpenWeatherMap\CurrentWeather;
use Cmfcmf\OpenWeatherMap\UVIndex;
use Cmfcmf\OpenWeatherMap\CurrentWeatherGroup;
use Cmfcmf\OpenWeatherMap\Exception as OWMException;
use Cmfcmf\OpenWeatherMap\NotFoundException as OWMNotFoundException;
use Cmfcmf\OpenWeatherMap\UVIndex;
use Cmfcmf\OpenWeatherMap\WeatherForecast;
use Psr\Cache\CacheItemPoolInterface;
use Psr\Http\Client\ClientInterface;
Expand Down Expand Up @@ -67,6 +69,11 @@ class OpenWeatherMap
*/
private $uvIndexUrl = 'https://api.openweathermap.org/data/2.5/uvi';

/**
* @var string The basic api url to fetch air pollution data from.
*/
private $airPollutionUrl = 'https://api.openweathermap.org/pollution/v1/';

/**
* @var CacheItemPoolInterface|null $cache The cache to use.
*/
Expand Down Expand Up @@ -336,6 +343,45 @@ public function getHistoricUVIndex($lat, $lon, $start, $end)
}, $data);
}

/**
* Returns air pollution data
*
* @param string $type One of CO, O3, SO2, and NO2.
* @param string $lat The location's latitude.
* @param string $lon The location's longitude.
* @param string $date The date to gather data from. If you omit this parameter or supply "current", returns current data.
*
* @return AirPollution\COAirPollution|AirPollution\NO2AirPollution|AirPollution\O3AirPollution|AirPollution\SO2AirPollution|null The air pollution data or null if no data was found.
*
* We use strings as $lat and $lon, since the exact number of digits in $lat and $lon determines the search range.
* For example, there is a difference between using "1.5" and "1.5000".
* We also use a string for $date, since it may either be "current" or an (abbreviated) ISO 8601 timestamp like 2016Z.
*
* @throws OWMException|\Exception
*
* @api
*/
public function getAirPollution($type, $lat, $lon, $date = "current")
{
$answer = $this->getRawAirPollutionData($type, $lat, $lon, $date);
if ($answer === null) {
return null;
}
$json = $this->parseJson($answer);
switch ($type) {
case "O3":
return new AirPollution\O3AirPollution($json);
case "NO2":
return new AirPollution\NO2AirPollution($json);
case "SO2":
return new AirPollution\SO2AirPollution($json);
case "CO":
return new AirPollution\COAirPollution($json);
default:
throw new \LogicException();
}
}

/**
* Directly returns the xml/json/html string returned by OpenWeatherMap for the current weather.
*
Expand Down Expand Up @@ -471,6 +517,40 @@ public function getRawUVIndexData($mode, $lat, $lon, $cnt = null, $start = null,
return $this->cacheOrFetchResult($url);
}

/**
* Fetch raw air pollution data
*
* @param string $type One of CO, O3, SO2, and NO2.
* @param string $lat The location's latitude.
* @param string $lon The location's longitude.
* @param string $date The date to gather data from. If you omit this parameter or supply "current", returns current data.
*
* @return string|null The air pollution data or null if no data was found.
*
* We use strings as $lat and $lon, since the exact number of digits in $lat and $lon determines the search range.
* For example, there is a difference between using "1.5" and "1.5000".
* We also use a string for $date, since it may either be "current" or an (abbreviated) ISO 8601 timestamp like 2016Z.
*
* @api
*/
public function getRawAirPollutionData($type, $lat, $lon, $date = "current")
{
if (!in_array($type, ["CO", "O3", "SO2", "NO2"])) {
throw new \InvalidArgumentException('Invalid $type received.');
}
if (!is_string($lat) || !is_string($lon) || !is_string($date)) {
throw new \InvalidArgumentException('$lat, $lon and $date all must be strings.');
}

$url = $this->airPollutionUrl . strtolower($type) . "/$lat,$lon/$date.json?appid=" . $this->apiKey;

try {
return $this->cacheOrFetchResult($url);
} catch (OWMNotFoundException $e) {
return null;
}
}

/**
* Returns whether or not the last result was fetched from the cache.
*
Expand Down Expand Up @@ -505,7 +585,10 @@ private function cacheOrFetchResult($url)
$response = $this->httpClient->sendRequest($this->httpRequestFactory->createRequest("GET", $url));
$result = $response->getBody()->getContents();
if ($response->getStatusCode() !== 200) {
throw new OWMException('OpenWeatherMap returned a response with status code ' . $response->getStatusCode() . ' and the following content '. $result);
if ($result === "{\"message\":\"not found\"}\n" && $response->getStatusCode() === 404) {
throw new OWMNotFoundException();
}
throw new OWMException('OpenWeatherMap returned a response with status code ' . $response->getStatusCode() . ' and the following content `'. $result . '`');
}

if ($this->cache !== null) {
Expand Down
46 changes: 46 additions & 0 deletions Cmfcmf/OpenWeatherMap/AirPollution/BaseAirPollution.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

/*
* OpenWeatherMap-PHP-API — A PHP API to parse weather data from https://OpenWeatherMap.org.
*
* @license MIT
*
* Please see the LICENSE file distributed with this source code for further
* information regarding copyright and licensing.
*
* Please visit the following links to read about the usage policies and the license of
* OpenWeatherMap data before using this library:
*
* @see https://OpenWeatherMap.org/price
* @see https://OpenWeatherMap.org/terms
* @see https://OpenWeatherMap.org/appid
*/

namespace Cmfcmf\OpenWeatherMap\AirPollution;

use Cmfcmf\OpenWeatherMap\Util\Location;

abstract class BaseAirPollution
{
/**
* @var \DateTime
*/
public $time;

/**
* @var Location
*/
public $location;

/**
* @param object $json
*
* @throws \Exception
* @internal
*/
public function __construct($json)
{
$this->time = new \DateTime($json->time, new \DateTimeZone('UTC'));
$this->location = new Location($json->location->latitude, $json->location->longitude);
}
}
23 changes: 23 additions & 0 deletions Cmfcmf/OpenWeatherMap/AirPollution/COAirPollution.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

/*
* OpenWeatherMap-PHP-API — A PHP API to parse weather data from https://OpenWeatherMap.org.
*
* @license MIT
*
* Please see the LICENSE file distributed with this source code for further
* information regarding copyright and licensing.
*
* Please visit the following links to read about the usage policies and the license of
* OpenWeatherMap data before using this library:
*
* @see https://OpenWeatherMap.org/price
* @see https://OpenWeatherMap.org/terms
* @see https://OpenWeatherMap.org/appid
*/

namespace Cmfcmf\OpenWeatherMap\AirPollution;

class COAirPollution extends PrecisionPressureValueAirPollution
{
}
49 changes: 49 additions & 0 deletions Cmfcmf/OpenWeatherMap/AirPollution/NO2AirPollution.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

/*
* OpenWeatherMap-PHP-API — A PHP API to parse weather data from https://OpenWeatherMap.org.
*
* @license MIT
*
* Please see the LICENSE file distributed with this source code for further
* information regarding copyright and licensing.
*
* Please visit the following links to read about the usage policies and the license of
* OpenWeatherMap data before using this library:
*
* @see https://OpenWeatherMap.org/price
* @see https://OpenWeatherMap.org/terms
* @see https://OpenWeatherMap.org/appid
*/

namespace Cmfcmf\OpenWeatherMap\AirPollution;

use Cmfcmf\OpenWeatherMap\Util\Unit;

class NO2AirPollution extends BaseAirPollution
{

/**
* @var Unit
*/
public $value;

/**
* @var Unit
*/
public $valueStratosphere;

/**
* @var Unit
*/
public $valueTroposphere;

public function __construct($json)
{
parent::__construct($json);

$this->value = new Unit($json->data->no2->value, "g/m³", "", $json->data->no2->precision);
$this->valueStratosphere = new Unit($json->data->no2_strat->value, "g/m³", "", $json->data->no2_strat->precision);
$this->valueTroposphere = new Unit($json->data->no2_trop->value, "g/m³", "", $json->data->no2_trop->precision);
}
}
37 changes: 37 additions & 0 deletions Cmfcmf/OpenWeatherMap/AirPollution/O3AirPollution.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

/*
* OpenWeatherMap-PHP-API — A PHP API to parse weather data from https://OpenWeatherMap.org.
*
* @license MIT
*
* Please see the LICENSE file distributed with this source code for further
* information regarding copyright and licensing.
*
* Please visit the following links to read about the usage policies and the license of
* OpenWeatherMap data before using this library:
*
* @see https://OpenWeatherMap.org/price
* @see https://OpenWeatherMap.org/terms
* @see https://OpenWeatherMap.org/appid
*/

namespace Cmfcmf\OpenWeatherMap\AirPollution;

use Cmfcmf\OpenWeatherMap\Util\Unit;

class O3AirPollution extends BaseAirPollution
{

/**
* @var Unit
*/
public $value;

public function __construct($json)
{
parent::__construct($json);

$this->value = new Unit($json->data, "DU");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

/*
* OpenWeatherMap-PHP-API — A PHP API to parse weather data from https://OpenWeatherMap.org.
*
* @license MIT
*
* Please see the LICENSE file distributed with this source code for further
* information regarding copyright and licensing.
*
* Please visit the following links to read about the usage policies and the license of
* OpenWeatherMap data before using this library:
*
* @see https://OpenWeatherMap.org/price
* @see https://OpenWeatherMap.org/terms
* @see https://OpenWeatherMap.org/appid
*/

namespace Cmfcmf\OpenWeatherMap\AirPollution;

use Cmfcmf\OpenWeatherMap\Util\Unit;

class PrecisionPressureValueAirPollution extends BaseAirPollution
{

/**
* @var object[]
*/
public $values;

public function __construct($json)
{
parent::__construct($json);

$this->values = [];
foreach ($json->data as $data) {
$this->values[] = [
"value" => new Unit($data->value, "g/m³", "", $data->precision),
"pressure" => new Unit($data->pressure, "hPa"),
];
}
}
}
23 changes: 23 additions & 0 deletions Cmfcmf/OpenWeatherMap/AirPollution/SO2AirPollution.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

/*
* OpenWeatherMap-PHP-API — A PHP API to parse weather data from https://OpenWeatherMap.org.
*
* @license MIT
*
* Please see the LICENSE file distributed with this source code for further
* information regarding copyright and licensing.
*
* Please visit the following links to read about the usage policies and the license of
* OpenWeatherMap data before using this library:
*
* @see https://OpenWeatherMap.org/price
* @see https://OpenWeatherMap.org/terms
* @see https://OpenWeatherMap.org/appid
*/

namespace Cmfcmf\OpenWeatherMap\AirPollution;

class SO2AirPollution extends PrecisionPressureValueAirPollution
{
}
Loading