Skip to content

Commit

Permalink
Merge pull request #78 from devbanana/feature/add-geolocation-support
Browse files Browse the repository at this point in the history
Add geolocation support
  • Loading branch information
maxbeckers authored Jun 13, 2019
2 parents b464b5b + cbc5418 commit fd08ce5
Show file tree
Hide file tree
Showing 11 changed files with 454 additions and 0 deletions.
34 changes: 34 additions & 0 deletions src/Request/Altitude.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace MaxBeckers\AmazonAlexa\Request;

/**
* @author Brandon Olivares <[email protected]>
*/
class Altitude
{
/**
* @var float
*/
public $altitudeInMeters;

/**
* @var float|null
*/
public $accuracyInMeters;

/**
* @param array $amazonRequest
*
* @return Altitude
*/
public static function fromAmazonRequest(array $amazonRequest): self
{
$altitude = new self();

$altitude->altitudeInMeters = floatval($amazonRequest['altitudeInMeters']);
$altitude->accuracyInMeters = isset($amazonRequest['accuracyInMeters']) ? floatval($amazonRequest['accuracyInMeters']) : null;

return $altitude;
}
}
6 changes: 6 additions & 0 deletions src/Request/Context.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ class Context
*/
public $audioPlayer;

/**
* @var Geolocation|null
*/
public $geolocation;

/**
* @param array $amazonRequest
*
Expand All @@ -28,6 +33,7 @@ public static function fromAmazonRequest(array $amazonRequest): self

$context->system = isset($amazonRequest['System']) ? System::fromAmazonRequest($amazonRequest['System']) : null;
$context->audioPlayer = isset($amazonRequest['AudioPlayer']) ? AudioPlayer::fromAmazonRequest($amazonRequest['AudioPlayer']) : null;
$context->geolocation = isset($amazonRequest['Geolocation']) ? Geolocation::fromAmazonRequest($amazonRequest['Geolocation']) : null;

return $context;
}
Expand Down
40 changes: 40 additions & 0 deletions src/Request/Coordinate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace MaxBeckers\AmazonAlexa\Request;

/**
* @author Brandon Olivares <[email protected]>
*/
class Coordinate
{
/**
* @var float
*/
public $latitudeInDegrees;

/**
* @var float
*/
public $longitudeInDegrees;

/**
* @var float
*/
public $accuracyInMeters;

/**
* @param array $amazonRequest
*
* @return Coordinate
*/
public static function fromAmazonRequest(array $amazonRequest): self
{
$coordinate = new self();

$coordinate->latitudeInDegrees = floatval($amazonRequest['latitudeInDegrees']);
$coordinate->longitudeInDegrees = floatval($amazonRequest['longitudeInDegrees']);
$coordinate->accuracyInMeters = floatval($amazonRequest['accuracyInMeters']);

return $coordinate;
}
}
58 changes: 58 additions & 0 deletions src/Request/Geolocation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

namespace MaxBeckers\AmazonAlexa\Request;

/**
* @author Brandon Olivares <[email protected]>
*/
class Geolocation
{
/**
* @var LocationServices|null
*/
public $locationServices;

/**
* @var \DateTime
*/
public $timestamp;

/**
* @var Coordinate|null
*/
public $coordinate;

/**
* @var Altitude|null
*/
public $altitude;

/**
* @var Heading|null
*/
public $heading;

/**
* @var Speed|null
*/
public $speed;

/**
* @param array $amazonRequest
*
* @return Geolocation
*/
public static function fromAmazonRequest(array $amazonRequest): self
{
$geolocation = new self();

$geolocation->locationServices = isset($amazonRequest['locationServices']) ? LocationServices::fromAmazonRequest($amazonRequest['locationServices']) : null;
$geolocation->timestamp = new \DateTime($amazonRequest['timestamp']);
$geolocation->coordinate = isset($amazonRequest['coordinate']) ? Coordinate::fromAmazonRequest($amazonRequest['coordinate']) : null;
$geolocation->altitude = isset($amazonRequest['altitude']) ? Altitude::fromAmazonRequest($amazonRequest['altitude']) : null;
$geolocation->heading = isset($amazonRequest['heading']) ? Heading::fromAmazonRequest($amazonRequest['heading']) : null;
$geolocation->speed = isset($amazonRequest['speed']) ? Speed::fromAmazonRequest($amazonRequest['speed']) : null;

return $geolocation;
}
}
34 changes: 34 additions & 0 deletions src/Request/Heading.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace MaxBeckers\AmazonAlexa\Request;

/**
* @author Brandon Olivares <[email protected]>
*/
class Heading
{
/**
* @var float
*/
public $directionInDegrees;

/**
* @var float|null
*/
public $accuracyInDegrees;

/**
* @param array $amazonRequest
*
* @return Heading
*/
public static function fromAmazonRequest(array $amazonRequest): self
{
$heading = new self();

$heading->directionInDegrees = floatval($amazonRequest['directionInDegrees']);
$heading->accuracyInDegrees = isset($amazonRequest['accuracyInDegrees']) ? floatval($amazonRequest['accuracyInDegrees']) : null;

return $heading;
}
}
40 changes: 40 additions & 0 deletions src/Request/LocationServices.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace MaxBeckers\AmazonAlexa\Request;

/**
* @author Brandon Olivares <[email protected]>
*/
class LocationServices
{
const ACCESS_ENABLED = 'ENABLED';
const ACCESS_DISABLED = 'DISABLED';

const STATUS_RUNNING = 'RUNNING';
const STATUS_STOPPED = 'STOPPED';

/**
* @var string
*/
public $access;

/**
* @var string
*/
public $status;

/**
* @param array $amazonRequest
*
* @return LocationServices
*/
public static function fromAmazonRequest(array $amazonRequest): self
{
$locationServices = new self();

$locationServices->access = $amazonRequest['access'];
$locationServices->status = $amazonRequest['status'];

return $locationServices;
}
}
34 changes: 34 additions & 0 deletions src/Request/Speed.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace MaxBeckers\AmazonAlexa\Request;

/**
* @author Brandon Olivares <[email protected]>
*/
class Speed
{
/**
* @var float
*/
public $speedInMetersPerSecond;

/**
* @var float|null
*/
public $accuracyInMetersPerSecond;

/**
* @param array $amazonRequest
*
* @return Speed
*/
public static function fromAmazonRequest(array $amazonRequest): self
{
$speed = new self();

$speed->speedInMetersPerSecond = floatval($amazonRequest['speedInMetersPerSecond']);
$speed->accuracyInMetersPerSecond = isset($amazonRequest['accuracyInMetersPerSecond']) ? floatval($amazonRequest['accuracyInMetersPerSecond']) : null;

return $speed;
}
}
2 changes: 2 additions & 0 deletions src/Response/Card.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ class Card implements \JsonSerializable

const PERMISSION_FULL_ADDRESS = 'read::alexa:device:all:address';
const PERMISSION_COUNTRY_REGION_AND_POSTAL_CODE = 'read::alexa:device:all:address:country_and_postal_code';
const PERMISSION_GEOLOCATION = 'alexa::devices:all:geolocation:read';
const PERMISSIONS = [
self::PERMISSION_FULL_ADDRESS,
self::PERMISSION_COUNTRY_REGION_AND_POSTAL_CODE,
self::PERMISSION_GEOLOCATION,
];

/**
Expand Down
56 changes: 56 additions & 0 deletions test/Test/Request/GeolocationRequestTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

namespace MaxBeckers\AmazonAlexa\Test\Request;

use MaxBeckers\AmazonAlexa\Request\Request;
use MaxBeckers\AmazonAlexa\Request\Request\Standard\IntentRequest;
use MaxBeckers\AmazonAlexa\Response\Card;
use PHPUnit\Framework\TestCase;

/**
* @author Brandon Olivares <[email protected]>
*/
class GeolocationRequestTest extends TestCase
{
public function testGeolocationNeedsPermission()
{
$requestBody = file_get_contents(__DIR__.'/RequestData/geolocationPermission.json');
$request = Request::fromAmazonRequest($requestBody, 'https://s3.amazonaws.com/echo.api/echo-api-cert.pem', 'signature');
$this->assertInstanceOf(IntentRequest::class, $request->request);
$this->assertArrayHasKey('Geolocation', $request->context->system->device->supportedInterfaces);
$this->assertNull($request->context->geolocation);

// Create permissions card.
$card = Card::createAskForPermissionsConsent([Card::PERMISSION_GEOLOCATION]);
$this->assertInstanceOf(Card::class, $card);
}

public function testGetGeolocationData()
{
$requestBody = file_get_contents(__DIR__.'/RequestData/geolocation.json');
$request = Request::fromAmazonRequest($requestBody, 'https://s3.amazonaws.com/echo.api/echo-api-cert.pem', 'signature');
$this->assertInstanceOf(IntentRequest::class, $request->request);
$this->assertArrayHasKey('Geolocation', $request->context->system->device->supportedInterfaces);

$geolocation = $request->context->geolocation;
$this->assertNotNull($geolocation);

$this->assertNotNull($geolocation->locationServices);
$this->assertEquals('ENABLED', $geolocation->locationServices->access);
$this->assertEquals('RUNNING', $geolocation->locationServices->status);
$this->assertEquals(new \DateTime('2019-06-12T19:13:01+00:00'), $geolocation->timestamp);
$this->assertNotNull($geolocation->coordinate);
$this->assertEquals(40.3, $geolocation->coordinate->latitudeInDegrees);
$this->assertEquals(-78.9, $geolocation->coordinate->longitudeInDegrees);
$this->assertEquals(100, $geolocation->coordinate->accuracyInMeters);
$this->assertNotNull($geolocation->altitude);
$this->assertEquals(600, $geolocation->altitude->altitudeInMeters);
$this->assertEquals(100, $geolocation->altitude->accuracyInMeters);
$this->assertNotNull($geolocation->heading);
$this->assertEquals(48.12, $geolocation->heading->directionInDegrees);
$this->assertEquals(5, $geolocation->heading->accuracyInDegrees);
$this->assertNotNull($geolocation->speed);
$this->assertEquals(1, $geolocation->speed->speedInMetersPerSecond);
$this->assertEquals(1.0, $geolocation->speed->accuracyInMetersPerSecond);
}
}
Loading

0 comments on commit fd08ce5

Please sign in to comment.