mirror of
https://github.com/netfun2000/hipudding-teslamate.git
synced 2026-02-27 09:44:28 +08:00
276 lines
11 KiB
Elixir
276 lines
11 KiB
Elixir
defmodule TeslaMate.Vehicles.Vehicle.ChargingTest do
|
|
use TeslaMate.VehicleCase, async: true
|
|
|
|
alias TeslaMate.Vehicles.Vehicle.Summary
|
|
alias TeslaMate.Log.ChargingProcess
|
|
|
|
import ExUnit.CaptureLog
|
|
|
|
@log_opts format: "[$level] $message\n",
|
|
colors: [enabled: false]
|
|
|
|
test "logs a full charging cycle", %{test: name} do
|
|
now_ts = DateTime.utc_now() |> DateTime.to_unix(:millisecond)
|
|
|
|
events = [
|
|
{:ok, online_event()},
|
|
{:ok, online_event(drive_state: %{timestamp: now_ts, latitude: 0.0, longitude: 0.0})},
|
|
{:ok, charging_event(now_ts + 1, "Starting", 0.1, range: 1)},
|
|
{:ok, charging_event(now_ts + 2, "Charging", 0.2, range: 2)},
|
|
{:ok, charging_event(now_ts + 3, "Charging", 0.3, range: 3)},
|
|
{:ok, charging_event(now_ts + 4, "Complete", 0.4, range: 4)},
|
|
{:ok, charging_event(now_ts + 5, "Complete", 0.4, range: 4)},
|
|
{:ok, charging_event(now_ts + 6, "Unplugged", 0.4, range: 4)},
|
|
{:ok, online_event(drive_state: %{timestamp: now_ts + 7, latitude: 0.2, longitude: 0.2})},
|
|
fn -> Process.sleep(10_000) end
|
|
]
|
|
|
|
:ok = start_vehicle(name, events)
|
|
|
|
start_date = DateTime.from_unix!(now_ts, :millisecond)
|
|
assert_receive {:start_state, car, :online, date: ^start_date}, 400
|
|
assert_receive {ApiMock, {:stream, 1000, _}}
|
|
assert_receive {:insert_position, ^car, %{}}
|
|
assert_receive {:pubsub, {:broadcast, _, _, %Summary{state: :online, since: s0}}}
|
|
|
|
assert_receive {:start_charging_process, ^car, %{latitude: 0.0, longitude: 0.0},
|
|
[lookup_address: true]}
|
|
|
|
assert_receive {:"$websockex_cast", :disconnect}
|
|
|
|
assert_receive {:insert_charge, %ChargingProcess{id: _process_id} = cproc,
|
|
%{
|
|
date: _,
|
|
charge_energy_added: 0.1,
|
|
rated_battery_range_km: 1.61,
|
|
ideal_battery_range_km: 1.61
|
|
}}
|
|
|
|
assert_receive {:pubsub, {:broadcast, _, _, %Summary{state: :charging, since: s1}}}
|
|
assert DateTime.diff(s0, s1, :nanosecond) < 0
|
|
|
|
assert_receive {:insert_charge, ^cproc,
|
|
%{
|
|
date: _,
|
|
charge_energy_added: 0.2,
|
|
rated_battery_range_km: 3.22,
|
|
ideal_battery_range_km: 3.22
|
|
}}
|
|
|
|
assert_receive {:pubsub, {:broadcast, _, _, %Summary{state: :charging, since: ^s1}}}
|
|
|
|
assert_receive {:insert_charge, ^cproc,
|
|
%{
|
|
date: _,
|
|
charge_energy_added: 0.3,
|
|
rated_battery_range_km: 4.83,
|
|
ideal_battery_range_km: 4.83
|
|
}}
|
|
|
|
assert_receive {:pubsub, {:broadcast, _, _, %Summary{state: :charging, since: ^s1}}}
|
|
|
|
assert_receive {:insert_position, ^car, %{}}
|
|
|
|
assert_receive {:insert_charge, ^cproc,
|
|
%{
|
|
date: _,
|
|
charge_energy_added: 0.4,
|
|
rated_battery_range_km: 6.44,
|
|
ideal_battery_range_km: 6.44
|
|
}}
|
|
|
|
# Completed
|
|
assert_receive {:complete_charging_process, ^cproc}
|
|
|
|
start_date = DateTime.from_unix!(now_ts + 4, :millisecond)
|
|
assert_receive {:start_state, ^car, :online, date: ^start_date}
|
|
assert_receive {ApiMock, {:stream, 1000, _}}
|
|
assert_receive {:insert_position, ^car, %{}}
|
|
assert_receive {:pubsub, {:broadcast, _, _, %Summary{state: :online, since: s2}}}
|
|
assert DateTime.diff(s1, s2, :nanosecond) < 0
|
|
|
|
assert_receive {:pubsub, {:broadcast, _, _, %Summary{state: :online, since: ^s2}}}
|
|
|
|
refute_receive _
|
|
end
|
|
|
|
@tag :capture_log
|
|
test "handles a connection loss when charging", %{test: name} do
|
|
now_ts = DateTime.utc_now() |> DateTime.to_unix(:millisecond)
|
|
|
|
events = [
|
|
{:ok, online_event()},
|
|
{:ok, online_event(drive_state: %{timestamp: now_ts, latitude: 0.0, longitude: 0.0})},
|
|
{:ok, charging_event(now_ts + 1, "Charging", 0.1)},
|
|
{:ok, charging_event(now_ts + 2, "Charging", 0.2)},
|
|
{:error, :vehicle_unavailable},
|
|
{:ok, %TeslaApi.Vehicle{state: "offline"}},
|
|
{:error, :vehicle_unavailable},
|
|
{:ok, %TeslaApi.Vehicle{state: "unknown"}},
|
|
{:ok, charging_event(now_ts + 3, "Charging", 0.3)},
|
|
{:ok, charging_event(now_ts + 4, "Complete", 0.3)},
|
|
{:ok, charging_event(now_ts + 5, "Complete", 0.3)},
|
|
{:ok, charging_event(now_ts + 6, "Unplugged", 0.3)},
|
|
{:ok, online_event(drive_state: %{timestamp: now_ts + 7, latitude: 0.2, longitude: 0.2})},
|
|
fn -> Process.sleep(10_000) end
|
|
]
|
|
|
|
:ok = start_vehicle(name, events)
|
|
|
|
start_date = DateTime.from_unix!(now_ts, :millisecond)
|
|
assert_receive {:start_state, car, :online, date: ^start_date}
|
|
assert_receive {ApiMock, {:stream, 1000, _}}
|
|
assert_receive {:insert_position, ^car, %{}}
|
|
assert_receive {:pubsub, {:broadcast, _, _, %Summary{state: :online}}}
|
|
|
|
assert_receive {:start_charging_process, ^car, %{latitude: 0.0, longitude: 0.0},
|
|
[lookup_address: true]}
|
|
|
|
assert_receive {:"$websockex_cast", :disconnect}
|
|
|
|
assert_receive {:insert_charge, %ChargingProcess{id: _cproc_id} = cproc,
|
|
%{date: _, charge_energy_added: 0.1}}
|
|
|
|
assert_receive {:pubsub, {:broadcast, _, _, %Summary{state: :charging}}}
|
|
|
|
assert_receive {:insert_charge, ^cproc, %{date: _, charge_energy_added: 0.2}}
|
|
assert_receive {:pubsub, {:broadcast, _, _, %Summary{state: :charging}}}
|
|
|
|
assert_receive {:insert_charge, ^cproc, %{date: _, charge_energy_added: 0.3}}
|
|
assert_receive {:pubsub, {:broadcast, _, _, %Summary{state: :charging}}}
|
|
|
|
assert_receive {:insert_position, ^car, %{}}
|
|
assert_receive {:insert_charge, ^cproc, %{date: _, charge_energy_added: 0.3}}
|
|
assert_receive {:complete_charging_process, ^cproc}
|
|
|
|
start_date = DateTime.from_unix!(now_ts + 4, :millisecond)
|
|
assert_receive {:start_state, ^car, :online, date: ^start_date}
|
|
assert_receive {ApiMock, {:stream, 1000, _}}
|
|
assert_receive {:insert_position, ^car, %{}}
|
|
assert_receive {:pubsub, {:broadcast, _, _, %Summary{state: :online}}}
|
|
|
|
assert_receive {:pubsub, {:broadcast, _, _, %Summary{state: :online}}}
|
|
|
|
refute_receive _
|
|
end
|
|
|
|
test "handles a invalid charge data", %{test: name} do
|
|
now_ts = DateTime.utc_now() |> DateTime.to_unix(:millisecond)
|
|
|
|
events = [
|
|
{:ok, online_event()},
|
|
{:ok, online_event(drive_state: %{timestamp: now_ts, latitude: 0.0, longitude: 0.0})},
|
|
{:ok, charging_event(now_ts + 1, "Charging", 0.1)},
|
|
{:ok, %TeslaApi.Vehicle{state: "online", charge_state: nil}},
|
|
{:ok, %TeslaApi.Vehicle{state: "online", charge_state: nil}},
|
|
{:ok, %TeslaApi.Vehicle{state: "online", charge_state: nil}},
|
|
{:ok, charging_event(now_ts + 3, "Charging", 0.3)},
|
|
{:ok, charging_event(now_ts + 5, "Complete", 0.3)},
|
|
{:ok, online_event(drive_state: %{timestamp: now_ts + 6, latitude: 0.2, longitude: 0.2})},
|
|
fn -> Process.sleep(10_000) end
|
|
]
|
|
|
|
:ok = start_vehicle(name, events)
|
|
|
|
start_date = DateTime.from_unix!(now_ts, :millisecond)
|
|
assert_receive {:start_state, car, :online, date: ^start_date}
|
|
assert_receive {ApiMock, {:stream, 1000, _}}
|
|
assert_receive {:insert_position, ^car, %{}}
|
|
assert_receive {:pubsub, {:broadcast, _, _, %Summary{state: :online}}}
|
|
|
|
assert_receive {:start_charging_process, ^car, %{latitude: 0.0, longitude: 0.0},
|
|
[lookup_address: true]}
|
|
|
|
assert_receive {:"$websockex_cast", :disconnect}
|
|
|
|
assert_receive {:insert_charge, cproc, %{date: _, charge_energy_added: 0.1}}
|
|
assert_receive {:pubsub, {:broadcast, _, _, %Summary{state: :charging}}}
|
|
|
|
assert capture_log(@log_opts, fn ->
|
|
assert_receive {:insert_charge, ^cproc, %{date: _, charge_energy_added: 0.3}}
|
|
assert_receive {:pubsub, {:broadcast, _, _, %Summary{state: :charging}}}
|
|
end) =~ "Discarded incomplete fetch result"
|
|
|
|
assert_receive {:insert_position, ^car, %{}}
|
|
assert_receive {:insert_charge, ^cproc, %{date: _, charge_energy_added: 0.3}}
|
|
assert_receive {:complete_charging_process, ^cproc}
|
|
|
|
start_date = DateTime.from_unix!(now_ts + 5, :millisecond)
|
|
assert_receive {:start_state, ^car, :online, date: ^start_date}
|
|
assert_receive {ApiMock, {:stream, 1000, _}}
|
|
assert_receive {:insert_position, ^car, %{}}
|
|
assert_receive {:pubsub, {:broadcast, _, _, %Summary{state: :online}}}
|
|
|
|
assert_receive {:pubsub, {:broadcast, _, _, %Summary{state: :online}}}
|
|
|
|
refute_receive _
|
|
end
|
|
|
|
test "Transitions directly into charging state", %{test: name} do
|
|
now_ts = DateTime.utc_now() |> DateTime.to_unix(:millisecond)
|
|
|
|
events = [
|
|
{:ok, online_event()},
|
|
{:ok, charging_event(now_ts, "Charging", 22)},
|
|
fn -> Process.sleep(10_000) end
|
|
]
|
|
|
|
:ok = start_vehicle(name, events)
|
|
|
|
start_date = DateTime.from_unix!(now_ts, :millisecond)
|
|
assert_receive {:start_state, car, :online, date: ^start_date}
|
|
assert_receive {ApiMock, {:stream, 1000, _}}
|
|
assert_receive {:insert_position, ^car, %{}}
|
|
assert_receive {:pubsub, {:broadcast, _, _, %Summary{state: :online}}}
|
|
|
|
assert_receive {:start_charging_process, ^car, %{latitude: 0.0, longitude: 0.0},
|
|
[lookup_address: true]}
|
|
|
|
assert_receive {:"$websockex_cast", :disconnect}
|
|
assert_receive {:pubsub, {:broadcast, _, _, %Summary{state: :charging}}}
|
|
assert_receive {:insert_charge, _charging_event, %{date: _, charge_energy_added: 22}}
|
|
|
|
refute_received _
|
|
end
|
|
|
|
@tag :capture_log
|
|
test "transitions into asleep state", %{test: name} do
|
|
now_ts = DateTime.utc_now() |> DateTime.to_unix(:millisecond)
|
|
|
|
events = [
|
|
{:ok, online_event()},
|
|
{:ok, online_event(drive_state: %{timestamp: now_ts, latitude: 0.0, longitude: 0.0})},
|
|
{:ok, charging_event(now_ts + 1, "Charging", 0.1)},
|
|
{:ok, charging_event(now_ts + 2, "Charging", 0.2)},
|
|
{:error, :vehicle_unavailable},
|
|
{:ok, %TeslaApi.Vehicle{state: "asleep"}},
|
|
fn -> Process.sleep(10_000) end
|
|
]
|
|
|
|
:ok = start_vehicle(name, events)
|
|
|
|
start_date = DateTime.from_unix!(now_ts, :millisecond)
|
|
assert_receive {:start_state, car, :online, date: ^start_date}
|
|
assert_receive {ApiMock, {:stream, 1000, _}}
|
|
assert_receive {:insert_position, ^car, %{}}
|
|
assert_receive {:pubsub, {:broadcast, _, _, %Summary{state: :online}}}
|
|
|
|
assert_receive {:start_charging_process, ^car, %{latitude: 0.0, longitude: 0.0},
|
|
[lookup_address: true]}
|
|
|
|
assert_receive {:"$websockex_cast", :disconnect}
|
|
|
|
assert_receive {:insert_charge, %ChargingProcess{id: _cproc_id} = cproc,
|
|
%{date: _, charge_energy_added: 0.1}}
|
|
|
|
assert_receive {:pubsub, {:broadcast, _, _, %Summary{state: :charging}}}
|
|
assert_receive {:insert_charge, ^cproc, %{date: _, charge_energy_added: 0.2}}
|
|
assert_receive {:pubsub, {:broadcast, _, _, %Summary{state: :charging}}}
|
|
assert_receive {:complete_charging_process, ^cproc}
|
|
assert_receive {:start_state, ^car, :asleep, []}
|
|
assert_receive {:pubsub, {:broadcast, _, _, %Summary{state: :asleep}}}
|
|
|
|
refute_receive _
|
|
end
|
|
end
|