mirror of
https://github.com/teslamate-org/teslamate.git
synced 2026-01-24 21:06:08 +08:00
Calculate statistics when closing a trip
This commit is contained in:
+45
-38
@@ -95,48 +95,55 @@ defmodule TeslaMate.Log do
|
||||
end
|
||||
|
||||
def close_trip(trip_id) do
|
||||
# TODO statistics
|
||||
attrs = %{}
|
||||
# TODO
|
||||
# :start_address
|
||||
# :end_address
|
||||
|
||||
with {:ok, _trip} <-
|
||||
Trip
|
||||
|> Repo.get!(trip_id)
|
||||
|> Trip.changeset(attrs)
|
||||
|> Repo.update() do
|
||||
:ok
|
||||
end
|
||||
trip =
|
||||
Trip
|
||||
|> Repo.get!(trip_id)
|
||||
|> Repo.preload([:car])
|
||||
|
||||
# statistics =
|
||||
# Position
|
||||
# |> select([p], %{
|
||||
# outside_temp_avg: fragment("?::float", avg(p.outside_temp)),
|
||||
# speed_max: max(p.speed),
|
||||
# speed_min: min(p.speed),
|
||||
# power_max: max(p.power),
|
||||
# power_min: min(p.power),
|
||||
# power_avg: fragment("?::float", avg(p.power))
|
||||
# })
|
||||
# |> where(
|
||||
# [p],
|
||||
# car_id == p.car_id and ^start_position_id <= p.id and p.id <= ^end_position_id
|
||||
# )
|
||||
# |> Repo.one!()
|
||||
# |> Map.to_list()
|
||||
stats =
|
||||
Position
|
||||
|> where(trip_id: ^trip_id)
|
||||
|> select([p, c], %{
|
||||
end_date: max(p.date),
|
||||
outside_temp_avg: avg(p.outside_temp),
|
||||
speed_max: max(p.speed),
|
||||
power_max: max(p.power),
|
||||
power_min: min(p.power),
|
||||
power_avg: avg(p.power),
|
||||
start_km: min(p.odometer),
|
||||
end_km: max(p.odometer),
|
||||
distance: max(p.odometer) - min(p.odometer),
|
||||
start_range_km: min(p.ideal_battery_range_km),
|
||||
end_range_km: max(p.ideal_battery_range_km),
|
||||
duration_min:
|
||||
fragment(
|
||||
"(EXTRACT(EPOCH FROM (?::timestamp - ?::timestamp)) / 60)::integer",
|
||||
max(p.date),
|
||||
min(p.date)
|
||||
)
|
||||
})
|
||||
|> join(:left, [p], c in Car, on: c.id == p.car_id)
|
||||
|> group_by(:car_id)
|
||||
|> Repo.one()
|
||||
|
||||
# result =
|
||||
# Trip
|
||||
# |> where(
|
||||
# [d],
|
||||
# car_id == d.car_id and d.start_position_id == ^start_position_id and
|
||||
# d.end_position_id == ^end_position_id
|
||||
# )
|
||||
# |> update(set: ^statistics)
|
||||
# |> Repo.update_all([])
|
||||
stats =
|
||||
stats
|
||||
|> Map.put(
|
||||
:consumption_kWh,
|
||||
(stats.end_range_km - stats.start_range_km) * trip.car.efficiency
|
||||
)
|
||||
|> Map.put(
|
||||
:consumption_kWh_100km,
|
||||
if(stats.distance > 0, do: stats.consumption_kWh / stats.distance * 100, else: nil)
|
||||
)
|
||||
|
||||
# case result do
|
||||
# {0, nil} -> {:erorr, :no_trips_to_be_updated}
|
||||
# {1, nil} -> :ok
|
||||
# end
|
||||
trip
|
||||
|> Trip.changeset(stats)
|
||||
|> Repo.update()
|
||||
end
|
||||
|
||||
alias TeslaMate.Log.{ChargingProcess, Charge}
|
||||
|
||||
@@ -11,7 +11,6 @@ defmodule TeslaMate.Log.Trip do
|
||||
field :outside_temp_avg, :float
|
||||
|
||||
field :speed_max, :integer
|
||||
field :speed_min, :integer
|
||||
|
||||
field :power_max, :float
|
||||
field :power_min, :float
|
||||
@@ -45,7 +44,6 @@ defmodule TeslaMate.Log.Trip do
|
||||
:end_date,
|
||||
:outside_temp_avg,
|
||||
:speed_max,
|
||||
:speed_min,
|
||||
:power_max,
|
||||
:power_min,
|
||||
:power_avg,
|
||||
|
||||
@@ -137,8 +137,7 @@ defmodule TeslaMate.Vehicles.Vehicle do
|
||||
|
||||
:ok = call(data.deps.log, :start_state, [data.car_id, :online])
|
||||
|
||||
{:next_state, :online, %Data{data | last_used: DateTime.utc_now()},
|
||||
{:next_event, :internal, event}}
|
||||
{:next_state, :online, data, {:next_event, :internal, event}}
|
||||
end
|
||||
|
||||
### :online
|
||||
@@ -241,9 +240,10 @@ defmodule TeslaMate.Vehicles.Vehicle do
|
||||
{:keep_state, %Data{data | last_used: DateTime.utc_now()}, schedule_fetch(10)}
|
||||
|
||||
nil ->
|
||||
Logger.info("Driving / Ended")
|
||||
{:ok, %Log.Trip{distance: distance, duration_min: duration}} =
|
||||
call(data.deps.log, :close_trip, [trip_id])
|
||||
|
||||
:ok = call(data.deps.log, :close_trip, [trip_id])
|
||||
Logger.info("Driving / Ended / #{Float.round(distance, 1)} km – #{duration} min")
|
||||
|
||||
{:next_state, :start, %Data{data | last_used: DateTime.utc_now()},
|
||||
{:next_event, :internal, {:update, {:online, vehicle_state}}}}
|
||||
|
||||
@@ -7,7 +7,6 @@ defmodule TeslaMate.Repo.Migrations.CreateTrips do
|
||||
add(:end_date, :utc_datetime)
|
||||
add(:outside_temp_avg, :float)
|
||||
add(:speed_max, :integer)
|
||||
add(:speed_min, :integer)
|
||||
add(:power_max, :float)
|
||||
add(:power_min, :float)
|
||||
add(:power_avg, :float)
|
||||
|
||||
@@ -4,7 +4,7 @@ defmodule LogMock do
|
||||
defstruct [:pid]
|
||||
alias __MODULE__, as: State
|
||||
|
||||
alias TeslaMate.Log.Car
|
||||
alias TeslaMate.Log.{Trip, Car}
|
||||
|
||||
# API
|
||||
|
||||
@@ -62,6 +62,11 @@ defmodule LogMock do
|
||||
{:reply, {:ok, 111}, state}
|
||||
end
|
||||
|
||||
def handle_call({:close_trip, _trip_id} = action, _from, %State{pid: pid} = state) do
|
||||
send(pid, action)
|
||||
{:reply, {:ok, %Trip{}}, state}
|
||||
end
|
||||
|
||||
def handle_call(action, _from, %State{pid: pid} = state) do
|
||||
send(pid, action)
|
||||
{:reply, :ok, state}
|
||||
|
||||
Reference in New Issue
Block a user