mirror of
https://github.com/teslamate-org/teslamate.git
synced 2026-01-24 21:06:08 +08:00
Restart Vehicles supervisor after potential eid change
This commit is contained in:
@@ -32,6 +32,11 @@ defmodule TeslaMate.Vehicles do
|
||||
)
|
||||
end
|
||||
|
||||
def kill do
|
||||
Logger.warn("Restarting #{__MODULE__} supervisor")
|
||||
__MODULE__ |> Process.whereis() |> Process.exit(:kill)
|
||||
end
|
||||
|
||||
def restart do
|
||||
with :ok <- Supervisor.stop(@name, :normal),
|
||||
:ok <- block_until_started(250) do
|
||||
@@ -61,8 +66,13 @@ defmodule TeslaMate.Vehicles do
|
||||
end
|
||||
|
||||
defp fallback_vehicles do
|
||||
Log.list_cars()
|
||||
|> Enum.map(&%TeslaApi.Vehicle{id: &1.eid, vin: &1.vin, vehicle_id: &1.vid})
|
||||
vehicles =
|
||||
Log.list_cars()
|
||||
|> Enum.map(&%TeslaApi.Vehicle{id: &1.eid, vin: &1.vin, vehicle_id: &1.vid})
|
||||
|
||||
Logger.warn("Using fallback vehicles:\n\n#{inspect(vehicles, pretty: true)}")
|
||||
|
||||
vehicles
|
||||
end
|
||||
|
||||
defp create_or_update!(%TeslaApi.Vehicle{} = vehicle) do
|
||||
|
||||
@@ -4,7 +4,7 @@ defmodule TeslaMate.Vehicles.Vehicle do
|
||||
require Logger
|
||||
|
||||
alias __MODULE__.Summary
|
||||
alias TeslaMate.{Api, Log, Settings, Convert}
|
||||
alias TeslaMate.{Vehicles, Api, Log, Settings, Convert}
|
||||
alias TeslaMate.Vehicles.Identification
|
||||
|
||||
alias TeslaApi.Vehicle.State.{Climate, VehicleState, Drive, Charge}
|
||||
@@ -61,6 +61,7 @@ defmodule TeslaMate.Vehicles.Vehicle do
|
||||
log: Keyword.get(opts, :deps_log, Log),
|
||||
api: Keyword.get(opts, :deps_api, Api),
|
||||
settings: Keyword.get(opts, :deps_settings, Settings),
|
||||
vehicles: Keyword.get(opts, :deps_vehicles, Vehicles),
|
||||
pubsub: Keyword.get(opts, :deps_pubsub, Phoenix.PubSub)
|
||||
}
|
||||
|
||||
@@ -81,6 +82,14 @@ defmodule TeslaMate.Vehicles.Vehicle do
|
||||
|
||||
:ok = call(deps.settings, :subscribe_to_changes)
|
||||
|
||||
fuse_name = fuse_name(:vehicle_not_found, data)
|
||||
fuse_opts = {{:standard, 8, :timer.minutes(10)}, {:reset, :timer.minutes(5)}}
|
||||
|
||||
case :fuse.install(fuse_name, fuse_opts) do
|
||||
:reset -> Logger.info("Reset fuse: #{inspect(fuse_name)}")
|
||||
:ok -> :ok
|
||||
end
|
||||
|
||||
{:ok, :start, data, {:next_event, :internal, :fetch}}
|
||||
end
|
||||
|
||||
@@ -227,7 +236,15 @@ defmodule TeslaMate.Vehicles.Vehicle do
|
||||
|
||||
{:error, :vehicle_not_found} ->
|
||||
Logger.error("Error / :vehicle_not_found", car_id: data.car.id)
|
||||
{:keep_state_and_data, schedule_fetch(60)}
|
||||
|
||||
fuse_name = fuse_name(:vehicle_not_found, data)
|
||||
|
||||
case :fuse.ask(fuse_name, :sync) do
|
||||
:blown -> true = call(data.deps.vehicles, :kill)
|
||||
:ok -> :ok = :fuse.melt(fuse_name)
|
||||
end
|
||||
|
||||
{:keep_state_and_data, schedule_fetch(30)}
|
||||
|
||||
{:error, reason} ->
|
||||
Logger.warn("Error / #{inspect(reason)}", car_id: data.car.id)
|
||||
@@ -801,6 +818,10 @@ defmodule TeslaMate.Vehicles.Vehicle do
|
||||
defp determince_interval(n) when not is_nil(n) and n > 0, do: round(725 / n) |> min(30)
|
||||
defp determince_interval(_), do: 15
|
||||
|
||||
defp fuse_name(:vehicle_not_found, %Data{car: car}) do
|
||||
:"#{__MODULE__}_#{car.id}_not_found"
|
||||
end
|
||||
|
||||
defp notify_subscribers do
|
||||
{:next_event, :internal, :notify_subscribers}
|
||||
end
|
||||
|
||||
@@ -10,6 +10,7 @@ defmodule VehiclesMock do
|
||||
GenServer.start_link(__MODULE__, opts, name: Keyword.fetch!(opts, :name))
|
||||
end
|
||||
|
||||
def kill(name), do: GenServer.call(name, :kill)
|
||||
def restart(name), do: GenServer.call(name, :restart)
|
||||
|
||||
def subscribe(name, car_id), do: GenServer.call(name, {:subscribe, car_id})
|
||||
@@ -27,6 +28,11 @@ defmodule VehiclesMock do
|
||||
{:reply, :ok, state}
|
||||
end
|
||||
|
||||
def handle_call(:kill, _from, %State{pid: pid} = state) do
|
||||
send(pid, {VehiclesMock, :kill})
|
||||
{:reply, true, state}
|
||||
end
|
||||
|
||||
def handle_call(:restart, _from, %State{pid: pid} = state) do
|
||||
send(pid, {VehiclesMock, :restart})
|
||||
{:reply, :ok, state}
|
||||
|
||||
@@ -17,11 +17,13 @@ defmodule TeslaMate.VehicleCase do
|
||||
log_name = :"log_#{name}"
|
||||
api_name = :"api_#{name}"
|
||||
settings_name = :"settings_#{name}"
|
||||
vehicles_name = :"vehicles_#{name}"
|
||||
pubsub_name = :"pubsub_#{name}"
|
||||
|
||||
{:ok, _pid} = start_supervised({LogMock, name: log_name, pid: self()})
|
||||
{:ok, _pid} = start_supervised({ApiMock, name: api_name, events: events, pid: self()})
|
||||
{:ok, _pid} = start_supervised({SettingsMock, name: settings_name, pid: self()})
|
||||
{:ok, _pid} = start_supervised({VehiclesMock, name: vehicles_name, pid: self()})
|
||||
{:ok, _pid} = start_supervised({PubSubMock, name: pubsub_name, pid: self()})
|
||||
|
||||
opts =
|
||||
@@ -52,6 +54,7 @@ defmodule TeslaMate.VehicleCase do
|
||||
deps_log: {LogMock, log_name},
|
||||
deps_api: {ApiMock, api_name},
|
||||
deps_settings: {SettingsMock, settings_name},
|
||||
deps_vehicles: {VehiclesMock, vehicles_name},
|
||||
deps_pubsub: {PubSubMock, pubsub_name}
|
||||
)}
|
||||
)
|
||||
|
||||
@@ -211,4 +211,17 @@ defmodule TeslaMate.Vehicles.VehicleTest do
|
||||
refute_receive _
|
||||
end
|
||||
end
|
||||
|
||||
describe "error handling" do
|
||||
@tag :capture_log
|
||||
test "restarts if the eid changed", %{test: name} do
|
||||
events = [
|
||||
{:error, :vehicle_not_found}
|
||||
]
|
||||
|
||||
:ok = start_vehicle(name, events)
|
||||
|
||||
assert_receive {VehiclesMock, :kill}, 2500
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user