@@ -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