mirror of
https://github.com/teslamate-org/teslamate.git
synced 2026-01-24 21:06:08 +08:00
Display more icons in the UI
This commit is contained in:
@@ -26,6 +26,8 @@ If you have feedback or can even verify/compare the calculated value with a real
|
||||
|
||||
- `teslamate/cars/$car_id/update_available`: Indicates if a car software update is available
|
||||
- `teslamate/cars/$car_id/is_climate_on`: Indicates if the climate control is on
|
||||
- `teslamate/cars/$car_id/is_preconditioning`: Indicates if the vehicle is being preconditioned
|
||||
- `teslamate/cars/$car_id/is_user_present`: Indicates if a user is present in the vehicle
|
||||
|
||||
### Enhancements
|
||||
|
||||
|
||||
@@ -12,28 +12,31 @@ Vehicle data will be published to the following topics (`$car_id` usually starts
|
||||
| ------------------------------------------------------ | -------------------- | ------------------------------------------------------------ |
|
||||
| `teslamate/cars/$car_id/display_name` | Blue Thunder | Vehicle Name |
|
||||
| `teslamate/cars/$car_id/state` | asleep | Status of the vehicle (e.g. `onlilne`, `asleep`, `charging`) |
|
||||
| `teslamate/cars/$car_id/since` | 2019-02-29T23:00:07Z | Date of the last status change |
|
||||
| `teslamate/cars/$car_id/healthy` | true | Health status of the logger for that vehicle |
|
||||
| `teslamate/cars/$car_id/version` | 2019.32.12.2 58f3b76 | Software Version |
|
||||
| `teslamate/cars/$car_id/update_available` | false | Indicates if a software update is available |
|
||||
| | | |
|
||||
| ------------------------------------------------------ | -------------------- | ------------------------------------------------------------ |
|
||||
| `teslamate/cars/$car_id/latitude` | 35.278131 | Last reported car latitude |
|
||||
| `teslamate/cars/$car_id/longitude` | 29.744801 | Last reported car longitude |
|
||||
| `teslamate/cars/$car_id/shift_state` | D | Current/Last Shift State (D/N/R/P) |
|
||||
| `teslamate/cars/$car_id/speed` | 12 | Current Speed in km/h |
|
||||
| | | |
|
||||
| ------------------------------------------------------ | -------------------- | ------------------------------------------------------------ |
|
||||
| `teslamate/cars/$car_id/locked` | true | Indicates if the car is locked |
|
||||
| `teslamate/cars/$car_id/sentry_mode` | false | Indicates if Sentry Mode is active |
|
||||
| `teslamate/cars/$car_id/windows_open` | false | Indicates if any of the windows are open |
|
||||
| | | |
|
||||
| `teslamate/cars/$car_id/is_user_present` | false | Indicates if a user is present in the vehicle |
|
||||
| ------------------------------------------------------ | -------------------- | ------------------------------------------------------------ |
|
||||
| `teslamate/cars/$car_id/is_climate_on` | true | Indicates if the climate control is on |
|
||||
| `teslamate/cars/$car_id/inside_temp` | 20.8 | Inside Temperature in °C |
|
||||
| `teslamate/cars/$car_id/outside_temp` | 18.4 | Temperature in °C |
|
||||
| | | |
|
||||
| `teslamate/cars/$car_id/is_preconditioning` | false | Indicates if the vehicle is being preconditioned |
|
||||
| ------------------------------------------------------ | -------------------- | ------------------------------------------------------------ |
|
||||
| `teslamate/cars/$car_id/odometer` | 1653 | Car odometer in km |
|
||||
| `teslamate/cars/$car_id/est_battery_range_km` | 372.5 | Estimated Range in km |
|
||||
| `teslamate/cars/$car_id/rated_battery_range_km` | 401.63 | Rated Range in km |
|
||||
| `teslamate/cars/$car_id/ideal_battery_range_km` | 335.79 | Ideal Range in km |
|
||||
| | | |
|
||||
| ------------------------------------------------------ | -------------------- | ------------------------------------------------------------ |
|
||||
| `teslamate/cars/$car_id/battery_level` | 88 | Battery Level Percentage |
|
||||
| `teslamate/cars/$car_id/plugged_in` | true | If car is currently plugged into a charger |
|
||||
| `teslamate/cars/$car_id/charge_energy_added` | 5.06 | Last added energy in kW |
|
||||
|
||||
@@ -40,20 +40,16 @@ defmodule TeslaMate.Mqtt.PubSub.VehicleSubscriber do
|
||||
{:noreply, state}
|
||||
end
|
||||
|
||||
@blacklist [:car]
|
||||
@always_published ~w(charge_energy_added charger_actual_current charger_phases
|
||||
charger_power charger_voltage scheduled_charging_start_time
|
||||
time_to_full_charge)a
|
||||
|
||||
def handle_info(summary, state) do
|
||||
summary
|
||||
|> Map.from_struct()
|
||||
|> Stream.filter(fn {key, value} ->
|
||||
not is_nil(value) or
|
||||
key in [
|
||||
:charge_energy_added,
|
||||
:charger_actual_current,
|
||||
:charger_phases,
|
||||
:charger_power,
|
||||
:charger_voltage,
|
||||
:scheduled_charging_start_time,
|
||||
:time_to_full_charge
|
||||
]
|
||||
not (key in @blacklist) and (not is_nil(value) or key in @always_published)
|
||||
end)
|
||||
|> Task.async_stream(&publish(&1, state),
|
||||
max_concurrency: 10,
|
||||
|
||||
@@ -4,40 +4,14 @@ defmodule TeslaMate.Vehicles.Vehicle.Summary do
|
||||
alias TeslaApi.Vehicle.State.{Drive, Charge, VehicleState}
|
||||
alias TeslaApi.Vehicle
|
||||
|
||||
defstruct [
|
||||
:car,
|
||||
:display_name,
|
||||
:state,
|
||||
:since,
|
||||
:healthy,
|
||||
:latitude,
|
||||
:longitude,
|
||||
:battery_level,
|
||||
:ideal_battery_range_km,
|
||||
:est_battery_range_km,
|
||||
:rated_battery_range_km,
|
||||
:charge_energy_added,
|
||||
:speed,
|
||||
:outside_temp,
|
||||
:inside_temp,
|
||||
:is_climate_on,
|
||||
:locked,
|
||||
:sentry_mode,
|
||||
:plugged_in,
|
||||
:scheduled_charging_start_time,
|
||||
:charge_limit_soc,
|
||||
:charger_power,
|
||||
:windows_open,
|
||||
:odometer,
|
||||
:shift_state,
|
||||
:charge_port_door_open,
|
||||
:time_to_full_charge,
|
||||
:charger_phases,
|
||||
:charger_actual_current,
|
||||
:charger_voltage,
|
||||
:version,
|
||||
:update_available
|
||||
]
|
||||
defstruct ~w(
|
||||
car display_name state since healthy latitude longitude battery_level
|
||||
ideal_battery_range_km est_battery_range_km rated_battery_range_km charge_energy_added
|
||||
speed outside_temp inside_temp is_climate_on is_preconditioning locked sentry_mode
|
||||
plugged_in scheduled_charging_start_time charge_limit_soc charger_power windows_open
|
||||
odometer shift_state charge_port_door_open time_to_full_charge charger_phases
|
||||
charger_actual_current charger_voltage version update_available is_user_present
|
||||
)a
|
||||
|
||||
def into(nil, %{state: :start, healthy?: healthy?, car: car}) do
|
||||
%__MODULE__{state: :unavailable, healthy: healthy?, car: car}
|
||||
@@ -90,6 +64,7 @@ defmodule TeslaMate.Vehicles.Vehicle.Summary do
|
||||
|
||||
# Climate State
|
||||
is_climate_on: get_in_struct(vehicle, [:climate_state, :is_climate_on]),
|
||||
is_preconditioning: get_in_struct(vehicle, [:climate_state, :is_preconditioning]),
|
||||
outside_temp: get_in_struct(vehicle, [:climate_state, :outside_temp]),
|
||||
inside_temp: get_in_struct(vehicle, [:climate_state, :inside_temp]),
|
||||
|
||||
@@ -98,6 +73,7 @@ defmodule TeslaMate.Vehicles.Vehicle.Summary do
|
||||
locked: get_in_struct(vehicle, [:vehicle_state, :locked]),
|
||||
sentry_mode: get_in_struct(vehicle, [:vehicle_state, :sentry_mode]),
|
||||
windows_open: window_open(vehicle),
|
||||
is_user_present: get_in_struct(vehicle, [:vehicle_state, :is_user_present]),
|
||||
version: get_in_struct(vehicle, [:vehicle_state, :car_version]),
|
||||
update_available: update_available(vehicle)
|
||||
}
|
||||
|
||||
@@ -25,6 +25,16 @@
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="icons ml-5">
|
||||
<%= if @summary.is_preconditioning do %>
|
||||
<span class="health icon has-text-grey-dark tooltip is-tooltip-top is-tooltip-left-mobile" data-tooltip='<%= gettext "Preconditioning" %>'>
|
||||
<span class="mdi mdi-air-conditioner"></span>
|
||||
</span>
|
||||
<% end %>
|
||||
<%= if @summary.state != :driving and @summary.is_user_present do %>
|
||||
<span class="health icon has-text-grey-dark tooltip is-tooltip-top is-tooltip-left-mobile" data-tooltip='<%= gettext "User present" %>'>
|
||||
<span class="mdi mdi-account"></span>
|
||||
</span>
|
||||
<% end %>
|
||||
<%= if @summary.plugged_in do %>
|
||||
<span class="health icon has-text-grey-dark tooltip is-tooltip-top is-tooltip-left-mobile" data-tooltip='<%= gettext "Plugged in" %>'>
|
||||
<span class="mdi mdi-power-plug"></span>
|
||||
@@ -203,7 +213,7 @@
|
||||
not is_nil(@error) ->
|
||||
link @error, to: "#", class: "button is-danger is-small is-outlined is-fullwidth", disabled: true
|
||||
|
||||
@summary.state == :online and !@summary.sentry_mode and @summary.locked->
|
||||
@summary.state == :online and !@summary.sentry_mode and !@summary.is_user_present and !@summary.is_preconditioning and @summary.locked->
|
||||
link gettext("try to sleep"), to: "#", phx_click: "suspend_logging",
|
||||
class: "button is-info is-small is-outlined is-fullwidth" <> (if @loading, do: " is-loading", else: "")
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ defmodule TeslaMate.Mqtt.PubSub.VehicleSubscriberTest do
|
||||
assert_receive {VehiclesMock, {:subscribe, 0}}
|
||||
|
||||
summary = %Summary{
|
||||
healthy: true,
|
||||
display_name: "Foo",
|
||||
odometer: 42_000,
|
||||
windows_open: true,
|
||||
@@ -43,7 +44,10 @@ defmodule TeslaMate.Mqtt.PubSub.VehicleSubscriberTest do
|
||||
sentry_mode: false,
|
||||
plugged_in: false,
|
||||
version: "2019.42",
|
||||
update_available: false
|
||||
update_available: false,
|
||||
is_preconditioning: true,
|
||||
is_user_present: false,
|
||||
is_climate_on: true
|
||||
}
|
||||
|
||||
send(pid, summary)
|
||||
|
||||
@@ -27,9 +27,31 @@ defmodule TeslaMateWeb.CarControllerTest do
|
||||
assert redirected_to(conn, 302) == Routes.live_path(conn, TeslaMateWeb.SignInLive.Index)
|
||||
end
|
||||
|
||||
# @tag :signed_in
|
||||
# test "lists all cares", %{conn: conn} do
|
||||
# end
|
||||
@tag :signed_in
|
||||
test "lists all active vehicles", %{conn: conn} do
|
||||
{:ok, _pid} =
|
||||
start_supervised(
|
||||
{ApiMock, name: :api_vehicle, events: [{:ok, online_event()}], pid: self()}
|
||||
)
|
||||
|
||||
{:ok, _pid} =
|
||||
start_supervised(
|
||||
{TeslaMate.Vehicles,
|
||||
vehicle: VehicleMock,
|
||||
vehicles: [
|
||||
%TeslaApi.Vehicle{display_name: "f0o", id: 4241, vehicle_id: 11111, vin: "1221"},
|
||||
%TeslaApi.Vehicle{display_name: "fo0", id: 1242, vehicle_id: 22222, vin: "2112"}
|
||||
]}
|
||||
)
|
||||
|
||||
conn = get(conn, Routes.car_path(conn, :index))
|
||||
html = response(conn, 200)
|
||||
|
||||
assert [
|
||||
{"div", [{"class", "car card"}], _},
|
||||
{"div", [{"class", "car card"}], _}
|
||||
] = Floki.find(html, ".car")
|
||||
end
|
||||
|
||||
@tag :signed_in
|
||||
test "renders last knwon vehicle stats", %{conn: conn} do
|
||||
@@ -82,7 +104,7 @@ defmodule TeslaMateWeb.CarControllerTest do
|
||||
battery_range: 175,
|
||||
battery_level: 69
|
||||
},
|
||||
climate_state: %{is_preconditioning: false, outside_temp: 24, inside_temp: 23.2},
|
||||
climate_state: %{is_preconditioning: true, outside_temp: 24, inside_temp: 23.2},
|
||||
vehicle_state: %{
|
||||
software_update: %{status: "available"},
|
||||
locked: true,
|
||||
@@ -90,7 +112,8 @@ defmodule TeslaMateWeb.CarControllerTest do
|
||||
fd_window: 1,
|
||||
fp_window: 0,
|
||||
rd_window: 0,
|
||||
rp_window: 0
|
||||
rp_window: 0,
|
||||
is_user_present: true
|
||||
},
|
||||
vehicle_config: %{car_type: "models2", trim_badging: "p90d"}
|
||||
)}
|
||||
@@ -110,6 +133,8 @@ defmodule TeslaMateWeb.CarControllerTest do
|
||||
assert table_row(html, "Range (est.)", "289.68 km")
|
||||
assert table_row(html, "State of Charge", "69%")
|
||||
assert icon(html, "Locked", "lock")
|
||||
assert icon(html, "User present", "account")
|
||||
assert icon(html, "Preconditioning", "air-conditioner")
|
||||
assert icon(html, "Sentry Mode", "shield-check")
|
||||
assert icon(html, "Windows open", "window-open")
|
||||
assert icon(html, "Software Update available", "gift-outline")
|
||||
|
||||
Reference in New Issue
Block a user