Peugeot Citroen DS cars - Connected Car

Hello. This is mine :


Where :
“e208_clim” can turn on or off if you heat the car with appli.
“Alimentation” icon show if it’s slow or fast, and charge icon show status (play, stop, pause/delay etc)
“Fin de charge estimée” show an ETA of charge (need to try)
“Risque de gel” must be a part of a futur automation to heat the car in case of night frost.
And i try to make a two-way graphical history with autonomy and reality (just finish, so need to try too).

Configuration :


Basic sensor
sensor PSA:
  - platform: rest
    resource_template: http://[IP]:5000/get_vehicleinfo/[VIN]?from_cache=1
    scan_interval: 60
    timeout: 30
    verify_ssl: false
    name: PSA
    device_class: timestamp
    value_template: "{{ value_json.energy[0].updated_at }}"
    json_attributes:
      - energy
      - kinetic
      - timed_odometer
      - last_position
      - preconditionning

Sensor, switch, automation...
template:
  binary_sensor:
    - name: e208 Alimentation
      unique_id: c5f46109-4cda-49b2-8c11-2a6b5d233aae
      state: >-
        {{ state_attr('sensor.psa', 'energy')[0].charging.plugged }}
      device_class: connectivity
      icon: >-
        {% if state_attr('sensor.psa', 'energy')[0].charging.plugged %}
          {% if state_attr('sensor.psa', 'energy')[0].charging.charging_mode == 'Slow' %}
            mdi:ev-plug-type2
          {% elif state_attr('sensor.psa', 'energy')[0].charging.charging_mode == 'Quick' %}
            mdi:ev-plug-ccs2
          {% endif %}
        {% else %}
          mdi:power-plug-off-outline
        {% endif %}
    - name: e208 Déplacement
      unique_id: dc7f3ff8-ad77-42d4-8523-ddec9dc821e0
      state: >-
        {{ state_attr('sensor.psa', 'kinetic').moving }}
      device_class: moving
      attributes:
        latitude: "{{ state_attr('sensor.psa', 'last_position').geometry.coordinates[1] }}"
        longitude: "{{ state_attr('sensor.psa', 'last_position').geometry.coordinates[0] }}"
  sensor:
    - name: e208 Charge
      unique_id: 8fbe0b19-447e-4e0b-b1c9-2d855437e63f
      state: >-
        {% set value = state_attr('sensor.psa', 'energy')[0].charging.status %}
        {% if value == 'Failure' %}
          Defaut
        {% elif value == 'InProgress' %}
          En charge
        {% elif value == 'Stopped' %}
          Pause
        {% elif value == 'Finished' %}
          Terminé
        {% elif value == 'Disconnected' %}
          Déconnecté
        {% else %}
          Inconnu
        {% endif %}
      icon: >-
        {% set value = state_attr('sensor.psa', 'energy')[0].charging.status %}
        {% if value == 'Failure' %}
          mdi:alert
        {% elif value == 'InProgress' %}
          mdi:play
        {% elif value == 'Stopped' %}
          mdi:pause
        {% elif value == 'Finished' %}
          mdi:stop
        {% else %}
          mdi:power-plug-off-outline
        {% endif %}
    - name: e208 Batterie
      unique_id: acf1f4f5-4180-43ba-9d1c-feb978f6b1eb
      state: >-
        {{ state_attr('sensor.psa', 'energy')[0].level }}
      unit_of_measurement: "%"
      device_class: battery
    - name: e208 Kilometrage
      unique_id: 4fe63f50-67f8-45f7-b148-e1f5554a85c9
      state: >-
        {{ state_attr('sensor.psa', 'timed_odometer').mileage }}
      unit_of_measurement: "Km"
      icon: 'mdi:road-variant'
    - name: e208 Autonomie
      unique_id: 0016a6a1-fed5-4a41-abb3-b1d6ca54bbab
      state: >-
        {{ state_attr('sensor.psa', 'energy')[0].autonomy }}
      unit_of_measurement: "Km"
      icon: 'mdi:map-marker-distance'
    - name: e208 Pré-conditionnement Defaut
      unique_id: a78793bf-1c13-4281-bf9f-d4abaed72d2f
      state: >-
        {% set value = state_attr('sensor.psa', 'preconditionning').failure_cause %}
        {% if value == 'Defect' %}
          Defectueux
        {% elif value == 'DoorOpened' %}
          Porte ouverte
        {% elif value == 'LowBattery' %}
          Batterie faible
        {% elif value == 'LowFuelLevel' %}
          Plus d'essence
        {% elif value == 'TooManyUnusedProg' %}
          Erreur de programmation
        {% else %}
          Inconnu
        {% endif %}
      icon: >-
        {% set value = state_attr('sensor.psa', 'preconditionning').failure_cause %}
        {% if value == 'Defect' %}
          mdi:information
        {% elif value == 'DoorOpened' %}
          mdi:information
        {% elif value == 'LowBattery' %}
          mdi:information
        {% elif value == 'LowFuelLevel' %}
          mdi:information
        {% elif value == 'TooManyUnusedProg' %}
          mdi:information
        {% else %}
          mdi:information-off
        {% endif %}
    - name: e208 Pré-conditionnement
      unique_id: b7c7350c-32ba-495a-aff0-7b88c2a134d5
      state: >-
        {{ state_attr('sensor.psa', 'preconditionning').air_conditioning.status }}
    - name: e208 Puissance de charge
      unique_id: e30a2bf6-3211-4859-abf1-17aa5f132ba6
      state: >-
        {{ state_attr('sensor.psa', 'energy')[0].charging.charging_rate * 0.163 }}
      unit_of_measurement: "kWh"
      icon: mdi:speedometer
############################################################################################################
    - name: e208 Parcouru
      unique_id: 7348f2e2-851f-4dc3-890f-4c73f571fb7e
      state: >-
        {% if is_state('binary_sensor.e208_alimentation', 'on') %}
          {{ states('sensor.e208_autonomie') }}
        {% else %}
          {{ (states('sensor.e208_parcouru')) - (states('sensor.e208_kilometrage') - state_attr('sensor.beta_test_timestamp', 'km')) }}
        {% endif %}
      attributes:
        km: >
          {% if is_state('binary_sensor.e208_alimentation', 'on') %}
            {{ states('sensor.e208_kilometrage') }}
          {% else %}
            {{ state_attr('sensor.e208_parcouru', 'km') }}
          {% endif %}
      unit_of_measurement: "Km"
      icon: 'mdi:map-marker-right'



############################################################################################################
    - name: e208 Fin de charge estimée
      unique_id: c249f813-62dc-474d-bb9f-f94220636f87
      state: >-
        {% set value = state_attr('sensor.psa', 'energy')[0].charging.status %}
        {% if value == 'InProgress' %}

          {% set value = state_attr('sensor.psa', 'energy')[0].charging.remaining_time %}
          
          {% if value.find("H") > 0 %}
            {% set hr = value[value.find("T")+1:value.find("T")+ 3] %}
            {% if hr[1:2] == "H"  %}
              {% set hr = "0" + hr[0] %}
            {% endif %}
          {% else %}
            {% set hr = "00" %}
          {% endif %}

          {% if value.find("M") > 0 %}
            {% set mn = value[value.find("M")-2:value.find("M")] %}
            {% if mn[0:1] == "H" or mn[0:1] == "T" %}
              {% set mn = "0" + mn[1] %}
            {% endif %}
          {% else %}
            {% set mn = "00" %}
          {% endif %}

          {% set result = hr + ":" + mn %}

          {% if result == "00:00" %}
            {{ result }}
          {% else %}
            {{ as_datetime((now() + timedelta( hours = int(hr), minutes = int(mn) )).isoformat()).strftime("%H:%M") }}
          {% endif %}

        {% else %}
          Déconnecté
        {% endif %}
      icon: "mdi:timer-outline"




automation:
  - id: "63a2f136-91ad-4fb7-8f75-0644db525be5"
    alias: "e208 GPS Tracking"
    trigger:
      - platform: state
        entity_id: binary_sensor.e208_deplacement
        attribute: latitude
      - platform: state
        entity_id: binary_sensor.e208_deplacement
        attribute: longitude
    condition: []
    action:
      - service: device_tracker.see
        data:
          dev_id: "e208"
          battery: "{{ state_attr('sensor.psa', 'energy')[0].level }}"
          gps:
            - "{{ state_attr('sensor.psa', 'last_position').geometry.coordinates[1] }}"
            - "{{ state_attr('sensor.psa', 'last_position').geometry.coordinates[0] }}"



switch:
  - platform: command_line
    switches:
      e208_clim:
        command_on: curl -s "http://[IP]:5000/preconditioning/[VIN]/1"
        command_off: curl -s "http://[IP]:5000/preconditioning/[VIN]/0"
        command_state: 'curl -k --silent "http://[IP]:5000/get_vehicleinfo/[VIN]?from_cache=1"'
        value_template: >
          {{ value_json.preconditionning.air_conditioning.status == 'Enabled' }}
        icon_template: >-
          {% set value = value_json.preconditionning.air_conditioning.status %}
          {% set switch = states('switch.e208_clim') %}
        
            {% if value == 'Enabled' %}
              mdi:car-defrost-front
            {% elif value == 'Disabled' or value == 'Finished' %}
              mdi:air-conditioner
            {% else %}
              mdi:alert
            {% endif %}

        command_timeout: 180

rest_command:
  maj:
    url: http://[IP]:5000/wakeup/[VIN]

script:
  e208_maj:
    alias: e208 Rafraichir
    sequence:
      - data: {}
        service: rest_command.maj

Lovelace

  - title: '208'
    path: '208'
    icon: mdi:car-sports
    badges: []
    cards:
      - type: vertical-stack
        cards:
          - type: picture
            image: /local/images/e208.png
            tap_action:
              action: none
            hold_action:
              action: none
          - type: glance
            entities:
              - entity: sensor.e208_kilometrage
              - entity: binary_sensor.e208_deplacement
              - entity: sensor.e208_autonomie
            show_name: true
            state_color: true
          - type: entities
            entities:
              - entity: sensor.entree_frostrisk
              - entity: switch.e208_clim
                secondary_info: last-updated
              - entity: sensor.e208_pre_conditionnement_defaut
              - entity: script.e208_maj
              - entity: sensor.release_psa
      - type: map
        entities:
          - entity: zone.home
          - entity: zone.travail_benjamin
          - entity: zone.travail_celine
          - entity: device_tracker.e208
        hours_to_show: 18
      - type: vertical-stack
        cards:
          - type: gauge
            entity: sensor.e208_batterie
            min: 0
            max: 100
          - type: glance
            entities:
              - entity: binary_sensor.e208_alimentation
              - entity: sensor.e208_charge
              - entity: sensor.e208_puissance_de_charge
            state_color: true
            show_name: true
          - type: entities
            entities:
              - entity: sensor.e208_temps_restant_de_charge
          - type: history-graph
            entities:
              - entity: sensor.e208_parcouru
              - entity: sensor.e208_autonomie
            hours_to_show: 24
            refresh_interval: 0

2 Likes

@limabravo , that worked great for me as well.

Regarding the following

because of time of refresh on primary sensor, switch can turn on, and off, and on before sensor’s update…

…it would be great if the icon_template would be able to show “switch is turned on, but the preconditioning hasn’t started yet”, so that one could see that state as well. Any idea on how to do it? I had a thought that I could add a helper that is controlled by the switch, so that I could use the following conditions (replace the result text with a fitting icon).

if (helper is on AND preconditioning is off)
“started but not running”
else if (helper is on AND preconditioning is on)
“running”
else if (helper is off AND preconditioning is on)
“running from other application” (for example, the preconditioning
is trigged from the app, since the helper isn’t turned on).

Or to be clear, I want to visualize the difference between “switch is pressed but preconditioning isn’t started” and “switch is pressed and preconditioning is started”.

It’s already the case. Icon’s state is different only if préconditionning is enabled or not (whatever switch state).

However, I can’t find a solution to display the switch’s “request” status in addition to the preconditioning status without 3 another entity and automation :frowning:

Ok, the same here :/. But, it’s not a big problem…

Hi,

How can I check what is incorrect in config when all my sensors have status Unaivalable? In PSA Car controller the controller tab is showing mileage and battery percentage. But all other tabs are mentioning no data to show, there is probably no trips recorded yet.

Other question, is there a sensor available for door locked yes or no? Would love to have that one.

Thanks and compliments for all the work!

Check your IP you use in the sensors AND be sure to set port 5000 for Host in Network Settings of the addin.

Hi limabravo,

Can you explain the use of the “e208 Pré-conditionnement Defaut” sensor and how it’s used together with the e208_clim switch?

Cheers!

Hello.

“e208 Pré-conditionnement Defaut” send all data on failure of précond:

  • Defect
  • Door Opened
  • Low Battery
  • Low Fuel Level
  • Too Many Unused Prog

It isn’t used with switch.

Switch is used with “preconditionning.air_conditioning.status”.
Whatever the switch is enabled or disabled, if “preconditionning.air_conditioning.status” sensor get enabled, switch turn on (if précond asked by the app, or the switch). And the same for off.

So, when i turn on the switch, HA send command_on directly to the car, and look with command_state if “preconditionning.air_conditioning.status” is enabled.
Because the update of PSA Sensor isn’t in real time, “preconditionning.air_conditioning.status” is still disabled, so switch return off.
When the car start précond (by HA switch or by the app), PSA Sensor will update “preconditionning.air_conditioning.status” to turn it enabled.
Finally, with “preconditionning.air_conditioning.status” enabled, switch can return on…

I think it’s pretty annoying

Hello :slight_smile:

I am confused about how much of this work because door sensor and moving never worked on my 208, and GPS location stoped working in march 2021

Maybe depend on PSA API…

Don’t we all have the same ? That’s an e-208 right ?

If you try this:

2.2 Get the car state from cache to avoid to use psa api too much
http://localhost:5000/get_vehicleinfo/YOURVIN?from_cache=1

what did you get ?

Summary
{"embedded": null, "links": {"_self": {"deprecation": null, "href": "https://api.groupe-psa.com/connectedcar/v4/user/vehicles/1566c497a5655686153316861544651784d6a41344d7a6b6a49325534596a45315a6d4d785a475a69596a42694f5452694d5755784d6a566b59325a6a4d6a4578596d4d314d32497a4f5463774f5755314d6a4d794d6a67785a4459794d575a6b4f475a6c4d4445354d4449315a444d3d/status", "hreflang": null, "name": null, "profile": null, "templated": null, "title": null, "type": null}, "vehicle": null}, "battery": {"current": 0.0, "voltage": 89.0}, "doors_state": null, "energy": [{"updated_at": "2022-01-10 17:02:21+00:00", "autonomy": 198.0, "battery": null, "charging": {"charging_mode": "No", "charging_rate": 0, "next_delayed_time": "PT0S", "plugged": false, "remaining_time": "PT0S", "status": "Disconnected"}, "consumption": null, "level": 74.0, "residual": null, "type": "Electric"}, {"updated_at": "2021-09-15 10:17:34+00:00", "autonomy": null, "battery": null, "charging": null, "consumption": null, "level": 0.0, "residual": null, "type": "Fuel"}], "environment": null, "ignition": null, "kinetic": {"acceleration": null, "moving": false, "pace": null, "speed": null}, "last_position": {"type": "Feature", "geometry": {"coordinates": [2.00047, 48.76988, 179], "type": "Point"}, "properties": {"heading": null, "signal_quality": null, "type": "Aquire", "updated_at": "2021-03-29 07:17:22+00:00"}}, "preconditionning": {"air_conditioning": {"failure_cause": null, "programs": [{"enabled": true, "slot": 1, "recurrence": "Daily", "start": "PT6H10M", "occurence": {"day": ["Mon", "Tue", "Wed", "Thu", "Fri"]}}, {"enabled": true, "slot": 2, "recurrence": "Daily", "start": "PT16H10M", "occurence": {"day": ["Mon", "Tue", "Wed", "Thu", "Fri"]}}], "status": "Disabled", "updated_at": "2022-01-10 17:02:21+00:00"}}, "privacy": {"state": "None"}, "safety": null, "service": {"type": "Electric", "updated_at": "2022-01-10 17:02:21+00:00"}, "timed_odometer": {"updated_at": null, "mileage": 9192.5}}```

As you can see, location stopped working in march, and i can assure moving or door never update.
Climate, millage and battery do.

If it work for you, can you please tell me when you got the car, and if you have the TELEMAINTENANCE service active ?

Maybe some reading is needed ^^ "kinetic" and "last_position" fields are empty · Issue #50 · flobz/psa_car_controller · GitHub check the recent advancements. Some still can not reactivate it that way and we still dont know what’s happening if you disable the membership at free2move, but it works for me and many others.

1 Like

Ohhhh ! i didn’t check back after the norme was “they removed it from the API and they don’t want to put it back”

is that how you got it @limabravo ? Subbing to Free2move ?
Also is this linked to the door and the motion input ?

I have a nice ui i wanted to share, but it use very old version of a custom lovelace plugin so i feel that it’s not worth it.

Hi Daniel
for the change_threshold % do not works because do not send the command
its a sample command
command_on: curl -s “http://xxx.xxx.xxx.xxx:5000/charge_control?vin=YOURVIN&percentage=80

1 Like

Yes maybe for the GPS. I had a free account i think.

But door and motion don’t work for me… I can remove motion from my ui

1 Like

Ok, it make more sens to me.

I was starting to wonder if i didn’t have bigger issue than just location.

Thank

1 Like

Somehow I can’t seem to get to work the preconditioning switch. My switch looks as follows in configuration.yaml:

switch:
  - platform: command_line
    switches:
      e208_climate:
        command_on: curl -s "http://192.168.2.15:5000/preconditioning/[VIN]/1"
        command_off: curl -s "http://192.168.2.15:5000/preconditioning/[VIN]/0"
        command_state: 'curl -k --silent "http://192.168.2.15:5000/get_vehicleinfo/[VIN]?from_cache=1"'
        value_template: >
          {{ value_json.preconditionning.air_conditioning.status == 'Enabled' }}
        icon_template: >-
          {% set value = value_json.preconditionning.air_conditioning.status %}
          {% set switch = states('switch.e208_climate') %}
            {% if value == 'Enabled' %}
              mdi:car-defrost-front
            {% elif value == 'Disabled' or value == 'Finished' %}
              mdi:air-conditioner
            {% else %}
              mdi:alert
            {% endif %}
        command_timeout: 180

But whenever I turn on this switch (it reverts back as you explained in this post earlier), but nothing happens to my car…Am I missing something?

Sometimes I have the same problem :disappointed: I don’t know why for the moment …

Test just on open the command_on’s url.