Skip to content

Commit

Permalink
Merge pull request #24 from Zhyltix/feature/ID-204-post-trip-process
Browse files Browse the repository at this point in the history
Feature/id 204 post trip process
  • Loading branch information
JoeyRoeters committed Jan 16, 2024
2 parents f171521 + d4a396b commit 32aad2b
Show file tree
Hide file tree
Showing 42 changed files with 1,183 additions and 653 deletions.
58 changes: 30 additions & 28 deletions app/Domain/Trip/Enum/TripEventEnum.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,35 +14,34 @@ enum TripEventEnum: String
case SPEEDING = 'speeding';
case TOO_SLOW = 'too_slow';
case HARSH_BRAKING = 'harsh braking';
case BREAKING_STOP_SHORT = 'breaking_stop_short';
case PERFECECT_BREAK = 'perfect_break';
case INEFFICIENT_BREAK = 'inefficient_break';
case BREAKING_AND_GAS = 'breaking_and_gas';
case MISSED_GEAR = 'missed_gear';
case PERFECT_GEAR = 'perfect_gear';
case INEFFICIENT_GEAR = 'inefficient_gear';
case LATE_SHIFT_GEAR = 'late_shift_gear';
case MISSED_SHIFT_GEAR = 'missed_shift_gear';
case HARSH_STEERING = 'harsh_steering';
case INEFFICIENT_STEERING = 'inefficient_steering';

case SYSTEM_START = "System Start";
case SYSTEM_END = "System End";
public function requiredDataField(): array
{
return match($this) {
self::SPEEDING => ['speed', 'speed_limit'],
default => [],
};
}

public function getEventTitle(mixed $value = null): string
{
return match ($this) {
self::CROSSED_LINE => 'Crossed Line',
self::COLLISION => 'Collision',
self::CROSSED_LINE => 'Lane departure detected',
self::COLLISION => 'Collision detected',
self::SPEEDING => $this->getSpeedingEventTitle($value),
self::HARSH_BRAKING => 'Harsh Braking',
self::BREAKING_STOP_SHORT => 'Stop Short',
self::PERFECECT_BREAK => 'Perfect Break',
self::INEFFICIENT_BREAK => 'Inefficient Break',
self::MISSED_GEAR => 'Missed Gear',
self::PERFECT_GEAR => 'Perfect Gear',
self::INEFFICIENT_GEAR => 'Inefficient Gear',
self::HARSH_STEERING => 'Harsh Steering',
self::INEFFICIENT_STEERING => 'Inefficient Steering',
self::SYSTEM_START => 'System Start',
self::SYSTEM_END => 'System End',
self::HARSH_BRAKING => 'Abrupt Braking Occurrence',
self::BREAKING_AND_GAS => 'Incorrect Throttle and Brake usage',
self::LATE_SHIFT_GEAR => 'Delayed Gear engagement',
self::MISSED_SHIFT_GEAR => 'Gear Shift Omitted',
self::MISSED_GEAR => 'Gear Engagement Omitted',
self::HARSH_STEERING => 'Aggressive Steering Maneuver',
self::INEFFICIENT_STEERING => 'Suboptimal Steering Maneuver',

default => throw new \Exception('Unexpected match value'),
};
Expand All @@ -52,6 +51,8 @@ private function getSpeedingEventTitle(mixed $value): string
{
$value = $value['speed'] - $value['speed_limit'];

$value = round($value);

return 'Over the speed limit +' . $value . ' km/h';
}

Expand All @@ -77,28 +78,29 @@ public function getEventSeverity(mixed $value = null): SeverityEnum
self::COLLISION => SeverityEnum::HIGH,
self::SPEEDING => $this->getSpeedSeverity($value),
self::HARSH_BRAKING => SeverityEnum::MEDIUM,
self::BREAKING_STOP_SHORT => SeverityEnum::HIGH,
self::PERFECECT_BREAK => SeverityEnum::LOW,
self::INEFFICIENT_BREAK => SeverityEnum::MEDIUM,
self::BREAKING_AND_GAS => SeverityEnum::HIGH,
self::LATE_SHIFT_GEAR => SeverityEnum::MEDIUM,
self::MISSED_SHIFT_GEAR => SeverityEnum::MEDIUM,
self::MISSED_GEAR => SeverityEnum::MEDIUM,
self::PERFECT_GEAR => SeverityEnum::LOW,
self::INEFFICIENT_GEAR => SeverityEnum::MEDIUM,
self::HARSH_STEERING => SeverityEnum::MEDIUM,
self::INEFFICIENT_STEERING => SeverityEnum::MEDIUM,
self::SYSTEM_START => SeverityEnum::LOW,
self::SYSTEM_END => SeverityEnum::LOW,
default => throw new \Exception('Unexpected match value'),
};
}

private function getSpeedSeverity(mixed $value): SeverityEnum
{
if (!is_array($value) && is_string($value)) {
$value = json_decode($value, true);
}

$value = $value['speed'] - $value['speed_limit'];

return match (true) {
$value > 0 && $value <= 10 => SeverityEnum::LOW,
$value > 0 && $value <= 10 => SeverityEnum::MEDIUM,
$value > 10 && $value <= 20 => SeverityEnum::MEDIUM,
$value > 20 => SeverityEnum::HIGH,
$value < 0 => SeverityEnum::LOW,
default => throw new \Exception('Unexpected match value'),
};
}
Expand Down
10 changes: 4 additions & 6 deletions app/Domain/Trip/Enum/TripStatisticParserEnum.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,20 @@ public function getEventEnums(): array
return match ($this) {
self::SPEED_PROFILE => [
TripEventEnum::SPEEDING,
TripEventEnum::HARSH_BRAKING,
],
self::BREAK_PROFILE => [
TripEventEnum::HARSH_BRAKING,
TripEventEnum::BREAKING_STOP_SHORT,
TripEventEnum::PERFECECT_BREAK,
TripEventEnum::INEFFICIENT_BREAK,
TripEventEnum::BREAKING_AND_GAS,
],
self::STEERING_PROFILE => [
TripEventEnum::HARSH_STEERING,
TripEventEnum::INEFFICIENT_STEERING,
// TripEventEnum::COLLISION,
],
self::GEAR_PROFILE => [
TripEventEnum::MISSED_GEAR,
TripEventEnum::PERFECT_GEAR,
TripEventEnum::INEFFICIENT_GEAR,
TripEventEnum::LATE_SHIFT_GEAR,
TripEventEnum::MISSED_SHIFT_GEAR
],
default => throw new \Exception('Unexpected match value'),
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace App\Domain\Trip\Helper;
namespace App\Domain\Trip\Helper\Parsers;

use App\Domain\Trip\Enum\TripStatisticParserEnum;
use App\Domain\Trip\Model\Trip;
Expand Down
116 changes: 116 additions & 0 deletions app/Domain/Trip/Helper/Parsers/Profile/AbstractProfileParser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<?php

namespace App\Domain\Trip\Helper\Parsers\Profile;

use App\Domain\Trip\Enum\TripEventEnum;
use App\Domain\Trip\Enum\TripStatisticParserEnum;
use App\Domain\Trip\Model\Trip;
use App\Domain\Trip\Model\TripEvent;
use App\Domain\Trip\Model\TripStatistic;
use App\Domain\Trip\ValueObject\Statistic\Profile\TimelineValueObject;
use App\Domain\Trip\ValueObject\Statistic\ProfileStatisticValueObject;
use App\Domain\Trip\ValueObject\Statistic\ProfileValueObject;
use Illuminate\Database\Eloquent\Collection;

abstract class AbstractProfileParser
{
protected TripStatistic $profile;

public function __construct(
protected Trip $trip,
) {
$this->profile = $this->getTripStatistic();

$data = $this->profile->data ?? [];
foreach ($data as $key => $value) {
$this->{$key} = $value;
}
}

abstract public function parse(Trip $trip): void;

abstract protected function getParserEnum(): TripStatisticParserEnum;

/**
* @return ProfileStatisticValueObject[]
*/
abstract protected function getProfileTitle(): string;

abstract protected function getProfileStatistics(): array;

public function getProfile(): ProfileValueObject
{
return new ProfileValueObject(
title: $this->getProfileTitle(),
statistics: $this->getProfileStatistics(),
events: $this->getTimeLineEvents()->getProfileEvents()
);
}

protected function getTripStatistic(bool $override = false): TripStatistic
{
$profile = $this->trip->statistics()->where('parser', $this->getParserEnum())->first();
if ($profile instanceof TripStatistic) {
if ($override) {
$profile->delete();
} else {
return $profile;
}
}

return new TripStatistic([
'parser' => $this->getParserEnum(),
'trip_id' => $this->trip->id,
]);
}

protected function getEvents(): Collection
{
return $this->trip
->events()
->where('is_processed', true)
->whereIn('type', $this->getParserEnum()->getEventEnums())
->get();
}

private function fakeData(Collection &$events): void
{
foreach (TripEventEnum::values() as $event) {
$event = TripEventEnum::from($event);
if (!in_array($event, $this->getParserEnum()->getEventEnums())) {
continue;
}

for($i = 0; $i < rand(2, 5); $i++) {
$data = [];
if ($event === TripEventEnum::SPEEDING) {
$data = [
'speed' => rand(0, 100),
'speed_limit' => rand(0, 100),
];
}

$events->push(new TripEvent([
'type' => $event,
'trip_id' => $this->trip->id,
'distance' => rand(0, 100),
'data' => $data,
]));
}
}
}

protected function getTimeLineEvents(): TimelineValueObject
{
$events = $this->getEvents();

// $this->fakeData($events);

return new TimelineValueObject($events);
}

protected function countEvents(TripEventEnum $event): int
{
return $this->getEvents()->where('type', $event)->count();
}
}
40 changes: 40 additions & 0 deletions app/Domain/Trip/Helper/Parsers/Profile/BreakingProfileParser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace App\Domain\Trip\Helper\Parsers\Profile;

use App\Domain\Trip\Enum\TripEventEnum;
use App\Domain\Trip\Enum\TripStatisticParserEnum;
use App\Domain\Trip\Model\Trip;
use App\Domain\Trip\ValueObject\Statistic\ProfileEventValueObject;
use App\Domain\Trip\ValueObject\Statistic\ProfileStatisticValueObject;

class BreakingProfileParser extends AbstractProfileParser
{
protected function getParserEnum(): TripStatisticParserEnum
{
return TripStatisticParserEnum::BREAK_PROFILE;
}

protected function getProfileTitle(): string
{
return 'Breaking';
}

protected function getProfileStatistics(): array
{
return [
new ProfileStatisticValueObject(
title: 'Abrupt Braking',
value: $this->countEvents(TripEventEnum::HARSH_BRAKING)
),
new ProfileStatisticValueObject(
title: 'Incorrect paddle usage',
value: $this->countEvents(TripEventEnum::BREAKING_AND_GAS)
),
];
}

public function parse(Trip $trip): void
{
}
}
40 changes: 40 additions & 0 deletions app/Domain/Trip/Helper/Parsers/Profile/GearProfileParser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace App\Domain\Trip\Helper\Parsers\Profile;

use App\Domain\Trip\Enum\TripEventEnum;
use App\Domain\Trip\Enum\TripStatisticParserEnum;
use App\Domain\Trip\Model\Trip;
use App\Domain\Trip\ValueObject\Statistic\ProfileEventValueObject;
use App\Domain\Trip\ValueObject\Statistic\ProfileStatisticValueObject;

class GearProfileParser extends AbstractProfileParser
{
protected function getParserEnum(): TripStatisticParserEnum
{
return TripStatisticParserEnum::GEAR_PROFILE;
}

protected function getProfileTitle(): string
{
return 'Gear';
}

protected function getProfileStatistics(): array
{
return [
new ProfileStatisticValueObject(
title: 'Engagement Omitted',
value: $this->countEvents(TripEventEnum::MISSED_GEAR)
),
new ProfileStatisticValueObject(
title: 'Late Shift',
value: $this->countEvents(TripEventEnum::LATE_SHIFT_GEAR)
)
];
}

public function parse(Trip $trip): void
{
}
}
51 changes: 51 additions & 0 deletions app/Domain/Trip/Helper/Parsers/Profile/SpeedProfileParser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

namespace App\Domain\Trip\Helper\Parsers\Profile;

use App\Domain\Trip\Enum\TripStatisticParserEnum;
use App\Domain\Trip\Model\Trip;
use App\Domain\Trip\ValueObject\Statistic\ProfileEventValueObject;
use App\Domain\Trip\ValueObject\Statistic\ProfileStatisticValueObject;

class SpeedProfileParser extends AbstractProfileParser
{
protected int $averageSpeed = 0;

protected function getParserEnum(): TripStatisticParserEnum
{
return TripStatisticParserEnum::SPEED_PROFILE;
}

protected function getProfileTitle(): string
{
return 'Speed';
}

protected function getProfileStatistics(): array
{
return [
new ProfileStatisticValueObject(
title: 'Average speed',
value: $this->averageSpeed,
unit: 'km/h'
)
];
}

public function parse(Trip $trip): void
{
$statistic = $this->getTripStatistic(true);

$statistic->data = [
'averageSpeed' => $trip->data()->avg('speed'),
];

$statistic->save();
}

public function getAverageSpeed(): int
{
return $this->averageSpeed;
}

}
Loading

0 comments on commit 32aad2b

Please sign in to comment.