diff --git a/lib/teslamate/log.ex b/lib/teslamate/log.ex index d149fe17..3f369927 100644 --- a/lib/teslamate/log.ex +++ b/lib/teslamate/log.ex @@ -212,7 +212,22 @@ defmodule TeslaMate.Log do |> Repo.insert() end - def close_charging_process(process_id) do + def resume_charging_process(process_id) do + ChargingProcess + |> preload([:car, :position]) + |> Repo.get!(process_id) + |> ChargingProcess.changeset(%{ + end_date: nil, + charge_energy_added: nil, + end_range_km: nil, + end_battery_level: nil, + duration_min: nil, + calculated_max_range: nil + }) + |> Repo.update() + end + + def complete_charging_process(process_id) do charging_process = ChargingProcess |> preload([:car, :position]) diff --git a/lib/teslamate/vehicles/vehicle/vehicle.ex b/lib/teslamate/vehicles/vehicle/vehicle.ex index ca09ca12..ed6a1cb8 100644 --- a/lib/teslamate/vehicles/vehicle/vehicle.ex +++ b/lib/teslamate/vehicles/vehicle/vehicle.ex @@ -272,7 +272,10 @@ defmodule TeslaMate.Vehicles.Vehicle do def handle_event(:internal, {:update, {:online, vehicle}}, {:charging, last, pid} = s, data) do case {vehicle.charge_state.charging_state, last} do {charging_state, last_state} when charging_state in ["Starting", "Charging"] -> - if last_state == "Complete", do: Logger.info("Charging / Restart", car_id: data.car.id) + if last_state == "Complete" do + Logger.info("Charging / Restart", car_id: data.car.id) + {:ok, _cproc} = call(data.deps.log, :resume_charging_process, [pid]) + end :ok = insert_charge(pid, vehicle, data) @@ -288,16 +291,19 @@ defmodule TeslaMate.Vehicles.Vehicle do try_to_suspend(vehicle, s, data) {"Complete", "Charging"} -> - Logger.info("Charging / Complete", car_id: data.car.id) - :ok = insert_charge(pid, vehicle, data) + {:ok, %Log.ChargingProcess{duration_min: duration, charge_energy_added: added}} = + call(data.deps.log, :complete_charging_process, [pid]) + + Logger.info("Charging / Complete / #{added} kWh – #{duration} min", car_id: data.car.id) + {:next_state, {:charging, "Complete", pid}, %Data{data | last_used: DateTime.utc_now()}, [notify_subscribers(), schedule_fetch()]} {charging_state, _} -> {:ok, %Log.ChargingProcess{duration_min: duration, charge_energy_added: added}} = - call(data.deps.log, :close_charging_process, [pid]) + call(data.deps.log, :complete_charging_process, [pid]) Logger.info("Charging / #{charging_state} / #{added} kWh – #{duration} min", car_id: data.car.id diff --git a/test/support/mocks/log.ex b/test/support/mocks/log.ex index 6eb4fdf6..d3655da7 100644 --- a/test/support/mocks/log.ex +++ b/test/support/mocks/log.ex @@ -27,8 +27,12 @@ defmodule LogMock do GenServer.call(name, {:start_charging_process, car_id, position_attrs}) end - def close_charging_process(name, process_id) do - GenServer.call(name, {:close_charging_process, process_id}) + def resume_charging_process(name, process_id) do + GenServer.call(name, {:resume_charging_process, process_id}) + end + + def complete_charging_process(name, process_id) do + GenServer.call(name, {:complete_charging_process, process_id}) end def insert_position(name, car_id, attrs) do @@ -52,7 +56,12 @@ defmodule LogMock do {:reply, {:ok, 99}, state} end - def handle_call({:close_charging_process, _pid} = action, _from, %State{pid: pid} = state) do + def handle_call({:resume_charging_process, _pid} = action, _from, %State{pid: pid} = state) do + send(pid, action) + {:reply, {:ok, %ChargingProcess{}}, state} + end + + def handle_call({:complete_charging_process, _pid} = action, _from, %State{pid: pid} = state) do send(pid, action) {:reply, {:ok, %ChargingProcess{}}, state} end diff --git a/test/teslamate/log/log_charging_test.exs b/test/teslamate/log/log_charging_test.exs index 94fcbdbe..04d88cc4 100644 --- a/test/teslamate/log/log_charging_test.exs +++ b/test/teslamate/log/log_charging_test.exs @@ -113,7 +113,7 @@ defmodule TeslaMate.LogChargingTest do end end - describe "close_charging_process/1" do + describe "complete_charging_process/1" do test "aggregates charging data" do assert %Car{id: car_id} = car_fixture() assert {:ok, charging_process_id} = Log.start_charging_process(car_id, @valid_pos_attrs) @@ -173,7 +173,8 @@ defmodule TeslaMate.LogChargingTest do assert {:ok, %Charge{} = charge} = Log.insert_charge(charging_process_id, c) end - assert {:ok, %ChargingProcess{} = cproc} = Log.close_charging_process(charging_process_id) + assert {:ok, %ChargingProcess{} = cproc} = + Log.complete_charging_process(charging_process_id) assert %DateTime{} = cproc.start_date assert %DateTime{} = cproc.end_date @@ -190,10 +191,113 @@ defmodule TeslaMate.LogChargingTest do test "closes charging process with zero charges " do assert %Car{id: car_id} = car_fixture() assert {:ok, charging_process_id} = Log.start_charging_process(car_id, @valid_pos_attrs) - assert {:ok, %ChargingProcess{} = cproc} = Log.close_charging_process(charging_process_id) + + assert {:ok, %ChargingProcess{} = cproc} = + Log.complete_charging_process(charging_process_id) assert %DateTime{} = cproc.start_date assert %DateTime{} = cproc.end_date end end + + describe "resume_charging_process/1" do + test "resets some fields" do + assert %Car{id: car_id} = car_fixture() + assert {:ok, charging_process_id} = Log.start_charging_process(car_id, @valid_pos_attrs) + + charges = [ + %{ + date: "2019-04-05 16:01:27", + battery_level: 50, + charge_energy_added: 0.41, + charger_actual_current: 5, + charger_phases: 3, + charger_pilot_current: 16, + charger_power: 4, + charger_voltage: 234, + ideal_battery_range_km: 266.6, + outside_temp: 16 + }, + %{ + date: "2019-04-05 16:05:40", + battery_level: 54, + charge_energy_added: 0.72, + charger_actual_current: 5, + charger_phases: 3, + charger_pilot_current: 16, + charger_power: 4, + charger_voltage: 234, + ideal_battery_range_km: 268.6, + outside_temp: 14.5 + } + ] + + for c <- charges do + assert {:ok, %Charge{} = charge} = Log.insert_charge(charging_process_id, c) + end + + assert {:ok, %ChargingProcess{} = cproc} = + Log.complete_charging_process(charging_process_id) + + assert %DateTime{} = start_date = cproc.start_date + assert %DateTime{} = cproc.end_date + assert cproc.calculated_max_range == 497 + assert cproc.charge_energy_added == 0.72 + assert cproc.duration_min == 4 + assert cproc.end_battery_level == 54 + assert cproc.start_battery_level == 50 + assert cproc.start_range_km == 266.6 + assert cproc.end_range_km == 268.6 + assert cproc.outside_temp_avg == 15.25 + + # RESUME + + assert {:ok, %ChargingProcess{} = cproc} = Log.resume_charging_process(charging_process_id) + + assert ^start_date = cproc.start_date + assert cproc.start_battery_level == 50 + assert cproc.start_range_km == 266.6 + assert cproc.outside_temp_avg == 15.25 + + assert cproc.end_date == nil + assert cproc.calculated_max_range == nil + assert cproc.charge_energy_added == nil + assert cproc.duration_min == nil + assert cproc.end_battery_level == nil + assert cproc.end_range_km == nil + + charges = [ + %{ + date: "2019-04-05 16:15:40", + battery_level: 55, + charge_energy_added: 1.12, + charger_actual_current: 5, + charger_phases: 3, + charger_pilot_current: 16, + charger_power: 4, + charger_voltage: 234, + ideal_battery_range_km: 278.6, + outside_temp: 15.01 + } + ] + + for c <- charges do + assert {:ok, %Charge{} = charge} = Log.insert_charge(charging_process_id, c) + end + + assert {:ok, %ChargingProcess{} = cproc} = + Log.complete_charging_process(charging_process_id) + + assert ^start_date = cproc.start_date + assert %DateTime{} = cproc.end_date + assert cproc.calculated_max_range == 507 + assert cproc.charge_energy_added == 1.12 + assert cproc.duration_min == 14 + assert cproc.end_battery_level == 55 + assert cproc.start_battery_level == 50 + assert cproc.start_range_km == 266.6 + assert cproc.end_range_km == 278.6 + assert cproc.outside_temp_avg == 15.17 + end + end end diff --git a/test/teslamate/vehicles/vehicle/charging_test.exs b/test/teslamate/vehicles/vehicle/charging_test.exs index 978a3596..ef38df4d 100644 --- a/test/teslamate/vehicles/vehicle/charging_test.exs +++ b/test/teslamate/vehicles/vehicle/charging_test.exs @@ -36,7 +36,10 @@ defmodule TeslaMate.Vehicles.Vehicle.ChargingTest do assert_receive {:insert_charge, ^charging_id, %{date: _, charge_energy_added: 0.4}} assert_receive {:pubsub, {:broadcast, _server, _topic, %Summary{state: :charging_complete}}} - assert_receive {:close_charging_process, ^charging_id} + # Completed + assert_receive {:complete_charging_process, ^charging_id} + # Unplugged + assert_receive {:complete_charging_process, ^charging_id} assert_receive {:start_state, ^car_id, :online} assert_receive {:insert_position, ^car_id, %{}} @@ -86,8 +89,9 @@ defmodule TeslaMate.Vehicles.Vehicle.ChargingTest do assert_receive {:insert_charge, ^charging_id, %{date: _, charge_energy_added: 0.3}} assert_receive {:pubsub, {:broadcast, _server, _topic, %Summary{state: :charging_complete}}} + assert_receive {:complete_charging_process, ^charging_id} - assert_receive {:close_charging_process, ^charging_id} + assert_receive {:complete_charging_process, ^charging_id} assert_receive {:start_state, ^car_id, :online} assert_receive {:insert_position, ^car_id, %{}} diff --git a/test/teslamate/vehicles/vehicle/suspend_test.exs b/test/teslamate/vehicles/vehicle/suspend_test.exs index c6e18016..ed9e9326 100644 --- a/test/teslamate/vehicles/vehicle/suspend_test.exs +++ b/test/teslamate/vehicles/vehicle/suspend_test.exs @@ -220,6 +220,7 @@ defmodule TeslaMate.Vehicles.Vehicle.SuspendTest do assert_receive {:insert_charge, charge_id, %{date: _, charge_energy_added: 0.1}} assert_receive {:pubsub, {:broadcast, _server, _topic, %Summary{state: :charging_complete}}} assert_receive {:insert_charge, ^charge_id, %{date: _, charge_energy_added: 0.2}} + assert_receive {:complete_charging_process, ^charge_id} assert_receive {:pubsub, {:broadcast, _server, _topic, %Summary{state: :suspended}}} @@ -262,6 +263,7 @@ defmodule TeslaMate.Vehicles.Vehicle.SuspendTest do assert_receive {:insert_charge, ^charging_event, %{date: _, charge_energy_added: 0.15}} assert_receive {:pubsub, {:broadcast, _server, _topic, %Summary{state: :charging_complete}}} + assert_receive {:complete_charging_process, ^charging_event} assert_receive {:pubsub, {:broadcast, _server, _topic, %Summary{state: :suspended}}} @@ -272,6 +274,7 @@ defmodule TeslaMate.Vehicles.Vehicle.SuspendTest do assert_receive {:pubsub, {:broadcast, _server, _topic, %Summary{state: :charging}}} assert_receive {:insert_charge, ^charging_event, %{date: _, charge_energy_added: 0.3}} + assert_receive {:resume_charging_process, ^charging_event} # ... end diff --git a/test/teslamate/vehicles/vehicle_test.exs b/test/teslamate/vehicles/vehicle_test.exs index 15b66aaf..3043da09 100644 --- a/test/teslamate/vehicles/vehicle_test.exs +++ b/test/teslamate/vehicles/vehicle_test.exs @@ -92,7 +92,7 @@ defmodule TeslaMate.Vehicles.VehicleTest do assert_receive {:pubsub, {:broadcast, _, _, %Summary{state: :charging_complete}}} # Unplugging - assert_receive {:close_charging_process, _} + assert_receive {:complete_charging_process, _} # Online assert_receive {:start_state, ^car_id, :online}