Commit 00307dc6 authored by Jacob Priddy's avatar Jacob Priddy 👌

add unresponsive door count to dashboard

parent e389365f
......@@ -48,12 +48,12 @@
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-success text-uppercase mb-1">Earnings (Annual)
<div class="text-xs font-weight-bold text-success text-uppercase mb-1">Unresponsive Doors
</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">$215,000</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">{{ $missingDoorCount }}</div>
</div>
<div class="col-auto">
<i class="fas fa-dollar-sign fa-2x text-gray-300"></i>
<i class="fas fa-exclamation-triangle fa-2x text-gray-300"></i>
</div>
</div>
</div>
......
......@@ -7,6 +7,11 @@ use Carbon\Carbon;
class Door
{
/**
* A door is missing if it is AWOL for this much time.
*/
public const AWOL_TIME_SECONDS = 60 * 60 * 8;
/**
* @var int
*/
......
......@@ -197,4 +197,19 @@ class DatabaseDoorsRepository implements DoorsRepository
{
return (bool)$this->get($doorId);
}
/**
* @inheritDoc
*/
public function awolFor(int $seconds): array
{
$doors = \App\Door::query()
->whereNotNull('last_seen_at')
->where('last_seen_at', '<', Carbon::now()->subRealSeconds($seconds))
->get();
return array_map(static function (\App\Door $door): Door {
return self::makeDoorFromDb($door);
}, $doors);
}
}
......@@ -79,4 +79,12 @@ interface DoorsRepository
* @return bool
*/
public function exists(string $doorId): bool;
/**
* Retrieves doors who have not contacted the API in the last x seconds.
*
* @param int $seconds
* @return \Source\Entities\Door[]
*/
public function awolFor(int $seconds): array;
}
......@@ -127,6 +127,7 @@ class InMemoryDoorsRepository implements DoorsRepository
$doors = 0;
$this->doors = array_values(array_filter($this->doors, static function (Door $door) use ($doorId, &$doors) {
$doors++;
return !$door->hasIdOf($doorId);
}));
......@@ -140,4 +141,16 @@ class InMemoryDoorsRepository implements DoorsRepository
{
return (bool)$this->get($doorId);
}
/**
* @inheritDoc
*/
public function awolFor(int $seconds): array
{
$compare = Carbon::now()->subRealSeconds($seconds);
return array_filter($this->doors, static function (Door $door) use ($compare) : bool {
return $door->getLastSeenAt() && $door->getLastSeenAt()->lessThan($compare);
});
}
}
......@@ -3,6 +3,7 @@
namespace Source\Gateways\Doors;
use Carbon\Carbon;
use Source\Entities\Door;
use Source\Entities\HashedSearchable;
......@@ -26,7 +27,10 @@ class LocalDoorsRepository extends InMemoryDoorsRepository
'The Amazon',
'chicken izta door',
HashedSearchable::hash($salt, 'door_1_api_token'),
'door version here'
'door version here',
null,
null,
Carbon::now()->subWeek()
);
}
......
......@@ -18,6 +18,8 @@ class ResponseModel
protected int $doorCount;
protected int $missingDoorCount;
public function addFailureRate(DoorFailureRate $failureRate): void
{
$this->failureRates[] = $failureRate;
......@@ -38,6 +40,11 @@ class ResponseModel
$this->doorCount = $count;
}
public function setMissingDoors(int $count): void
{
$this->missingDoorCount = $count;
}
public function getActiveUsers(): int
{
return $this->activeUsers;
......@@ -57,4 +64,9 @@ class ResponseModel
{
return $this->doorCount;
}
public function getNumberOfMissingDoors(): int
{
return $this->missingDoorCount;
}
}
......@@ -3,46 +3,30 @@
namespace Source\UseCases\Admin\Statistics;
use Carbon\Carbon;
//use Source\Gateways\Entries\EntriesRepository;
//use Source\Gateways\Attempts\AttemptsRepository;
use Source\Entities\Door;
use Source\Gateways\Doors\DoorsRepository;
use Source\Gateways\Users\UsersRepository;
use Source\Gateways\Statistics\StatisticsRepository;
class Statistics implements StatisticsUseCase
{
protected const STATISTIC_LIMIT = 10;
/*
* Active users of the system (Number of unique users who have used a door in the past week)
* Graph of door usages
* bad doors
* bad keypads
* Top entry fialure by percentage of entered codes
*/
// /**
// * @var \Source\Gateways\Attempts\AttemptsRepository
// */
// protected AttemptsRepository $attempts;
//
// /**
// * @var \Source\Gateways\Entries\EntriesRepository
// */
// protected EntriesRepository $entries;
/**
* @var \Source\Gateways\Statistics\StatisticsRepository
*/
protected StatisticsRepository $statistics;
/**
* @var \Source\Gateways\Doors\DoorsRepository
*/
protected DoorsRepository $doors;
public function __construct(
// AttemptsRepository $attempts,
// EntriesRepository $entries,
StatisticsRepository $statistics
StatisticsRepository $statistics,
DoorsRepository $doors
) {
// $this->attempts = $attempts;
// $this->entries = $entries;
$this->statistics = $statistics;
$this->doors = $doors;
}
/**
......@@ -59,12 +43,16 @@ class Statistics implements StatisticsUseCase
$doors = $this->statistics->countDoors();
$awolDoorCount = count($this->doors->awolFor(Door::AWOL_TIME_SECONDS));
$response = new ResponseModel();
$response->setActiveUsers($this->statistics->countActiveUsers($start, $date));
$response->setDoorCount($doors);
$response->setMissingDoors($awolDoorCount);
foreach ($usages as $usage) {
$response->addMostUsedDoor($usage[1], $usage[0]);
}
......
......@@ -3,6 +3,7 @@
namespace Source\UseCases\Admin\Statistics;
use Source\Gateways\Doors\DoorsRepository;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\Support\DeferrableProvider;
use Illuminate\Support\ServiceProvider;
......@@ -21,7 +22,10 @@ class StatisticsUseCaseServiceProvider extends ServiceProvider implements Deferr
public function register(): void
{
$this->app->bind(StatisticsUseCase::class, static function (Application $app) {
return new Statistics($app->make(StatisticsRepository::class));
return new Statistics(
$app->make(StatisticsRepository::class),
$app->make(DoorsRepository::class)
);
});
}
......
......@@ -17,6 +17,8 @@ class WebPresenter extends BasePresenter implements Presenter
$this->viewModel['doorCount'] = $responseModel->getDoorCount();
$this->viewModel['missingDoorCount'] = $responseModel->getNumberOfMissingDoors();
try {
$this->viewModel['failures']['labels'] = json_encode(array_map(static function (DoorFailureRate $rate) {
return $rate->getDoor()->getLocation();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment