Skip to content

Commit

Permalink
Allow setting angle and azimuth
Browse files Browse the repository at this point in the history
  • Loading branch information
Holicz committed Sep 30, 2021
1 parent ef0a382 commit 3529c0a
Show file tree
Hide file tree
Showing 8 changed files with 160 additions and 68 deletions.
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ composer require holicz/pvgis
```

# Requirements
* PHP >= 7.4
* PHP ^7.4|^8.0

# Usage

Expand All @@ -19,7 +19,12 @@ $latitude = '50.0898689';
$longitude = '14.4000936';

$pvgis = new PVGIS(new PvgisAdapter());
$electricityProduction = $pvgis->getElectricityProduction($latitude, $longitude);
$electricityProduction = $pvgis->getElectricityProduction(
$latitude,
$longitude,
35, // Solar panels angle (not required)
CardinalDirection::SOUTH // Solar panels azimuth (not required)
);

// Yearly sum of production
$electricityProduction->getYearlyProduction();
Expand Down
38 changes: 8 additions & 30 deletions src/Adapter/PvgisAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,20 @@
use holicz\PVGIS\Exception\InvalidResponseFormatException;
use holicz\PVGIS\Exception\PvgisResponseFailureException;
use holicz\PVGIS\Model\ElectricityProduction;
use Safe\Exceptions\FilesystemException;
use Safe\Exceptions\StringsException;
use holicz\PVGIS\Model\Request;

use function file_get_contents;

final class PvgisAdapter
{
private const API_URL = 'https://re.jrc.ec.europa.eu/api/pvcalc?peakpower=1&pvtechchoice=crystSi&mountingplace=building&loss=10&outputformat=json&angle=35&lat=%s&lon=%s';

/**
* Multiplier to change the PVGIS result in order to get desired production
*/
private float $multiplier;

public function __construct(float $multiplier = 1.0)
{
$this->multiplier = $multiplier;
}

/**
* @param string $latitude
* @param string $longitude
*
* @return ElectricityProduction
*
* @throws FilesystemException
* @throws InvalidResponseFormatException
* @throws PvgisResponseFailureException
* @throws StringsException
*/
public function getPvgisData(string $latitude, string $longitude): ElectricityProduction
public function getPvgisData(Request $request): ElectricityProduction
{
$response = \Safe\file_get_contents(\Safe\sprintf(self::API_URL, $latitude, $longitude));
$urlBuilder = new UrlBuilder($request);
$response = file_get_contents($urlBuilder->build());

if (!$response) {
throw new PvgisResponseFailureException();
Expand All @@ -48,21 +31,16 @@ public function getPvgisData(string $latitude, string $longitude): ElectricityPr
}

/**
* @param string $response
*
* @return ElectricityProduction
*
* @throws InvalidResponseFormatException
* @throws StringsException
*/
private function parsePvgisResponse(string $response): ElectricityProduction
{
try {
$response = json_decode($response, true, 512, JSON_THROW_ON_ERROR);

$electricityProduction = new ElectricityProduction($this->multiplier * $response['outputs']['totals']['fixed']['E_y']);
$electricityProduction = new ElectricityProduction($response['outputs']['totals']['fixed']['E_y']);
foreach ($response['outputs']['monthly']['fixed'] as $month) {
$electricityProduction->addMonthlyProduction($month['month'], $this->multiplier * $month['E_m']);
$electricityProduction->addMonthlyProduction($month['month'], $month['E_m']);
}
} catch (Exception $e) {
throw new InvalidResponseFormatException();
Expand Down
54 changes: 54 additions & 0 deletions src/Adapter/UrlBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

declare(strict_types=1);

namespace holicz\PVGIS\Adapter;

use holicz\PVGIS\Model\Request;

/**
* @internal
*/
final class UrlBuilder
{
private Request $request;
private string $url;

public function __construct(Request $request)
{
$this->request = $request;
$this->url = 'https://re.jrc.ec.europa.eu/api/pvcalc?peakpower=1&pvtechchoice=crystSi&mountingplace=building&loss=10&outputformat=json';
}

public function build(): string
{
$this->buildGPSCoordinates();
$this->buildAngle();
$this->buildAzimuth();

return $this->url;
}

private function buildGPSCoordinates(): void
{
$this->url .= sprintf('&lat=%s&lon=%s', $this->request->getLatitude(), $this->request->getLongitude());
}

private function buildAngle(): void
{
if ($this->request->getAngle() === null) {
return;
}

$this->url .= sprintf('&angle=%d', $this->request->getAngle());
}

private function buildAzimuth(): void
{
if ($this->request->getAzimuth() === null) {
return;
}

$this->url .= sprintf('&aspect=%d', $this->request->getAzimuth());
}
}
17 changes: 17 additions & 0 deletions src/Enum/CardinalDirection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

namespace holicz\PVGIS\Enum;

final class CardinalDirection
{
public const NORTH = 180;
public const NORTHEAST = -135;
public const EAST = -90;
public const SOUTHEAST = -45;
public const SOUTH = 0;
public const SOUTHWEST = 45;
public const WEST = 90;
public const NORTHWEST = 135;
}
17 changes: 3 additions & 14 deletions src/Exception/InvalidResponseFormatException.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,12 @@

namespace holicz\PVGIS\Exception;

use holicz\SimpleException\BaseException;
use holicz\SimpleException\ExceptionContext;
use Safe\Exceptions\StringsException;
use Exception;

final class InvalidResponseFormatException extends BaseException
final class InvalidResponseFormatException extends Exception
{
/**
* @throws StringsException
*/
public function __construct()
{
$exceptionContext = new ExceptionContext(
'Nepodařilo se získat informace z evropského Fotovoltaického geografického informačního systému.',
\Safe\sprintf('Pvgis responded with unknown format.'),
500
);

parent::__construct($exceptionContext);
parent::__construct('Pvgis responded with unknown format.', 500);
}
}
13 changes: 3 additions & 10 deletions src/Exception/PvgisResponseFailureException.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,12 @@

namespace holicz\PVGIS\Exception;

use holicz\SimpleException\BaseException;
use holicz\SimpleException\ExceptionContext;
use Exception;

final class PvgisResponseFailureException extends BaseException
final class PvgisResponseFailureException extends Exception
{
public function __construct()
{
$exceptionContext = new ExceptionContext(
'Nepodařilo se získat informace z evropského Fotovoltaického geografického informačního systému.',
'Failed to get response from Pvgis API',
500
);

parent::__construct($exceptionContext);
parent::__construct('Failed to get response from Pvgis API', 500);
}
}
58 changes: 58 additions & 0 deletions src/Model/Request.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

declare(strict_types=1);

namespace holicz\PVGIS\Model;

/**
* @internal
*/
final class Request
{
private string $latitude;
private string $longitude;
private ?int $angle;
private ?int $azimuth;

public function __construct(
string $latitude,
string $longitude,
?int $angle = null,
?int $azimuth = null
) {
$this->latitude = $latitude;
$this->longitude = $longitude;
$this->angle = $angle;
$this->azimuth = $azimuth;
}

public function getLatitude(): string
{
return $this->latitude;
}

public function getLongitude(): string
{
return $this->longitude;
}

public function setAngle(?int $angle): void
{
$this->angle = $angle;
}

public function getAngle(): ?int
{
return $this->angle;
}

public function setAzimuth(?int $azimuth): void
{
$this->azimuth = $azimuth;
}

public function getAzimuth(): ?int
{
return $this->azimuth;
}
}
22 changes: 10 additions & 12 deletions src/PVGIS.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@

use holicz\PVGIS\Adapter\PvgisAdapter;
use holicz\PVGIS\Model\ElectricityProduction;
use Safe\Exceptions\FilesystemException;
use Safe\Exceptions\StringsException;
use holicz\PVGIS\Model\Request;

final class PVGIS
{
Expand All @@ -19,18 +18,17 @@ public function __construct(PvgisAdapter $pvgisAdapter)
}

/**
* @param string $latitude
* @param string $longitude
*
* @return ElectricityProduction
*
* @throws Exception\InvalidResponseFormatException
* @throws Exception\PvgisResponseFailureException
* @throws FilesystemException
* @throws StringsException
*/
public function getElectricityProduction(string $latitude, string $longitude): ElectricityProduction
{
return $this->pvgisAdapter->getPvgisData($latitude, $longitude);
public function getElectricityProduction(
string $latitude,
string $longitude,
?int $angle = null,
?int $azimuth = null
): ElectricityProduction {
$request = new Request($latitude, $longitude, $angle, $azimuth);

return $this->pvgisAdapter->getPvgisData($request);
}
}

0 comments on commit 3529c0a

Please sign in to comment.