JLindvig

Virtuel PHEV Tracker

Dec 11th, 2025 (edited)
291
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
YAML 6.20 KB | None | 0 0
  1. alias: Virtuel PHEV Tracker
  2. description: >-
  3.   Kombinerer bilens egen GPS med telefoners GPS (ved kørsel) for at sikre
  4.   hurtigere opdateringer. Bruger Bluetooth/WiFi til at detektere føreren og en
  5.   Bayesian-sensor til at bekræfte 'Hjemme'-status for at undgå GPS-drift.
  6.  
  7. # ------------------------------------------------------------------------------
  8. # VIRTUAL PHEV TRACKER - ADVANCED VERSION
  9. # ------------------------------------------------------------------------------
  10. # This automation creates a virtual device_tracker that intelligently switches
  11. # between multiple GPS sources (Car native GPS vs. Driver phones).
  12. #
  13. # PREREQUISITES:
  14. # 1. A Bayesian binary_sensor (e.g., binary_sensor.yeti_presence) for home detection.
  15. # 2. A native car integration (e.g., device_tracker.yeti_location).
  16. # 3. Bluetooth MAC addresses for the car's dongles/headunit.
  17. # ------------------------------------------------------------------------------
  18.  
  19. triggers:
  20.  # 1. Trigger when "Car is Home" confidence changes (Bayesian)
  21.   - trigger: state
  22.     entity_id: binary_sensor.yeti_presence
  23.     to: null
  24.     id: bayesian
  25.   # 2. Trigger when Primary Driver's phone moves
  26.   - trigger: state
  27.     entity_id: device_tracker.jacob_nothing
  28.     attribute: latitude
  29.     id: jacob
  30.   # 3. Trigger when Native Car GPS updates
  31.   - trigger: state
  32.     entity_id: device_tracker.yeti_location
  33.     attribute: latitude
  34.     id: car
  35.  
  36. conditions: []
  37.  
  38. actions:
  39.   - variables:
  40.      # ========================================================================
  41.       # CONFIGURATION SECTION - EDIT THIS
  42.       # ========================================================================
  43.       name: yeti                                     # The name of this virtual device
  44.       fallback_entity: device_tracker.yeti_location  # The car's native integration
  45.       target_macs:                                  # Bluetooth MACs indicating "In Car"
  46.         - 00:92:A5:5D:E2:E1
  47.         - 68:8F:C9:8B:B0:99
  48.         - 30:95:E3:E9:9C:FF
  49.      
  50.       # ========================================================================
  51.       # LOGIC & CALCULATIONS (DRY)
  52.       # ========================================================================
  53.      
  54.       # --- Dynamic Entity ID ---
  55.       # Constructs 'device_tracker.yeti' automatically from the name variable
  56.       this_entity_id: "{{ 'device_tracker.' ~ name }}"
  57.  
  58.       # --- Home Presence ---
  59.       is_confirmed_home: "{{ is_state('binary_sensor.yeti_presence', 'on') }}"
  60.  
  61.       # --- Driver Detection (Bluetooth) ---
  62.       jacob_bt_devices: >
  63.        {{ state_attr('sensor.jacob_nothing_bluetooth_connection', 'connected_paired_devices') }}
  64.       jacob_driving: >
  65.        {{ jacob_bt_devices | select('search', target_macs | join('|')) | list | length > 0 }}
  66.      
  67.       # --- Driver Detection (WiFi SSID) ---
  68.       rikke_driving: "{{ is_state('sensor.iphone_3_ssid', 'CAR2-ED79') }}"
  69.  
  70.       # --- Timestamps for Comparison ---
  71.       # Uses the dynamic 'this_entity_id' to check self-state
  72.       virtuel_last_updated: |
  73.        {{ as_timestamp(states[this_entity_id].last_updated) | default(0) }}
  74.       car_last_updated: |
  75.        {{ as_timestamp(states[fallback_entity].last_updated) | default(0) }}
  76.  
  77.       # --- Source Selection Strategy ---
  78.       # 1. If driving (phone connected to car) -> Use Phone GPS
  79.       # 2. If parked -> Use Car GPS (fallback_entity) if it has new data
  80.       # 3. Else -> Keep current state (this_entity_id)
  81.       gps_source_entity: |
  82.        {% if jacob_driving %}
  83.           device_tracker.jacob_nothing
  84.         {% elif rikke_driving %}
  85.           device_tracker.iphone_3
  86.         {% else %}
  87.           {{ fallback_entity if car_last_updated > virtuel_last_updated else this_entity_id }}
  88.         {% endif %}
  89.  
  90.       # --- Data Normalization ---
  91.       # Handles differences between iOS 'Location' list and Standard 'latitude' attributes
  92.       latitude: >
  93.        {{ state_attr(gps_source_entity, 'Location')[0] if rikke_driving else state_attr(gps_source_entity, 'latitude') }}
  94.       longitude: >
  95.        {{ state_attr(gps_source_entity, 'Location')[1] if rikke_driving else state_attr(gps_source_entity, 'longitude') }}
  96.      
  97.       # Convert m/s to km/h
  98.       current_speed: "{{ (state_attr(gps_source_entity, 'speed') | float(0) * 3.6) | round(1) }}"
  99.       current_course: "{{ state_attr(gps_source_entity, 'course') | default(0) }}"
  100.       current_altitude: "{{ state_attr(gps_source_entity, 'altitude') | default(0) }}"
  101.      
  102.       # Pass-through sensors
  103.       fuel_level: "{{ states('sensor.yeti_fuel_level') }}"
  104.       ev_battery: "{{ states('sensor.yeti_ev_battery_level') }}"
  105.  
  106.     alias: Definér variabler
  107.  
  108.   # --- OPTIMIZATION FILTER ---
  109.   # Only continue if the trigger matches the currently selected source
  110.   # or if the bayesian sensor (Home Logic) triggered the update.
  111.   - condition: template
  112.     value_template: |
  113.      {{ trigger.id == 'bayesian' or
  114.          trigger.entity_id == gps_source_entity or
  115.          gps_source_entity == fallback_entity }}
  116.     enabled: true
  117.  
  118.   # --- UPDATE VIRTUAL TRACKER ---
  119.   - action: device_tracker.see
  120.     data:
  121.       dev_id: "{{ name }}"
  122.       # Force location name "home" if Bayesian sensor confirms it
  123.       location_name: "{{ 'home' if is_confirmed_home else omit }}"
  124.       source_type: gps
  125.       # Force zone.home coordinates if confirmed home (Anti-Drift)
  126.       gps: |
  127.        {% if is_confirmed_home %}
  128.           {{ [state_attr('zone.home', 'latitude'), state_attr('zone.home', 'longitude')] }}
  129.         {% else %}
  130.           {{ [latitude, longitude] }}
  131.         {% endif %}
  132.       gps_accuracy: "{{ 10 if is_confirmed_home else state_attr(gps_source_entity, 'gps_accuracy') | default(50) }}"
  133.       battery: "{{ states('sensor.yeti_car_battery_level') }}"
  134.       attributes:
  135.         speed: "{{ current_speed }}"
  136.         course: "{{ current_course }}"
  137.         altitude: "{{ current_altitude }}"
  138.         fuel_level: "{{ fuel_level }}"
  139.         ev_battery: "{{ ev_battery }}"
  140.         last_source: "{{ gps_source_entity }}"
  141.         # Status logic: If source is 'self', we are waiting for external data
  142.         status: "{{ 'Parkeret (Venter på bil-data)' if gps_source_entity == this_entity_id else 'Opdateret' }}"
  143. mode: restart
Advertisement
Add Comment
Please, Sign In to add comment