mirror of
https://github.com/netfun2000/hipudding-teslamate.git
synced 2026-02-27 09:44:28 +08:00
135 lines
4.1 KiB
Elixir
135 lines
4.1 KiB
Elixir
defmodule TeslaMate.Import.LineParser do
|
|
use Timex
|
|
|
|
require Logger
|
|
|
|
alias TeslaApi.Vehicle.State.{Charge, Climate, Drive, VehicleConfig, VehicleState}
|
|
alias TeslaApi.Vehicle
|
|
|
|
@default_vehicle %{
|
|
"display_name" => "",
|
|
"charge_state" => %{},
|
|
"climate_state" => %{},
|
|
"drive_state" => %{},
|
|
"vehicle_config" => %{},
|
|
"vehicle_state" => %{}
|
|
}
|
|
|
|
def parse(line, tz) when is_map(line) do
|
|
line
|
|
|> Enum.reduce(@default_vehicle, &into_vehicle(&1, &2, tz))
|
|
|> Vehicle.result()
|
|
end
|
|
|
|
@charge_state %Charge{} |> Map.keys() |> Enum.map(&to_string/1)
|
|
@climate_state %Climate{} |> Map.keys() |> Enum.map(&to_string/1)
|
|
@drive_state %Drive{} |> Map.keys() |> Enum.map(&to_string/1)
|
|
@vehicle %Vehicle{} |> Map.keys() |> Enum.map(&to_string/1)
|
|
@vehicle_config %VehicleConfig{} |> Map.keys() |> Enum.map(&to_string/1)
|
|
@vehicle_state %VehicleState{} |> Map.keys() |> Enum.map(&to_string/1)
|
|
|
|
defp map_value(_, ""), do: nil
|
|
defp map_value(_, "None"), do: nil
|
|
defp map_value(_, "none"), do: nil
|
|
|
|
defp map_value(_, "TRUE"), do: true
|
|
defp map_value(_, "True"), do: true
|
|
defp map_value(_, "true"), do: true
|
|
defp map_value(_, "FALSE"), do: false
|
|
defp map_value(_, "False"), do: false
|
|
defp map_value(_, "false"), do: false
|
|
|
|
defp map_value("display_name", name), do: name
|
|
defp map_value("vehicle_name", name), do: name
|
|
defp map_value("state", "waking"), do: "online"
|
|
defp map_value("state", "shutdown"), do: "online"
|
|
|
|
defp map_value("scheduled_charging_start_time", _val), do: nil
|
|
|
|
@boolean ~w(battery_heater_on is_climate_on is_front_defroster_on is_rear_defroster_on
|
|
fast_charger_present not_enough_power_to_heat)
|
|
|
|
defp map_value(key, val) when key in @boolean do
|
|
with v when v not in [nil, false, true] <- map_value(nil, val) do
|
|
nil
|
|
end
|
|
end
|
|
|
|
defp map_value(_key, val) do
|
|
case Integer.parse(val) do
|
|
{i, ""} -> i
|
|
{_, _} -> to_float(val)
|
|
:error -> val
|
|
end
|
|
end
|
|
|
|
defp to_float(val) do
|
|
case Float.parse(val) do
|
|
{f, ""} -> f
|
|
{_, _} -> val
|
|
:error -> val
|
|
end
|
|
end
|
|
|
|
defp into_vehicle({key, val}, acc, tz) do
|
|
case {key, val} do
|
|
{"id", _val} ->
|
|
Map.put(acc, "id", :rand.uniform(65536))
|
|
|
|
{"vehicle_id", ""} ->
|
|
Map.put(acc, "vehicle_id", System.get_env("TESLAFI_IMPORT_VEHICLE_ID", "1"))
|
|
|
|
{"Date", val} ->
|
|
{:ok, datetime} =
|
|
with {:error, _reason} <- Timex.parse(val, "{YYYY}-{M}-{D} {h24}:{m}:{s}"),
|
|
{:error, _reason} <- Timex.parse(val, "{M}/{D}/{YYYY} {h12}:{m}:{s} {AM}"),
|
|
{:error, _reason} <- Timex.parse(val, "{M}/{D}/{YYYY} {h24}:{m}") do
|
|
{:error, {:invalid_date_format, val}}
|
|
end
|
|
|
|
ts =
|
|
case DateTime.from_naive(datetime, tz) do
|
|
{:ok, datetime} ->
|
|
DateTime.to_unix(datetime, :millisecond)
|
|
|
|
{kind, _first_dt, _second_dt} when kind in [:ambiguous, :gap] ->
|
|
# To keep things simple, return nil to ignore these ambiguous responses
|
|
nil
|
|
|
|
{:error, reason} ->
|
|
Logger.warning("""
|
|
Could not convert date #{inspect(datetime)} w/ time zone #{inspect(tz)}:
|
|
#{inspect(reason)}
|
|
""")
|
|
|
|
nil
|
|
end
|
|
|
|
["vehicle_config", "vehicle_state", "drive_state", "climate_state", "charge_state"]
|
|
|> Enum.reduce(acc, fn key, acc -> put_in(acc, [key, "timestamp"], ts) end)
|
|
|
|
{key, val} when key in @charge_state ->
|
|
put_in(acc, ["charge_state", key], map_value(key, val))
|
|
|
|
{key, val} when key in @climate_state ->
|
|
put_in(acc, ["climate_state", key], map_value(key, val))
|
|
|
|
{key, val} when key in @drive_state ->
|
|
put_in(acc, ["drive_state", key], map_value(key, val))
|
|
|
|
{key, val} when key in @vehicle_config ->
|
|
put_in(acc, ["vehicle_config", key], map_value(key, val))
|
|
|
|
{key, val} when key in @vehicle_state ->
|
|
put_in(acc, ["vehicle_state", key], map_value(key, val))
|
|
|
|
{key, val} when key in @vehicle ->
|
|
Map.put(acc, key, map_value(key, val))
|
|
|
|
{key, val} ->
|
|
Logger.debug("unhandled: #{inspect({key, val})}")
|
|
acc
|
|
end
|
|
end
|
|
end
|