How to test your system with simulated vehicles

Introduction

We are providing you with some methods to let you test your own system in a production-like environment.

This way, if your system runs fine in these test conditions, it will run smoothly in a production environment.


On this page, you'll learn how to test your system by using simulated vehicles.

Follow the steps, and you'll be able to reproduce your specific use-case exploring multiple functionalities.

The testing environment supports all the use-cases linked to the generic commands:


START

STOP

LOCATE


Do you have a fantastic idea that you want to realize? Use this tutorial to make your dreams come true.


One last recommendation before you go: do you remember you have to do authentication and authorization? No? Check out our Guides!



Now, let's start from the beginning!

πŸ“˜

Info

We're going to create simulated vehicles that behave like their real counterparts.
The simulator supports 2hireBox and Omni-Ninebot enabled vehicles, in this guide we're going to focus on the 2hireBox ones.


Your first move will be to create a simulated vehicle.

The endpoint response will contain a body with an array of identifiers made of fifteen random numeric digits representing the identifier of your testing vehicles.


You'll need those to change the vehicles' statuses later on.

POST
e2e.adapter.2hire.io/devices/

The success response will consist of the following:

ParameterTypeDescription
devicesarrayArray containing the device just created.
devices[n].identifierstringRandom numeric identifier of the device. You can use the identifier to interact with the simulated vehicle through the End-to-End API.
devices[n].qrCodestringQRCode of the simulated vehicle. It will be required to register the vehicle.
{
  "devices": [
    {
      "identifier": "000450188066859", //Random numeric identifier
      "qrCode": "MVQR_000450188066859" //Simulated QRCode of the vehicle
    }
  ]
}

Quick tip! You may have noticed that the "qrCode" and the indentifier are pretty similar. We suggest copying just one of them. We'll let you decide which one.

In the case of a gateway connection failure, the error response will consist of the following:

{
    "code": "INTERNAL_ERROR",
    "details": {
        "cause": "INTERNAL_ERROR"
    },
    "errorId": string
}



Once you have created your simulated vehicle, you can register in the testing environment. This will let you interact with it as if it were real.

PUT
test.adapter.2hire.io/api/v1/vehicle/register
Requires authorization

Request

Body table for 2hireBox-enabled vehicles:

NameTypeDescription
connectivityProviderstringThe provider of the vehicle's IoT.
data.qrCodestringQRCode IoT's identifier
data. profileId stringIdentifier of the configuration for the vehicle on which the IoT will be installed. In order to configure simulators, the profile id 51ba5b28-28da-435a-b42e-a3931288470c need to be used

The success response will consist of the following:

ParameterTypeDescription
vehicleIdstringUUID v4 identifying the registered vehicle. You can use it to interact with the simulated vehicle through the Test API.
{
  "vehicleId": "542349940-cfe7-4057-8172-0c3a6f06a0e3"
}

πŸ“˜

Info

You can optionally subscribe to the webhooks to receive signals updates.
Follow this guide to check how to do that.




Vehicle state

Once you have your vehicle registered, you can start to change its state in order to send events to your system.

For this purpose, we'll provide you with a set of endpoints to retrieve the current values and set some new ones.

The vehicle state endpoint exposes the intrinsic vehicle's characteristics and can be used to gather the current state.

The simulated vehicle state has an initial value for each generic signal.

Later on, you'll be able to define all the values through endpoints.

The status defines the vehicle behaviour, which will change in response to the generic commands and over time.

So, always pay attention to your vehicle's status!


It'll be crucial in all the next steps.


The vehicle state has the following properties (reflecting the related signals):

Online

The starting value is true.

It'll change in false if the autonomy percentage goes under 0%.

Does it sound familiar to you?

🚧

Warning

The online signal has specific behaviour, it is sent every time the status changes and every 15 minutes if it doesn't.


Position

The starting position is predefined, and embedded in our code, the vehicle sends it with a message.

Don't get scared. You'll be able to perform fantastic trips all around the world, from your home of course.


Distance covered

The starting value is 0.

The simulated trip represents a vehicle movement, so it will produce an increment in the value.

We evaluate an average testing speed of 15 km/h. Every minute in trip equals an increment in the distance covered of 250 m.

Always respect the speed limits.

🚧

Warning

Remember the position is saved only when it changes above the fifth decimal place (included).
Simulated vehicles always send the same position when being still, this will mean that you'll only receive the first position.


Autonomy percentage

The starting value is 100%.

Every minute, the value will drop off by a defined percentage, depending on the vehicle status.

LOCKED

-2%

UNLOCKED

-4%

MOVING

-8%


Don't forget your vehicle unlocked or you won't be able to go too far away.


Autonomy meters

The starting value is specific to the type of the vehicle.

The value will drop off progressively in parallel with the autonomy percentage.

A 2% drop in the autonomy percentage equals a 2% drop in the starting autonomy meters.

Too much math? You can find somewhere a fantastic calculator ready to help you.


Trunk status

This specific signal emulates the status of a car's trunk.
If the trunk is closed the trunk status is true, false otherwise.

The starting value is true.

Don't forget your trunk open or you might don't find your car where you leaft it.

🚧

Warning

The trunk status is a specific signal.
Remember, this type of signal is available only on a subset of compatible vehicles.


Status

The starting status is LOCKED.

There are three possible statuses:

UNLOCKED

LOCKED

MOVING


Calling the generic commands and the trip endpoints will change the status.


START

=

LOCKED

UNLOCKED

STOP

=

UNLOCKED

LOCKED

TRIP

=

UNLOCKED

MOVING

TRIP END

=

MOVING

UNLOCKED


I'm sure you'll never pay enough attention to the vehicle status. Don't let me down!


Last locate

The starting value is undefined.

The locate command execution will update the timestamp value with the current date.


You'll be able to recover an actual vehicle state.

GET
e2e.adapter.2hire.io/devices/:identifier/state
ParameterTypeDescription
identifierstringThe identifier of the vehicle for the state you want to retrieve.

The response body will consist of the following:

{
  "position": {
    "timestamp": 1488700800000, //always set to current timestamp
    "data": {
     "longitude": -3.69623494,
     "latitude": 40.42277527,
    },
   },
  "autonomy_meters": {
    "timestamp": 1488700800000, //always set to current timestamp
    "data": {
     "meters": 800000, //max autonomy of the vehicle
    },
   },
  "distance_covered": {
    "timestamp": 1488700800000, //always set to current timestamp
    "data": {
     "meters": 0,
    },
   },
  "online": {
    "timestamp": 1488700800000, //always set to current timestamp
    "data": {
     "online": true,
    },
   },
  "autonomy_percentage": {
    "timestamp": 1488700800000, //always set to current timestamp
    "data": {
     "percentage": 100,
    },
   },
   "status": "LOCKED",
   "lastLocate": undefined,
}

Remember, the vehicle state is fundamental to simulate any possible flows.


That's a lot of information!


Vehicles are complex. Get used to it!


This set represents the most relevant information you'll need in your integration.



πŸ‘

Congrats

Now that you know which signals the simulated vehicle support and how they work, you're ready to start changing them and interacting with the simulated vehicle.

Vehicle functionality

The simulated vehicle can:

  • Receive messages and generate events from all the generic commands and signals.

  • Send a heartbeat (a periodic signal to indicate regular operation) with a position within a predefined time interval.

  • Simulate a trip from a set of positions.

  • Update its status depending on an interaction.

  • Check the status to avoid incoherent operations.

    e.g. ERROR if stop in LOCKED

  • Trigger an alarm message if the trip starts in the LOCKED status.

  • Continue to change its state following the supposed behaviour even if manually set offline.

I bet now you're thinking these functionalities aren't enough for your use-cases.


Wait for the next step to discover what you'll be able to do.


You'll be able to simulate a trip with your vehicle.

You'll declare an array of positions, each position defines a point in the trip track.

POST
e2e.adapter.2hire.io/devices/:identifier/trips
ParameterTypeDescription
identifierstringThe identifier of the vehicle to be modified.

Each element in the array:

  • Corresponds to a point in the trip track.
  • Updates the vehicle's position every ten seconds.
  • Generates a webhook event.

The first element triggers the start of the trip, which changes the status to MOVING.

The last element represents the stop of the trip, which changes the status to UNLOCKED.

The request body will consist of the following:

{
 "positions": [
  {
   "longitude": -3.69623494,
   "latitude": 40.42277527
  },
  {
   "longitude": -3.69623494,
   "latitude": 40.42277527
  },
  {
   "longitude": -3.69582844,
   "latitude": 40.42259979
  },
 ]
}

The success response body will consist of the following:

{
    "success": true
}

If the vehicle is in LOCKED status, an error response will be returned.
Remember to unlock the vehicle by starting it with the test endpoint before starting a trip.

Body response:

{
    "success": false,
    "code": "VEHICLE_INTERACTION_ERROR",
    "details": {
        "cause": "COMMAND_FAILED"
    },
    "errorId": string
}

This is truly interesting!


A vehicle that can't move is a useless thing. Don't you agree?


You'll be able to define a vehicle's autonomy percentage.

This will let you discharge or recharge a vehicle immediately.

PUT
e2e.adapter.2hire.io/devices/:identifier/state/battery
ParameterTypeDescription
identifierstringThe identifier of the vehicle to be modified.

The request body will consist of the following:

{
	"percentage": number
}

The response body will consist of the following:

{
    "success": true
}

Be careful with this parameter. Remember that it drops off through time.


We don't want you to be stuck in the middle of nowhere.


You'll be able to define a vehicle's online status.

PUT
e2e.adapter.2hire.io/devices/:identifier/state/online
ParameterTypeDescription
identifierstringThe identifier of the vehicle to be modified.

The request body will consist of the following:

{
	"online": true
}

The response body will consist of the following:

{
    "success": true
}

It's the same old story. In these times, to be offline is like to be cut off from the world.


You'll be able to define a vehicle trunk status.

PUT
e2e.adapter.2hire.io/devices/:identifier/state/trunk
ParameterTypeDescription
identifierstringThe identifier of the vehicle to be modified.

The request body will consist of the following:

{
	"closed": true
}

The response body will consist of the following:

{
	"success": true
}


πŸ‘

Nice job!

Now that you know how to interact with a simulated vehicle in order to change its signals, it's time to receive the changes in real time.

Start receiving signals events

  1. Clone the testing server as described in the Setup a demo server cookbook.
  2. Subscribe to signal changes via the topics of interest as described in the Receiving signals guide.
  3. Try simulating a trip in order to generate events.


Errors are always around the corner.


We want to help you avoid strange situations, or catch them if it's what you're trying to do!


Potential errors

The identifier used in the API calls has to be among those created when adding vehicles.

The error response to an API call with the wrong identifier will consist of the following:

{
    "code": "VEHICLE_NOT_FOUND_ERROR",
    "errorId": string,
    "details": {
        "cause": "VEHICLE_NOT_REGISTERED"
    }
}

You wouldn't start a vehicle that it's not yours.


If the vehicle is LOCKED, you won't be able to start a trip.

The error response will consist in the following:

{
    "code": "VEHICLE_INTERACTION_ERROR",
    "errorId": string,
    "details": {
        "cause": "COMMAND_FAILED"
    }
}

In addition to the error response, this action will trigger an Alarm Event to the gateway, which consequently causes a webhook event.

Have you ever tried to move a locked car? It's a crime!


If the vehicle's autonomy percentage reaches 0%, it will disconnect from the gateway.

How many times did your kick scooter run out of charge, and you had to walk back home?


After 10 minutes from when the vehicle was completely discharged, it'll be removed from the service and made unavailable.

It's a strict rule, I know it. But a rule is a rule. Follow it!



Summary

In the previous sections, you can find all the elements you need to test your own system.


Have you realized how many unbelievable things you are now able to do?


Here is a brief recap for you.


Now you have all the tools needed to simulate real exciting use-cases.

You can easily:

  • Create your fleet.
  • Interact with each vehicle.
  • Simulate a trip with the related increment in the vehicle's distance covered.
  • Change the vehicle's status.
  • Reproduce the natural discharge of the vehicle's autonomy percentage and the related vehicle's autonomy meters.
  • Simulate the vehicle's behaviour with connection issues.

All the endpoints, excluding those of the end-to-end test API, are equal to our production API.

Did you get that? The transition from test to production we'll be a piece of cake.
So, now that you are able to simulate a vehicle behavior in real life let’s get serious and develop some real code