chargemap/ocpi-protocol

处理OCPI的库。与PSR兼容。使用JsonSchema验证有效载荷。

0.6.1 2021-11-12 15:03 UTC

README

处理OCPI的库。与PSR兼容。

功能

库提供了eMSP接口的OCPI请求/响应类,包括模型、工厂和错误。支持GET路由的请求/响应列表。响应需要相应的请求来构建。需要确保请求头中的“offset”和“limit”以及响应头中的“X-Total-Count”、“X-Limit”和“Link”的存在和有效性。因此,构建有效的列表响应或获取下一个请求非常容易。

eMSP接口

响应CPO

use Chargemap\OCPI\Versions\V2_1_1\Server\Emsp\Sessions\Put\OcpiEmspSessionPutRequest;
use Chargemap\OCPI\Versions\V2_1_1\Server\Emsp\Sessions\Put\OcpiEmspSessionPutResponse;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;

/** @var RequestInterface $httpRequest */
$sessionPutRequest = new OcpiEmspSessionPutRequest($httpRequest, 'NL', 'TNM', '101');
$session = $sessionPutRequest->getSession();

// Some code...

$sessionPutResponse = new OcpiEmspSessionPutResponse($session);
/** @var ResponseInterface $response */
$response = $sessionPutResponse->getResponseInterface();

每个请求和响应类对应一个eMSP接口路由。请求类必须通过提供PSR-7兼容的请求(从CPO获取)来实例化。内部,它从头部提取授权令牌,并(如有必要)使用json schema验证正文。然后,它使用工厂构建相应的模型类。模型可以通过getter访问。

响应类必须使用模型实例实例化,即使它没有被使用(例如,在Post/Put/Patch响应中)。可以使用getResponseInterface方法将其转换为PSR-7兼容的响应实例。

使用列表请求/响应

use Chargemap\OCPI\Versions\V2_1_1\Server\Emsp\Tokens\Get\OcpiEmspTokenGetRequest;
use Chargemap\OCPI\Versions\V2_1_1\Server\Emsp\Tokens\Get\OcpiEmspTokenGetResponse;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;

/** @var RequestInterface $httpRequest */
$tokenGetRequest = new OcpiEmspTokenGetRequest($httpRequest);
$tokens = [];
$tokenCount = 0;

//Fetch tokens from database...

$tokenGetResponse = new OcpiEmspTokenGetResponse($tokenGetRequest, $tokenCount, count($tokens));
foreach ($tokens as $token) {
    $tokenGetResponse->addToken($token);
}
// X-Total-Count, X-Limit and Link headers are already set in $response
/** @var ResponseInterface $response */
$response = $tokenGetResponse->getResponseInterface();

请求CPO

这部分提供了一个API SDK来请求CPO。要使用它,您需要使用OcpiConfiguration和所需端点实例化OcpiClient。然后您可以执行如下请求

use Chargemap\OCPI\Versions\V2_1_1\Client\Locations\GetListing\GetLocationsListingRequest;
use Chargemap\OCPI\Versions\V2_1_1\Common\Models\Location;
use Chargemap\OCPI\Common\Client\OcpiClient;
use Chargemap\OCPI\Common\Client\OcpiConfiguration;
use Chargemap\OCPI\Common\Client\OcpiEndpoint;
use Chargemap\OCPI\Common\Client\OcpiVersion;
use Chargemap\OCPI\Common\Models\BaseModuleId;

$ocpiClient = new OcpiClient(
            (new OcpiConfiguration($supervisorAuthString))
                ->withEndpoint(new OcpiEndpoint(
                    OcpiVersion::V2_1_1(),
                    BaseModuleId::LOCATIONS(),
                    new Uri('ocpi/cpo2.0/locations'))
                )
        );
$getLocationListingRequest = (new GetLocationsListingRequest())
                                ->withOffset(0)
                                ->withLimit(100)
                                ->withDateFrom($dateFrom)
                                ->withDateTo($dateTo);
$locationResponse = $ocpiClient->V2_1_1()->locations()->getListing($getLocationListingRequest);
/** @var Location[] $locations */
$locations = $locationResponse->getLocations();
//Some code...

列表请求/响应

use Chargemap\OCPI\Versions\V2_1_1\Client\Locations\GetListing\GetLocationsListingRequest;
use Chargemap\OCPI\Common\Client\OcpiClient;
use Chargemap\OCPI\Common\Client\OcpiConfiguration;
use Chargemap\OCPI\Common\Client\OcpiEndpoint;
use Chargemap\OCPI\Common\Client\OcpiVersion;
use Chargemap\OCPI\Common\Models\BaseModuleId;

$ocpiClient = new OcpiClient(
            (new OcpiConfiguration($supervisorAuth))
                ->withEndpoint(new OcpiEndpoint(
                    OcpiVersion::V2_1_1(),
                    BaseModuleId::LOCATIONS(),
                    new Uri('ocpi/cpo2.0/locations'))
                )
        );
$getLocationListingRequest = (new GetLocationsListingRequest())
                                ->withOffset(0)
                                ->withLimit(100)
                                ->withDateFrom($dateFrom)
                                ->withDateTo($dateTo);
do {
    $locationResponse = $this->ocpiClient->V2_1_1()->locations()->getListing($getLocationListingRequest);
    
    //Some code...     
    
    //Next request will update its limit and offset values
    $getLocationListingRequest = $locationResponse->getNextRequest();
} while ($getLocationListingRequest !== null);

公共

错误

每个错误类对应一个OCPI错误代码。它可以像任何响应类一样转换为PSR-7响应实例。它确保正确的HTTP错误代码以及OCPI状态代码。

use Chargemap\OCPI\Common\Server\Errors\OcpiGenericClientError;
use Psr\Http\Message\ResponseInterface;

$error = new OcpiGenericClientError('Client error');
//Correct payload and HTTP error code is already set
/** @var ResponseInterface $response */
$response = $error->getResponseInterface();

错误应该由中间件/监听器抛出和捕获,然后转换为响应。

模型

从请求/响应的json体中获取的模型对应于OCPI对象。例外是用于PATCH路由的Partial[Class]类,它们具有与对应的[Class]相同的但可空的属性。