Skip to content

Commit

Permalink
streamline prediction destination code (#827)
Browse files Browse the repository at this point in the history
  • Loading branch information
panentheos authored Oct 8, 2024
1 parent 8e40add commit 666eeb5
Show file tree
Hide file tree
Showing 8 changed files with 207 additions and 254 deletions.
86 changes: 32 additions & 54 deletions lib/content/message/predictions.ex
Original file line number Diff line number Diff line change
Expand Up @@ -88,34 +88,23 @@ defmodule Content.Message.Predictions do
do: {nil, nil},
else: do_crowding(prediction, sign)

case Content.Utilities.destination_for_prediction(
prediction.route_id,
prediction.direction_id,
prediction.destination_stop_id
) do
{:ok, destination} ->
%__MODULE__{
destination: destination,
minutes: minutes,
approximate?: approximate?,
route_id: prediction.route_id,
stop_id: prediction.stop_id,
trip_id: prediction.trip_id,
direction_id: prediction.direction_id,
width: width,
new_cars?: sign.location_engine.for_vehicle(prediction.vehicle_id) |> new_cars?(),
station_code: station_code,
zone: zone,
platform: platform,
certainty: certainty,
crowding_data_confidence: crowding_data_confidence,
crowding_description: crowding_description
}

{:error, _} ->
Logger.warn("no_destination_for_prediction #{inspect(prediction)}")
nil
end
%__MODULE__{
destination: Content.Utilities.destination_for_prediction(prediction),
minutes: minutes,
approximate?: approximate?,
route_id: prediction.route_id,
stop_id: prediction.stop_id,
trip_id: prediction.trip_id,
direction_id: prediction.direction_id,
width: width,
new_cars?: sign.location_engine.for_vehicle(prediction.vehicle_id) |> new_cars?(),
station_code: station_code,
zone: zone,
platform: platform,
certainty: certainty,
crowding_data_confidence: crowding_data_confidence,
crowding_description: crowding_description
}
end

@spec terminal(
Expand All @@ -137,32 +126,21 @@ defmodule Content.Message.Predictions do
x -> compute_minutes(x, prediction.departure_certainty)
end

case Content.Utilities.destination_for_prediction(
prediction.route_id,
prediction.direction_id,
prediction.destination_stop_id
) do
{:ok, destination} ->
%__MODULE__{
destination: destination,
minutes: minutes,
approximate?: approximate?,
route_id: prediction.route_id,
stop_id: prediction.stop_id,
trip_id: prediction.trip_id,
direction_id: prediction.direction_id,
width: width,
new_cars?: sign.location_engine.for_vehicle(prediction.vehicle_id) |> new_cars?(),
station_code: station_code,
zone: zone,
terminal?: true,
certainty: prediction.departure_certainty
}

{:error, _} ->
Logger.warn("no_destination_for_prediction #{inspect(prediction)}")
nil
end
%__MODULE__{
destination: Content.Utilities.destination_for_prediction(prediction),
minutes: minutes,
approximate?: approximate?,
route_id: prediction.route_id,
stop_id: prediction.stop_id,
trip_id: prediction.trip_id,
direction_id: prediction.direction_id,
width: width,
new_cars?: sign.location_engine.for_vehicle(prediction.vehicle_id) |> new_cars?(),
station_code: station_code,
zone: zone,
terminal?: true,
certainty: prediction.departure_certainty
}
end

defp compute_minutes(sec, certainty) do
Expand Down
33 changes: 11 additions & 22 deletions lib/content/message/stopped_train.ex
Original file line number Diff line number Diff line change
Expand Up @@ -27,28 +27,17 @@ defmodule Content.Message.StoppedTrain do

@spec from_prediction(Predictions.Prediction.t()) :: t() | nil
def from_prediction(%{boarding_status: status} = prediction) when not is_nil(status) do
case Content.Utilities.destination_for_prediction(
prediction.route_id,
prediction.direction_id,
prediction.destination_stop_id
) do
{:ok, destination} ->
stops_away = parse_stops_away(prediction.boarding_status)

%__MODULE__{
destination: destination,
stops_away: stops_away,
certainty: prediction.arrival_certainty || prediction.departure_certainty,
stop_id: prediction.stop_id,
trip_id: prediction.trip_id,
route_id: prediction.route_id,
direction_id: prediction.direction_id
}

{:error, _} ->
Logger.warn("no_destination_for_prediction #{inspect(prediction)}")
nil
end
stops_away = parse_stops_away(prediction.boarding_status)

%__MODULE__{
destination: Content.Utilities.destination_for_prediction(prediction),
stops_away: stops_away,
certainty: prediction.arrival_certainty || prediction.departure_certainty,
stop_id: prediction.stop_id,
trip_id: prediction.trip_id,
route_id: prediction.route_id,
direction_id: prediction.direction_id
}
end

defp parse_stops_away(str) do
Expand Down
129 changes: 76 additions & 53 deletions lib/content/utilities.ex
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,21 @@ defmodule Content.Utilities do
|> Enum.max()
end

@spec destination_for_prediction(String.t(), 0 | 1, String.t()) ::
{:ok, PaEss.destination()} | {:error, :not_found}
def destination_for_prediction("Mattapan", 0, _), do: {:ok, :mattapan}
def destination_for_prediction("Mattapan", 1, _), do: {:ok, :ashmont}
def destination_for_prediction("Orange", 0, _), do: {:ok, :forest_hills}
def destination_for_prediction("Orange", 1, _), do: {:ok, :oak_grove}
def destination_for_prediction("Blue", 0, _), do: {:ok, :bowdoin}
def destination_for_prediction("Blue", 1, _), do: {:ok, :wonderland}
def destination_for_prediction("Red", 1, _), do: {:ok, :alewife}

def destination_for_prediction("Red", 0, last_stop_id)
when last_stop_id in ["70085", "70086", "70087", "70089", "70091", "70093"],
do: {:ok, :ashmont}

def destination_for_prediction("Red", 0, last_stop_id)
when last_stop_id in [
@spec destination_for_prediction(Predictions.Prediction.t()) :: PaEss.destination()
def destination_for_prediction(%{route_id: "Mattapan", direction_id: 0}), do: :mattapan
def destination_for_prediction(%{route_id: "Mattapan", direction_id: 1}), do: :ashmont
def destination_for_prediction(%{route_id: "Orange", direction_id: 0}), do: :forest_hills
def destination_for_prediction(%{route_id: "Orange", direction_id: 1}), do: :oak_grove
def destination_for_prediction(%{route_id: "Blue", direction_id: 0}), do: :bowdoin
def destination_for_prediction(%{route_id: "Blue", direction_id: 1}), do: :wonderland
def destination_for_prediction(%{route_id: "Red", direction_id: 1}), do: :alewife

def destination_for_prediction(%{route_id: "Red", direction_id: 0, destination_stop_id: stop_id})
when stop_id in ["70085", "70086", "70087", "70089", "70091", "70093"],
do: :ashmont

def destination_for_prediction(%{route_id: "Red", direction_id: 0, destination_stop_id: stop_id})
when stop_id in [
"70095",
"70096",
"70097",
Expand All @@ -45,43 +44,67 @@ defmodule Content.Utilities do
"Braintree-01",
"Braintree-02"
],
do: {:ok, :braintree}

def destination_for_prediction("Red", 0, _), do: {:ok, :southbound}

def destination_for_prediction(_, 0, "70151"), do: {:ok, :kenmore}
def destination_for_prediction(_, 0, "71151"), do: {:ok, :kenmore}
def destination_for_prediction(_, 0, "70202"), do: {:ok, :government_center}
def destination_for_prediction(_, 0, "70201"), do: {:ok, :government_center}
def destination_for_prediction(_, 0, "70175"), do: {:ok, :reservoir}
def destination_for_prediction(_, 0, "70107"), do: {:ok, :boston_college}
def destination_for_prediction(_, 0, "70237"), do: {:ok, :cleveland_circle}
def destination_for_prediction(_, 0, "70161"), do: {:ok, :riverside}
def destination_for_prediction(_, 0, "70260"), do: {:ok, :heath_street}

def destination_for_prediction(_, 1, "70205"), do: {:ok, :north_station}
def destination_for_prediction(_, 1, "70511"), do: {:ok, :medford_tufts}
def destination_for_prediction(_, 1, "70503"), do: {:ok, :union_square}
def destination_for_prediction(_, 1, "70501"), do: {:ok, :lechmere}
def destination_for_prediction(_, 1, "70201"), do: {:ok, :government_center}
def destination_for_prediction(_, 1, "70200"), do: {:ok, :park_street}
def destination_for_prediction(_, 1, "71199"), do: {:ok, :park_street}
def destination_for_prediction(_, 1, "70150"), do: {:ok, :kenmore}
def destination_for_prediction(_, 1, "71150"), do: {:ok, :kenmore}
def destination_for_prediction(_, 1, "70174"), do: {:ok, :reservoir}

def destination_for_prediction(_, _, "Government Center-Brattle"), do: {:ok, :government_center}

def destination_for_prediction("Green-B", 0, _), do: {:ok, :boston_college}
def destination_for_prediction("Green-C", 0, _), do: {:ok, :cleveland_circle}
def destination_for_prediction("Green-D", 0, _), do: {:ok, :riverside}
def destination_for_prediction("Green-E", 0, _), do: {:ok, :heath_street}
def destination_for_prediction("Green-B", 1, _), do: {:ok, :government_center}
def destination_for_prediction("Green-C", 1, _), do: {:ok, :government_center}
def destination_for_prediction("Green-D", 1, _), do: {:ok, :union_square}
def destination_for_prediction("Green-E", 1, _), do: {:ok, :medford_tufts}

def destination_for_prediction(_, _, _), do: {:error, :not_found}
do: :braintree

def destination_for_prediction(%{route_id: "Red", direction_id: 0}), do: :southbound

def destination_for_prediction(%{direction_id: 0, destination_stop_id: "70151"}), do: :kenmore
def destination_for_prediction(%{direction_id: 0, destination_stop_id: "71151"}), do: :kenmore

def destination_for_prediction(%{direction_id: 0, destination_stop_id: "70202"}),
do: :government_center

def destination_for_prediction(%{direction_id: 0, destination_stop_id: "70201"}),
do: :government_center

def destination_for_prediction(%{direction_id: 0, destination_stop_id: "70175"}), do: :reservoir

def destination_for_prediction(%{direction_id: 0, destination_stop_id: "70107"}),
do: :boston_college

def destination_for_prediction(%{direction_id: 0, destination_stop_id: "70237"}),
do: :cleveland_circle

def destination_for_prediction(%{direction_id: 0, destination_stop_id: "70161"}), do: :riverside

def destination_for_prediction(%{direction_id: 0, destination_stop_id: "70260"}),
do: :heath_street

def destination_for_prediction(%{direction_id: 1, destination_stop_id: "70205"}),
do: :north_station

def destination_for_prediction(%{direction_id: 1, destination_stop_id: "70511"}),
do: :medford_tufts

def destination_for_prediction(%{direction_id: 1, destination_stop_id: "70503"}),
do: :union_square

def destination_for_prediction(%{direction_id: 1, destination_stop_id: "70501"}), do: :lechmere

def destination_for_prediction(%{direction_id: 1, destination_stop_id: "70201"}),
do: :government_center

def destination_for_prediction(%{direction_id: 1, destination_stop_id: "70200"}),
do: :park_street

def destination_for_prediction(%{direction_id: 1, destination_stop_id: "71199"}),
do: :park_street

def destination_for_prediction(%{direction_id: 1, destination_stop_id: "70150"}), do: :kenmore
def destination_for_prediction(%{direction_id: 1, destination_stop_id: "71150"}), do: :kenmore
def destination_for_prediction(%{direction_id: 1, destination_stop_id: "70174"}), do: :reservoir

def destination_for_prediction(%{destination_stop_id: "Government Center-Brattle"}),
do: :government_center

def destination_for_prediction(%{route_id: "Green-B", direction_id: 0}), do: :boston_college
def destination_for_prediction(%{route_id: "Green-C", direction_id: 0}), do: :cleveland_circle
def destination_for_prediction(%{route_id: "Green-D", direction_id: 0}), do: :riverside
def destination_for_prediction(%{route_id: "Green-E", direction_id: 0}), do: :heath_street
def destination_for_prediction(%{route_id: "Green-B", direction_id: 1}), do: :government_center
def destination_for_prediction(%{route_id: "Green-C", direction_id: 1}), do: :government_center
def destination_for_prediction(%{route_id: "Green-D", direction_id: 1}), do: :union_square
def destination_for_prediction(%{route_id: "Green-E", direction_id: 1}), do: :medford_tufts

@spec stop_track_number(String.t()) :: track_number() | nil
def stop_track_number("Alewife-01"), do: 1
Expand Down
40 changes: 12 additions & 28 deletions lib/signs/utilities/predictions.ex
Original file line number Diff line number Diff line change
Expand Up @@ -134,35 +134,19 @@ defmodule Signs.Utilities.Predictions do
end)
|> Enum.sort_by(fn prediction -> prediction.seconds_until_passthrough end)
|> Enum.flat_map(fn prediction ->
route_id = prediction.route_id

case Content.Utilities.destination_for_prediction(
route_id,
prediction.direction_id,
prediction.destination_stop_id
) do
{:ok, :southbound} when route_id == "Red" ->
[
%Content.Audio.Passthrough{
destination: :ashmont,
trip_id: prediction.trip_id,
route_id: prediction.route_id
}
]

{:ok, destination} ->
[
%Content.Audio.Passthrough{
destination: destination,
trip_id: prediction.trip_id,
route_id: prediction.route_id
}
]
destination =
case Content.Utilities.destination_for_prediction(prediction) do
:southbound -> :ashmont
destination -> destination
end

_ ->
Logger.info("no_passthrough_audio_for_prediction prediction=#{inspect(prediction)}")
[]
end
[
%Content.Audio.Passthrough{
destination: destination,
trip_id: prediction.trip_id,
route_id: prediction.route_id
}
]
end)
|> Enum.take(1)
end
Expand Down
55 changes: 0 additions & 55 deletions test/content/messages/predictions_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,6 @@ defmodule Content.Message.PredictionsTest do
:ok
end

test "logs a warning when we cant find a headsign" do
prediction = %Predictions.Prediction{
seconds_until_arrival: 0,
direction_id: 1,
route_id: "NON-ROUTE",
stopped?: false,
stops_away: 1,
destination_stop_id: "70261"
}

log =
capture_log([level: :warn], fn ->
assert is_nil(Content.Message.Predictions.non_terminal(prediction, "test", "m", @sign))
end)

assert log =~ "no_destination_for_prediction"
end

test "puts ARR on the sign when train is 0 seconds away, but not boarding" do
prediction = %Predictions.Prediction{
seconds_until_arrival: 0,
Expand Down Expand Up @@ -288,43 +270,6 @@ defmodule Content.Message.PredictionsTest do
:ok
end

test "logs a warning when we cant find a headsign, even if it should be boarding" do
prediction = %Predictions.Prediction{
seconds_until_departure: 0,
direction_id: 1,
route_id: "NON-ROUTE",
destination_stop_id: "70261",
stopped?: false,
stops_away: 0,
boarding_status: "Boarding"
}

log =
capture_log([level: :warn], fn ->
assert is_nil(Content.Message.Predictions.terminal(prediction, "test", "m", @sign))
end)

assert log =~ "no_destination_for_prediction"
end

test "logs a warning when we cant find a headsign" do
prediction = %Predictions.Prediction{
seconds_until_departure: 0,
direction_id: 1,
route_id: "NON-ROUTE",
stopped?: false,
stops_away: 1,
destination_stop_id: "70261"
}

log =
capture_log([level: :warn], fn ->
assert is_nil(Content.Message.Predictions.terminal(prediction, "test", "m", @sign))
end)

assert log =~ "no_destination_for_prediction"
end

test "puts boarding on the sign when train is supposed to be boarding according to rtr" do
prediction = %Predictions.Prediction{
seconds_until_departure: 75,
Expand Down
Loading

0 comments on commit 666eeb5

Please sign in to comment.