Skip to content

Commit ba33348

Browse files
authored
refactor: replace fake_online_state integer with typed mcu2_online_ch… (#5245)
* refactor: replace fake_online_state integer with typed mcu2_online_check atom The integer values 0/1/2/3 were undocumented magic numbers that required reading multiple comments to understand. Replace with a self-documenting atom enum: :idle – no MCU2 check in progress (was: 0) :probing – stream connected, awaiting first power reading (was: 1) :confirmed_fake – stream reported power=nil, subsystem wakeup (was: 2) :confirmed_real – stream reported numeric power, genuine wakeup (was: 3) No behaviour changes.
1 parent 0c141df commit ba33348

1 file changed

Lines changed: 49 additions & 36 deletions

File tree

lib/teslamate/vehicles/vehicle.ex

Lines changed: 49 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,18 @@ defmodule TeslaMate.Vehicles.Vehicle do
2525
task: nil,
2626
import?: false,
2727
stream_pid: nil,
28-
# fake_online_state is introduced because older cars upgraded to MCU2 have a little wakeup every hour to check subsystems.
29-
# They report online but if vehicle_data is requested they wake up completely (cars clicks) and is awake for
30-
# 15 minutes instead of a 2-3 minutes. The only difference (known at this moment) is that stream reports power=nil
31-
# in subsystem online and reports power as a number when it is a real online.
32-
fake_online_state: 0
28+
# pre_online_check tracks whether an apparent online event is a real wakeup or a brief
29+
# subsystem check. Some vehicles (especially MCU2-upgraded cars) wake briefly (~2-3 min)
30+
# each hour for subsystem checks and report online, but requesting vehicle_data causes a
31+
# full wakeup (~15 min). The distinguishing signal is the streaming API: power=nil means
32+
# a subsystem check (fake online), a numeric power value means a genuine wakeup (real online).
33+
#
34+
# Values:
35+
# :idle – no pre-online check in progress (default)
36+
# :probing – stream connected, waiting for first power reading
37+
# :confirmed_fake – stream reported power=nil, treating as fake online
38+
# :confirmed_real – stream reported numeric power, treating as real online
39+
pre_online_check: :idle
3340
end
3441

3542
@asleep_interval 30
@@ -355,30 +362,29 @@ defmodule TeslaMate.Vehicles.Vehicle do
355362

356363
{:ok, pid} = connect_stream(data)
357364

358-
{:keep_state, %Data{data | stream_pid: pid, fake_online_state: 1},
365+
{:keep_state, %Data{data | stream_pid: pid, pre_online_check: :probing},
359366
[broadcast_fetch(false), schedule_fetch(@asleep_interval, data)]}
360367

361368
{%CarSettings{use_streaming_api: true}, state, %Data{stream_pid: pid}}
362369
when state in [:asleep, :offline] and is_pid(pid) ->
363370
case data do
364-
%Data{fake_online_state: 1} ->
371+
%Data{pre_online_check: :probing} ->
365372
# Under normal circumstances stream always give data within @asleep_interval (30s)
366373
# otherwise detect it here and allow vehicle_data in next fetch
367374
Logger.info("Stream connected, but nothing received, allow real online",
368375
car_id: data.car.id
369376
)
370377

371-
# fetch now and go through regular :start -> :online by setting fake_online_state=3
372-
{:keep_state, %Data{data | fake_online_state: 3},
378+
{:keep_state, %Data{data | pre_online_check: :confirmed_real},
373379
[broadcast_fetch(false), schedule_fetch(0, data)]}
374380

375-
%Data{fake_online_state: 0} ->
381+
%Data{pre_online_check: :idle} ->
376382
Logger.warning(
377-
"Stream connected, but fake_online_state is 0, shouldnt be possible, allow real online",
383+
"Stream connected, but pre_online_check is :idle, shouldn't be possible, allow real online",
378384
car_id: data.car.id
379385
)
380386

381-
{:keep_state, %Data{data | fake_online_state: 3},
387+
{:keep_state, %Data{data | pre_online_check: :confirmed_real},
382388
[broadcast_fetch(false), schedule_fetch(0, data)]}
383389

384390
%Data{} ->
@@ -393,7 +399,8 @@ defmodule TeslaMate.Vehicles.Vehicle do
393399
car_id: data.car.id
394400
)
395401

396-
data =
402+
%Data{} =
403+
data =
397404
with %Data{last_response: nil} <- data do
398405
{last_response, geofence} = restore_last_known_values(vehicle, data)
399406
%Data{data | last_response: last_response, geofence: geofence}
@@ -402,7 +409,7 @@ defmodule TeslaMate.Vehicles.Vehicle do
402409
{:ok, pid} = connect_stream(data)
403410

404411
{:next_state, {:offline, @asleep_interval},
405-
%Data{data | stream_pid: pid, fake_online_state: 1},
412+
%Data{data | stream_pid: pid, pre_online_check: :probing},
406413
[broadcast_fetch(false), schedule_fetch(@asleep_interval, data)]}
407414

408415
{%CarSettings{use_streaming_api: true}, _state, %Data{}} ->
@@ -422,13 +429,14 @@ defmodule TeslaMate.Vehicles.Vehicle do
422429
# (in that case we won't go through Start / :offline or Start / :asleep)
423430
:ok = disconnect_stream(data)
424431

425-
data =
432+
%Data{} =
433+
data =
426434
with %Data{last_response: nil} <- data do
427435
{last_response, geofence} = restore_last_known_values(vehicle, data)
428436
%Data{data | last_response: last_response, geofence: geofence}
429437
end
430438

431-
{:keep_state, %Data{data | fake_online_state: 0, stream_pid: nil},
439+
{:keep_state, %Data{data | pre_online_check: :idle, stream_pid: nil},
432440
[
433441
broadcast_fetch(false),
434442
{:next_event, :internal, {:update, {String.to_existing_atom(state), vehicle}}}
@@ -524,26 +532,30 @@ defmodule TeslaMate.Vehicles.Vehicle do
524532
#### sleep or offline
525533
# stream is started in def handle_event(:info, {ref, fetch_result}, state, %Data{task: %Task{ref: ref}} = data)
526534

527-
def handle_event(:info, {:stream, %Stream.Data{} = stream_data}, {state, _}, data)
535+
def handle_event(:info, {:stream, %Stream.Data{} = stream_data}, {state, _}, %Data{} = data)
528536
when state in [:asleep, :offline] do
529537
case stream_data do
530538
%Stream.Data{power: nil} ->
531539
Logger.debug(inspect(stream_data), car_id: data.car.id)
532540

533-
# stay on stream, keep asking if online and see if a real one appears
534-
# set to 2 to avoid triggering real online in fetch_result (fallback if stream doesn't work)
541+
# Stay on stream and keep waiting to see if a real online appears.
542+
# Transition to :confirmed_fake so the fetch fallback (if stream stalls) won't
543+
# re-trigger a confirmed_real promotion.
535544
case data do
536-
%Data{fake_online_state: 1} ->
537-
Logger.info("Fake online: power is nil", car_id: data.car.id)
538-
{:keep_state, %Data{data | fake_online_state: 2}}
545+
%Data{pre_online_check: :probing} ->
546+
Logger.info("Subsystem check detected: power is nil, treating as fake online",
547+
car_id: data.car.id
548+
)
539549

540-
%Data{fake_online_state: 0} ->
550+
{:keep_state, %Data{data | pre_online_check: :confirmed_fake}}
551+
552+
%Data{pre_online_check: :idle} ->
541553
Logger.warning(
542-
"Fake online: power is nil, but fake_online_state is 0, shouldnt be possible, allow real online",
554+
"Subsystem check detected: power is nil, but pre_online_check is :idle, shouldn't be possible, treating as fake online",
543555
car_id: data.car.id
544556
)
545557

546-
{:keep_state, %Data{data | fake_online_state: 2}}
558+
{:keep_state, %Data{data | pre_online_check: :confirmed_fake}}
547559

548560
%Data{} ->
549561
:keep_state_and_data
@@ -553,22 +565,23 @@ defmodule TeslaMate.Vehicles.Vehicle do
553565
Logger.debug(inspect(stream_data), car_id: data.car.id)
554566

555567
case data do
556-
%Data{fake_online_state: fake_online_state}
557-
when is_number(fake_online_state) and fake_online_state in [1, 2] ->
568+
%Data{pre_online_check: check} when check in [:probing, :confirmed_fake] ->
558569
Logger.info("Real online detected: power is a number", car_id: data.car.id)
559-
# fetch now and go through regular :start -> :online by setting fake_online_state=3
560-
{:keep_state, %Data{data | fake_online_state: 3}, schedule_fetch(0, data)}
561570

562-
%Data{fake_online_state: 0} ->
571+
{:keep_state, %Data{data | pre_online_check: :confirmed_real},
572+
schedule_fetch(0, data)}
573+
574+
%Data{pre_online_check: :idle} ->
563575
Logger.warning(
564-
"Real online detected: power is a number, but fake_online_state is 0, shouldnt be possible, allow real online",
576+
"Real online detected: power is a number, but pre_online_check is :idle, shouldn't be possible, treating as real online",
565577
car_id: data.car.id
566578
)
567579

568-
{:keep_state, %Data{data | fake_online_state: 3}, schedule_fetch(0, data)}
580+
{:keep_state, %Data{data | pre_online_check: :confirmed_real},
581+
schedule_fetch(0, data)}
569582

570583
%Data{} ->
571-
# fake_online_state already set to 3, dont fetch again to avoid 'Fetch already in progress ...'
584+
# pre_online_check already :confirmed_real — don't fetch again to avoid 'Fetch already in progress'
572585
:keep_state_and_data
573586
end
574587

@@ -911,7 +924,7 @@ defmodule TeslaMate.Vehicles.Vehicle do
911924
:ok = disconnect_stream(data)
912925

913926
{:next_state, {:asleep, asleep_interval()},
914-
%{data | last_state_change: last_state_change, stream_pid: nil, fake_online_state: 0},
927+
%{data | last_state_change: last_state_change, stream_pid: nil, pre_online_check: :idle},
915928
[broadcast_summary(), schedule_fetch(data)]}
916929
end
917930

@@ -924,7 +937,7 @@ defmodule TeslaMate.Vehicles.Vehicle do
924937
:ok = disconnect_stream(data)
925938

926939
{:next_state, {:offline, asleep_interval()},
927-
%{data | last_state_change: last_state_change, stream_pid: nil, fake_online_state: 0},
940+
%{data | last_state_change: last_state_change, stream_pid: nil, pre_online_check: :idle},
928941
[broadcast_summary(), schedule_fetch(data)]}
929942
end
930943

@@ -1485,7 +1498,7 @@ defmodule TeslaMate.Vehicles.Vehicle do
14851498

14861499
{state, _} when state in [:asleep, :offline] ->
14871500
case data do
1488-
%Data{fake_online_state: 3} -> true
1501+
%Data{pre_online_check: :confirmed_real} -> true
14891502
%Data{} -> false
14901503
end
14911504

0 commit comments

Comments
 (0)