Test Your App with Virtual Vinli

Virtual Vinli is a system of tools that allow you, the developer, to test your application with standardized, repeatable routes. These routes are driven by virtual devices that appear to the platform as real devices, but are managed completely by you. Managing so-called "Dummy Devices" is done through the Dummy Service (API endpoint: https://dummies.vin.li), but we include all the necessary commands in the Vinli CLI to make it a bit easier to work with.

Creating a Dummy Device creates a record in the Dummy Service and adds the device to the internal "inventory" of the platform. This includes generating fictitious case ID and device ID, things that otherwise exist only on a physical device. In this way, you can do all the things with a Dummy Device that you can do with a real device (with the exception of plugging it into a car, of course).

Start by creating a Dummy Device:

> vinli dummy create --name "My Fake Vinli"

│        ID │ 027d2a40-d229-4436-ae5e-9fca3c8628a9 │
│      Name │ My Fake Vinli                        │
│ Device ID │ 5e8075d2-c518-4164-91eb-5eb008e75b19 │
│   Case ID │ VVBD735                              │

If you haven't set your current app you'll need to either run vinli app set-current, or get your app and secret from the Developer Portal and set VINLI_APP and VINLI_SECRET environment variables.

It's important to note that creating a dummy device does not automatically add that device to your application. This allows you to walk through the normal lifecycle of the device. You can add it to a MyVinli account based on its case id. List out your dummy devices to get the device id and case id. We'll show you how to add the device to your MyVinli account after we cover a few more basics.

> vinli dummy list
│ ID                                   │ Name          │ Device ID                            │ Case ID │
│ 027d2a40-d229-4436-ae5e-9fca3c8628a9 │ My Fake Vinli │ 5e8075d2-c518-4164-91eb-5eb008e75b19 │ VVBD735 │
                                                                                       Showing 1 - 1 of 1

Another important note is that the dummy's ID is not the same as the Device ID. When working with the device on the rest of the platform, you will need to use the Device ID (5e8075d2-c518-4164-91eb-5eb008e75b19 in this case). When starting runs and managing the "virtual" side of the device, you will need to use the Dummy ID (027d2a40-d229-4436-ae5e-9fca3c8628a9).

Now that you have your dummy, you can start a run. A run is when a dummy device virtually drives through a route. Routes are pre-defined driving trips that we've set up to help you test different scenarios.

Let's start a run with the dummy device. To get a list of available routes:

> vinli dummy routes

│ ID                                   │ Name                   │ Description                              │ Distance (m) │ Duration (s) │ Messages │ Locations │
│ 64803498-cc0d-4724-99ef-e0d32d527670 │ DFW - Downtown Route 1 │ Out and about in downtown Dallas.  This  │      8904.45 │          499 │      139 │       120 │
│                                      │                        │ route includes MAF and several other     │              │              │          │           │
│                                      │                        │ low-frequency parameters.                │              │              │          │           │

We can pick the "DFW - Downtown Route 1" route. From the list you can tell that it is about 9km and 500 seconds long. We will have to pick a VIN number, and to make sure that we don't interfere with any real vehicles, the VIN must start with VV. Vinli CLI will create a random one for you if you don't specify, so let it do that this time:

> vinli dummy start --dummy="My Fake Vinli" --route="DFW - Downtown Route 1"

Starting run of DFW - Downtown Route 1 for dummy My Fake Vinli (VVTWVVB97E2HL4KU6)...
Run started

Note that you can specify either the dummy ID and route ID, or you can use a string and the CLI will find the closest dummy or route.

Now that the dummy is running, you can query it to see where it is on its route:

> vinli dummy status --dummy="My Fake Vinli"

│          Route │ DFW - Downtown Route 1               │
│         Status │ running                              │
│         Repeat │ false                                │
│   Repeat Count │                                      │
│    Speed (kph) │ 78                                   │
│  Remaining (s) │ 436.004                              │
│ Remaining Msgs │ 142                                  │

Just like a real Vinli Device, each Virtual Vinli can only run one run at a time; however each application can have up to five Virtual Vinlis that can run simultaneously if desired.

Great! We have a virtual Vinli device virtually driving around a virtual Dallas. But how do we use this device in our application? If you try to get data from the device:

> vinli device locations --device=5e8075d2-c518-4164-91eb-5eb008e75b19

Server could not process request:

  403 Forbidden - Application not authorized for device


One of the most important things to realize about virtual vinlis is that, though they are created by your application, they do not automatically get added to your application. They need to go through the same process as any real device:

  1. A user needs to add it to their MyVinli account.
  2. Your app has to request and receive access to this account's devices via OAuth.

Thankfully, vinli-cli provides helper commands to do this from the command line. You'll need credentials to a MyVinli account, then:

> vinli auth add-device --case-id=VVBD735

Add Device:email: testuser@vin.li
Add Device:password: *******
Add Device:caseId: (VVBD735)
Add Device:name: (CLI Vinli) My Fake Vinli

Signing in to testuser@vin.li MyVinli account...
Authenticated user.  Adding device...
        Device Added

which will add the device to a MyVinli account, then go through the oauth flow:

> vinli auth authorize

signup:email: testuser@vin.li
signup:password: *******

Signing in to testuser@vin.li MyVinli account...
Authenticated user.  Initiation OAuth flow for application...
Authorizing application...

Note, for this to work you need to create a web client for your app.

Now you can use your app credentials to access the Dummy Device's data (remember to use the device ID, not the dummy ID):

> vinli device locations --device=5e8075d2-c518-4164-91eb-5eb008e75b19 --limit=3

│ Timestamp                 │ ID                                   │ Longitude  │ Latitude  │
│ 2016-01-28 16:11:34 -0600 │ cdc63207-ca8a-4208-84b3-655f72a7190e │ -96.792305 │ 32.781268 │
│ 2016-01-28 16:11:34 -0600 │ f5191093-780f-4e5b-acf6-37ca3988d8a8 │ -96.792336 │ 32.781266 │
│ 2016-01-28 16:11:34 -0600 │ 50d5e192-2ea1-4284-9ab1-7b11d5f27ba8 │ -96.792337 │ 32.781261 │
                                                                      Showing 3, 98 remaining

The Dummy Device will automatically stop at the end of the route and be ready for the next route, but if you want to stop it early, you can run:

> vinli dummy stop --dummy="My Fake Vinli"

Stopping run for dummy 027d2a40-d229-4436-ae5e-9fca3c8628a9...
Run stopping...

Understanding the Route

Using the HTTP API, you can get a bit more data about the route:

curl -u $VINLI_APP_ID:$VINLI_APP_SECRET "https://dummies.vin.li/api/v1/routes/64803498-cc0d-4724-99ef-e0d32d527670"

  "route": {
    "id": "64803498-cc0d-4724-99ef-e0d32d527670",
    "name": "DFW - Downtown Route 1",
    "description": "Out and about in downtown Dallas.  This route includes MAF and several other low-frequency parameters.",
    "messageCount": 139,
    "locationCount": 120,
    "distanceByGPS": 4506.49,
    "distanceByVSS": 8904.45,
    "duration": 499277,
    "preview": "wb_gElezmQ?wCm@sC{F}HiDiEq@uAsA}AeDsEyCgJKgCk@uDUaCa@cC_@kDYcFAiBOaCGeC_@eI_@oDi@wDiBgFw@wAuAiBqDeEaEmF_BaAoBq@cDSsB~BwApBsAdCaDpGyB`GuAtC{@`Dg@bIZ|Bn@hEOQJ?E?BbAN|@Nb@HbA\~AFrBH`@LzAHf@r@LZAj@D\Or@Cp@a@\KCEABBDAEB?\]g@}C]gCBDDEAEt@g@Rw@AWOm@V]G]MOOFCFBBDE@N?I",
    "links": {
      "self": "https://dummies.vin.li/api/v1/routes/64803498-cc0d-4724-99ef-e0d32d527670"

One of the most useful pieces of data regarding a route is the preview, which is an encoded polyline (https://developers.google.com/maps/documentation/utilities/polylinealgorithm). You can use this to see what the general route the vehicle will take:

Route Preview for "Downtown Dallas - Route 1"