<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Patrick Demers</title>
    <description>The latest articles on DEV Community by Patrick Demers (@patrickdemers6).</description>
    <link>https://dev.to/patrickdemers6</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F808183%2F99fb2bb7-02c0-4406-9f78-f2c6e1488d04.jpeg</url>
      <title>DEV Community: Patrick Demers</title>
      <link>https://dev.to/patrickdemers6</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/patrickdemers6"/>
    <language>en</language>
    <item>
      <title>Fleet Telemetry: Streaming Data from Your Tesla</title>
      <dc:creator>Patrick Demers</dc:creator>
      <pubDate>Sat, 24 Feb 2024 10:01:29 +0000</pubDate>
      <link>https://dev.to/patrickdemers6/fleet-telemetry-streaming-data-from-your-tesla-2i97</link>
      <guid>https://dev.to/patrickdemers6/fleet-telemetry-streaming-data-from-your-tesla-2i97</guid>
      <description>&lt;p&gt;Tesla's recent rollout of &lt;a href="https://github.com/teslamotors/fleet-telemetry" rel="noopener noreferrer"&gt;fleet-telemetry&lt;/a&gt; empowers authorized users to seamlessly stream real-time data directly from Tesla vehicles. Let's delve into the process of initiating live data streaming from a Tesla vehicle.&lt;/p&gt;

&lt;p&gt;To make this as smooth as possible, a few important notes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I created a &lt;a href="https://www.postman.com/patrickdemers6/workspace/tesla-fleet-api" rel="noopener noreferrer"&gt;Postman collection&lt;/a&gt; to help with the API requests sent during this tutorial.&lt;/li&gt;
&lt;li&gt;The latest documentation for Tesla's Fleet API is available &lt;a href="https://developer.tesla.com/docs/fleet-api" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Create a Developer Account
&lt;/h2&gt;

&lt;p&gt;To begin your quest for data, first create a developer account on Tesla's official developer portal: &lt;a href="https://developer.tesla.com" rel="noopener noreferrer"&gt;developer.tesla.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I recommend selecting all scopes as there is no downside. Here is my configuration for Client Details:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frcjk1gp7jfdlydxifhuk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frcjk1gp7jfdlydxifhuk.png" alt="Client Details of Tesla developer application"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Finishing Application Registration
&lt;/h2&gt;

&lt;p&gt;Once your developer application is created, you must register it with Fleet API.&lt;/p&gt;

&lt;p&gt;This includes submitting a certificate signing request (CSR) to Tesla. To create one, first generate a private key.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

openssl ecparam &lt;span class="nt"&gt;-name&lt;/span&gt; prime256v1 &lt;span class="nt"&gt;-genkey&lt;/span&gt; &lt;span class="nt"&gt;-noout&lt;/span&gt; &lt;span class="nt"&gt;-out&lt;/span&gt; private-key.pem


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now, derive its public key.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

openssl ec -in private-key.pem -pubout -out public-key.pem


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Make this public key accessible at: &lt;code&gt;https://your-domain.com/.well-known/appspecific/com.tesla.3p.public-key.pem&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: there are two domains you may use throughout this tutorial. The first one is your public domain users are familiar with (such as your-domain.com). This is the domain you host your public key on. The second domain is the domain your fleet-telemetry server is exposed on (such as tesla-telemetry.your-domain.com).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, using the private key, create a CSR.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

openssl req -out your-domain.com.csr -key private_key.pem -subj /CN=your-domain.com/ -new


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;With all this created, let's send it to Tesla.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In Postman, fill in your environment variables (client id, client secret, scopes, audience, redirect uri).&lt;/li&gt;
&lt;li&gt;Send the "Generate Partner Token" request.&lt;/li&gt;
&lt;li&gt;Send the "Register Partner Account" request.

&lt;ul&gt;
&lt;li&gt;Input the appropriate &lt;code&gt;domain&lt;/code&gt; and &lt;code&gt;csr&lt;/code&gt; in the body.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Sample body:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"domain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"your-domain.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"csr"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"-----BEGIN CERTIFICATE REQUEST-----&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;cert_data&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;-----END CERTIFICATE REQUEST-----&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;
}


&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Once this is submitted, Tesla will process the CSR and update your account on the backend accordingly. It may take a few weeks to process. In the meanwhile, check out all the capabilities of &lt;a href="https://developer.tesla.com/docs/fleet-api" rel="noopener noreferrer"&gt;Fleet API&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  After CSR Confirmation
&lt;/h2&gt;

&lt;p&gt;Once you receive a confirmation email from Tesla, you can begin configuring your fleet-telemetry server. Since the server will need to be accessible to the world, I am using a &lt;a href="https://www.linode.com/lp/refer/?r=1d59b066db56b58778f5e5859ee4e9ed96a56b9f" rel="noopener noreferrer"&gt;Linode nano&lt;/a&gt; server to run everything.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Create another CSR (optional)
&lt;/h3&gt;

&lt;p&gt;If the domain your fleet-telemetry server will be on is different from the domain used in the CSR above, create a new CSR for this domain.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Obtain a Certificate and CA Bundle
&lt;/h3&gt;

&lt;p&gt;Next, we need to obtain a certificate for fleet-telemetry to use for TLS connections. There are many ways to do this, but I opted for a free and simple soution: LetsEncrypt and Certbot.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: Ensure your server's DNS is configured for this to work.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="c"&gt;# install certbot&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;snap &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--classic&lt;/span&gt; certbot

&lt;span class="c"&gt;# ensure certbot command can be run&lt;/span&gt;
&lt;span class="nb"&gt;sudo ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; /snap/bin/certbot /usr/bin/certbot

&lt;span class="c"&gt;# create the certificate&lt;/span&gt;
&lt;span class="c"&gt;# when offered http server or validation files, I opted for http server (option 1)&lt;/span&gt;
certbot certonly &lt;span class="nt"&gt;-d&lt;/span&gt; tesla-telemetry.your-domain.com &lt;span class="nt"&gt;--csr&lt;/span&gt; tesla-telemetry.your-domain.com.csr



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The output of this last command should tell you where the certificate and full certificate chain are located. Copy these files into an easy to access directory.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

Successfully received certificate.
Certificate is saved at:            /root/fleet-telemetry/0000_cert.pem
Intermediate CA chain is saved at:  /root/fleet-telemetry/0000_chain.pem
Full certificate chain is saved at: /root/fleet-telemetry/0001_chain.pem


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Create fleet-telemetry config
&lt;/h2&gt;

&lt;p&gt;The fleet-telemetry server takes a JSON configuration file. You can take this template and customize accordingly:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"host"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0.0.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"hostname"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tesla-telemetry.your-domain.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;443&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"log_level"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"debug"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"json_log_enable"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"namespace"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"telemetry"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"reliable_ack"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rate_limit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"enabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"message_limit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"records"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"alerts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"logger"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"errors"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"logger"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"V"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="s2"&gt;"logger"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tls"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"server_cert"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"path to certificate from previous step"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"server_key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"path to private key"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ca"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"content of full certificate chain file from previous step"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;The &lt;code&gt;hostname&lt;/code&gt; and &lt;code&gt;ca&lt;/code&gt; fields are not required. They must be included to use the &lt;code&gt;check_server_cert.sh&lt;/code&gt; script later in tutorial.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Start your server
&lt;/h2&gt;

&lt;p&gt;There are many ways to start your fleet-telemetry server. I opted to use Docker with the following &lt;code&gt;docker-compose.yml&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3.8'&lt;/span&gt;

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./repo&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;0.0.0.0:443:443&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/path/on/host/to/certs:/config&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/path/on/host/to/config.json:/etc/fleet-telemetry/config.json&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This requires having &lt;code&gt;fleet-telemetry&lt;/code&gt; cloned to the &lt;code&gt;repo&lt;/code&gt; directory:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

git clone https://github.com/teslamotors/fleet-telemetry.git repo


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Then, start the server with &lt;code&gt;docker compose up&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;However you run fleet-telemetry, ensure your server is accessible to the outside world on port 443. This is the port vehicles use when connecting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Validate server configuration
&lt;/h2&gt;

&lt;p&gt;Tesla provides a handy &lt;a href="https://github.com/teslamotors/fleet-telemetry/blob/main/tools/check_server_cert.sh" rel="noopener noreferrer"&gt;check_server_cert.sh&lt;/a&gt; script to ensure your server is configured properly.&lt;/p&gt;

&lt;p&gt;From your local machine, run the script. Pass in the path to your server's &lt;code&gt;config.json&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

./check_server_cert.sh config.json


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Before moving on, be sure to get the success message from this script.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add Fleet Key to Vehicle
&lt;/h2&gt;

&lt;p&gt;Before configuring a vehicle, it needs your Fleet Key (public key) to be added. To do this, send the owner to &lt;a href="https://tesla.com/_ak/your-domain.com" rel="noopener noreferrer"&gt;https://tesla.com/_ak/your-domain.com&lt;/a&gt;. This will prompt them to add your key to the vehicle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Send configuration to vehicle
&lt;/h2&gt;

&lt;p&gt;Once the server configuration is validated, it's time to try sending data from a real vehicle.&lt;/p&gt;

&lt;p&gt;The endpoints we used earlier required Partner Account tokens. The endpoints we will be using here act on behalf of a customer account.&lt;/p&gt;

&lt;p&gt;When we called the "Generate Partner Token" endpoint earlier, an environment variable &lt;code&gt;AUTHORIZE_URL&lt;/code&gt; was created in Postman. Grab that URL and paste it into your browser. This redirects to Tesla for authenticating with a customer account.&lt;/p&gt;

&lt;p&gt;Once Tesla redirects to the redirect URI, extract the &lt;code&gt;code&lt;/code&gt; from the URL parameters and paste it into the &lt;code&gt;CALLBACK_CODE&lt;/code&gt; environment variable in Postman.&lt;/p&gt;

&lt;p&gt;Now, go back to Collections in Postman. Send the "Code Exchange" request.&lt;/p&gt;

&lt;p&gt;Next, let's setup and send the "Send Fleet Telemetry Config" request. This places your streaming config on a vehicle.&lt;/p&gt;

&lt;p&gt;Here is an example body for the request:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"vins"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"VIN"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"config"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"hostname"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tesla-telemetry.your-domain.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;443&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"ca"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"full certificate chain (actual contents, not path)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"fields"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Soc"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"interval_seconds"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;You can view all possible fields &lt;a href="https://github.com/teslamotors/fleet-telemetry/blob/main/protos/vehicle_data.proto" rel="noopener noreferrer"&gt;in this file&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once you send the request, the impacted VINs will begin trying to send data shortly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Receiving Data
&lt;/h2&gt;

&lt;p&gt;If everything went smoothly, the logs from your fleet-telemetry server should begin showing realtime vehicle data.&lt;/p&gt;

&lt;p&gt;Here's a sample of what I received:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Soc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"stringValue"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"79.147"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"createdAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2024-02-24T07:23:58.314605660Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"vin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TESLA00000001"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If you aren't receiving data or are seeing TLS errors, send a request to the "Fleet Telemetry Errors" endpoint. It shows any errors the vehicle is encountering.&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;br&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"response"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;br&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"fleet_telemetry_errors"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;&lt;br&gt;
            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;br&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"created_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2024-02-24T06:54:20.660684365Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;br&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;webconnection error: x509: certificate relies on legacy Common Name field, use SANs instead&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; cm_type=stream"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;br&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"error_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cloud_manager_error"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;br&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"hostname"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"your-domain.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;br&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"121c18bba1fc-4058-bd98-687727180599"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;br&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"443"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;br&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"txID"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"edf2ba8d-cc8b-4d03-b619-74bd5a0e0be8"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;br&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"vin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TESLA00000001"&lt;/span&gt;&lt;span class="w"&gt;&lt;br&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&lt;br&gt;
    &lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&lt;br&gt;
&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Congratulations&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;If you made it this far, hopefully you are seeing realtime data from your vehicle. Nice work! Hopefully you can leverage this data to build something awesome 😎&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
