Deez Watts
IntroductionWorkloadsAppsImplementationsResourcesData Exhaust
  • A Rivian Data Adventure
  • INTRODUCTION
    • Architecture
    • Data Access
    • Rivian Databricks
    • The Whip
  • Workloads
    • Rivian Falcon LogScale
    • Rivian NATS Comms
  • Apps
    • Rivian Prometheus Exporter
    • Rivian Configurator Rotator
  • Implementations
    • Rivian Geo via IRIS Document Database
    • Rivian on FHIR®
  • Data Exhaust
    • Fun with ffmpeg, Gear Guard at Iceman 2024
  • Resources
    • Repos
    • Miscellaneous
Powered by GitBook
On this page
  • Hardware
  • Network/Sound Setup
  • Implementation
  • Demo
  1. Workloads

Rivian NATS Comms

PreviousRivian Falcon LogScaleNextRivian Prometheus Exporter

Last updated 1 year ago

So this workload is about using to communicate from the Data workload to the truck based on events that it sees. Other workloads are directed at applying the telemetry being pulled from the Rivian API to describe the state of the vehicle while it is in motion or at rest, this particular workload is about responding to the events and opening up opportunities to carry out events directly pushed to the whip through an always available dial tone.

We accomplish this by using a minimal hardware implementation on the truck, that takes advantage of the hotspot/bluetooth, and a implementation on the Deez Watts Data workload.

I discovered during the wait for delivery of the truck (I also had two birthdays and achieved AARP status), and discovered in the Rivian Github repo that they had forked , and by best guess here they most likely at some point or maybe even currently use the implementation to deliver OTA updates.

Working backwards from that discovery, I bought the book, installed the helm chart and applied it here in true Rivian Data Adventure fashion.

Hardware

Now here is where you can question the issuance of my man card perse, as others are driving their trucks off road, taking 6 kids to practice, or loading up the dogs and heading to the beach, I am sitting in the backseat at a Chargepoint imaging a raspberri pi... takes a village I guess.

So I took a Raspberry 4B, installed Ubuntu on it and went to work, I paired the audio to the bluetooth stack and associated the wifi to the onboard hotspot and threw it in the center console where there are two USB-C opportunities in the console that power the Raspberry PI sufficiently, in addition to the storage for Gear Guard imaging.

From an OS perspective I enabled automated logon, installed python, the nats module from pypi, and festival from apt. Then invoked the below script to run interactively at startup.

Network/Sound Setup

Implementation

Now the script is a few bytes longer than the hello world example from NATS, but Ill explain what it is doing anyway.

import asyncio
from nats.aio.client import Client as NATS
import os

async def run(loop):
    nc = NATS()
    
    async def disconnected_cb():
        print("Got disconnected...")

    async def reconnected_cb():
        print("Got reconnected...")

    await nc.connect("nats.deezwatts.com:42222",
                     reconnected_cb=reconnected_cb,
                     disconnected_cb=disconnected_cb,
                     max_reconnect_attempts=-1)
                     #loop=loop)
    print(nc.is_connected)

    # Use queue named 'deezwatts' for distributing requests
    # among subscribers.
    sub = await nc.subscribe("deezwatts")
    #await nc.subscribe("help", "deezwatts", help_request)

    print("Listening for requests on 'deezwatts' subject...")
    for i in range(1, 1000000):
        await asyncio.sleep(1)
        try:
            # Process a message
            msg = await sub.next_msg()
            print("Received:", msg.data)
            print(type(msg.data))
            # Speak to the Rivian
            os.system('echo %s | festival --tts' % msg.data.decode())
        except Exception as e:
            print("Dial Tone: " + str(nc.is_connected))
            #print("Status: " + str(e))

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(run(loop))
    loop.run_forever()
    loop.close()

So NATS is essentially a pub/sub queue, like Google Cloud Pub/Sub, Amazon SQS, Rabbit MQ or whatever it is on that other cloud with slow disk and shit support out of Redmond, WA. So the running NATS is simply a server side queue, and the Rivian just polls the queue and subscribes to messages being published there, continually, in lightweight fashion.

Once it gets a message, this implementation simply takes the string off the message payload, and pipes it through festival and "says" it audibly through the speakers on the whip. Super great if you are at a campsite with the Portable speaker and want to include your truck in the conversation while dealing Johnny Cash hits as one does at camp fires quite frequently.

Demo

So for the demo, its going to be borderline stupid, but we knew that going into this project anyway.

So if we are pumping telemetry data into Databricks at an interval and we have a true streaming workload implemented, we can set an alert to react to conditions it seems in the data while passing through. That alert must publish a message to the NATS queue so that the truck can pull it off the queue on the other end. We can do this with Databricks or we can do this with our implemtation of Crowdstrike Logscale or just bash it up for a quick demo.

External Event

We can listen to other events too, maybe some home automation or gods forbid you decide to wire up your work slack/teams or some other life intrusive technology in annoying fashion.

Here we are going to notify the driver they have been Rick Rolled.

So there you have it, full cycle comms implemented through NATS and some python tricks with an always available dial tone.

For this, we wanted to speak to the Rivian, so we pipe that message through so in essence gives the truck a voice.

NATS
NATS
NATS
NATS
GitHub - sween/rivian-nats: An always available Dial Tone for Rivian CommsGitHub
You've been rick rolled.
Logo
Associated to the Rivian Hotspot
Paired as a Headset
festival