Skip to content

Commit

Permalink
add /metrics/zones/{zone_id}/visiting-time-by-vessel
Browse files Browse the repository at this point in the history
  • Loading branch information
herve.le-bars committed Oct 6, 2024
1 parent e9630e5 commit 3c2be7c
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 22 deletions.
46 changes: 46 additions & 0 deletions backend/bloom/domain/metrics.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from pydantic import BaseModel, ConfigDict
from typing_extensions import Annotated, Literal, Optional
from datetime import datetime, timedelta

class ResponseMetricsVesselInActiviySchema(BaseModel):
id: int
mmsi: int
ship_name: str
width: Optional[float] = None
length: Optional[float] = None
country_iso3: Optional[str] = None
type: Optional[str] = None
imo: Optional[int] = None
cfr: Optional[str] = None
external_marking: Optional[str] = None
ircs: Optional[str] = None
home_port_id: Optional[int] = None
details: Optional[str] = None
tracking_activated: Optional[bool]
tracking_status: Optional[str]
length_class: Optional[str]
check: Optional[str]
total_time_at_sea: timedelta

class ResponseMetricsZoneVisitedSchema(BaseModel):
id : int
category: str
sub_category: Optional[str] = None
name: str
visiting_duration: timedelta

class ResponseMetricsZoneVisitingTimeByVesselSchema(BaseModel):
zone_id : int
zone_category: str
zone_sub_category: Optional[str] = None
zone_name: str
vessel_id : int
vessel_name: str
vessel_type: Optional[str] = None
vessel_length_class: Optional[str] = None
zone_visiting_time_by_vessel: timedelta


class TemporalRequest(BaseModel):
start_at: datetime
end_at: datetime = datetime.now()
84 changes: 62 additions & 22 deletions backend/bloom/routers/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,19 @@
from datetime import datetime, timedelta
from sqlalchemy import select, func, and_, or_
from bloom.infra.database import sql_model
from bloom.domain.segment import Segment
from bloom.infra.repositories.repository_segment import SegmentRepository
import json
from pydantic import BaseModel, ConfigDict
from bloom.domain.metrics import ResponseMetricsVesselInActiviySchema,\
ResponseMetricsZoneVisitedSchema,\
ResponseMetricsZoneVisitingTimeByVesselSchema,\
DatetimeRangeRequest

router = APIRouter()
redis_client = Redis(host=settings.redis_host, port=settings.redis_port, db=0)


class ResponseMetricsVesselInActiviySchema(BaseModel):
id: int
mmsi: int
ship_name: str
width: Optional[float] = None
length: Optional[float] = None
country_iso3: Optional[str] = None
type: Optional[str] = None
imo: Optional[int] = None
cfr: Optional[str] = None
external_marking: Optional[str] = None
ircs: Optional[str] = None
home_port_id: Optional[int] = None
details: Optional[str] = None
tracking_activated: Optional[bool]
tracking_status: Optional[str]
length_class: Optional[str]
check: Optional[str]
total_time_at_sea: timedelta


@router.get("/metrics/vessels-in-activity",
response_model=list[ResponseMetricsVesselInActiviySchema],
Expand Down Expand Up @@ -84,12 +69,67 @@ def read_metrics_vessels_in_activity_total(start_at: datetime,
return session.execute(stmt).all()

@router.get("/metrics/zone-visited",
response_model=list[ResponseMetricsZoneVisitedSchema],
tags=['metrics'] )
def read_metrics_vessels_in_activity_total(start_at: datetime,
end_at: datetime = None,
end_at: datetime = datetime.now(),
limit: int = None,
order_by: str = 'DESC'):
pass
use_cases = UseCases()
db = use_cases.db()
with db.session() as session:
stmt=select(
sql_model.Zone.id.label("zone_id"),
sql_model.Zone.category.label("zone_category"),
sql_model.Zone.sub_category.label("zone_sub_category"),
sql_model.Zone.name.label("zone_name"),
func.sum(sql_model.Segment.segment_duration).label("visiting_duration")
)\
.where(
or_(
sql_model.Segment.timestamp_start.between(start_at,end_at),
sql_model.Segment.timestamp_end.between(start_at,end_at),)
)\
.group_by(sql_model.Zone.id)
stmt = stmt.limit(limit) if limit != None else stmt
stmt = stmt.order_by("visiting_duration")\
if order_by.upper() == 'ASC' \
else stmt.order_by("visiting_duration")
return session.execute(stmt).all()

@router.get("/metrics/zones/{zone_id}/visiting-time-by-vessel",
response_model=list[ResponseMetricsZoneVisitingTimeByVesselSchema],
tags=['metrics'])
def read_metrics_zone_visiting_time_by_vessel(
zone_id: int,
start_at: datetime,
end_at: datetime = datetime.now(),
limit: int = None,
order_by: str = 'DESC'):
use_cases = UseCases()
db = use_cases.db()
with db.session() as session:
stmt=select(
sql_model.Zone.id.label("zone_id"),
sql_model.Zone.category.label("zone_category"),
sql_model.Zone.sub_category.label("zone_sub_category"),
sql_model.Zone.name.label("zone_name"),
sql_model.Vessel.id.label("vessel_id"),
sql_model.Vessel.ship_name.label("vessel_name"),
sql_model.Vessel.type.label("vessel_type"),
sql_model.Vessel.length_class.label("vessel_length_class"),
func.sum(sql_model.Segment.segment_duration).label("zone_visiting_time_by_vessel")
)\
.select_from(sql_model.Zone)\
.join(sql_model.RelSegmentZone, sql_model.RelSegmentZone.zone_id == sql_model.Zone.id)\
.join(sql_model.Segment, sql_model.RelSegmentZone.segment_id == sql_model.Segment.id)\
.join(sql_model.Excursion, sql_model.Excursion.id == sql_model.Segment.excursion_id)\
.join(sql_model.Vessel, sql_model.Excursion.vessel_id == sql_model.Vessel.id)\
.where(sql_model.Zone.id == zone_id)\
.group_by(sql_model.Zone.id,sql_model.Vessel.id)
return session.execute(stmt).all()



@router.get("/metrics/vessels/{vessel_id}/visits/{visit_type}", tags=['metrics'])
def read_metrics_vessels_visits_by_visit_type(
Expand Down

0 comments on commit 3c2be7c

Please sign in to comment.