Skip to content

User interface

openOBD supports displaying a user interface to both the customer (i.e. the car mechanic) and the operator. This makes it possible to inform the customer and operator during an automated diagnostic procedure, and allows the diagnostic procedure to be controlled through input from the customer or operator.

Displaying the user interface

To display the user interface, we need to make use of the userInterface service. This service contains the openControlStream method, which is a bidirectional stream, using Control messages as both requests and responses.

When creating a Control message, we need to provide it with the following data:

  • The InterfaceType to indicate to whom the user interface should be shown. By default, it will be shown to the customer.
  • The control type to indicate what should be displayed. A UserInterface message can contain only one control type at a time.

The response for a UserInterface message will be sent the moment the user presses a button. In the case where only a label is shown, the response will be sent immediately after the label has been displayed, or after the specified amount of time has passed after being displayed.

Keep in mind that the user interface will not automatically disappear or change after a response has been sent. It will remain displayed until either a new user interface is shown or the stream is closed.

While the user interface is active, the customer will not be able to send messages in the chat with the operator. The chat will be reactivated when the user interface stream is closed.

Below is an example of using the UI to display a "Hello, World!" message to the operator.

from openobd import *

# Create an OpenOBD instance, which allows for managing openOBD sessions
openobd = OpenOBD()

# Start an openOBD session on a ticket by passing the ticket ID as a string
openobd_session = openobd.start_session_on_ticket(TICKET_ID)

# Start the SessionTokenHandler to ensure the openOBD session remains authenticated
SessionTokenHandler(openobd_session)

# Create a UiHandler instance to control the UI visible for the operator
ui_handler = UiHandler(openobd_session, target=InterfaceType.INTERFACE_OPERATOR)

# Displays a label to the operator for 3 seconds
ui_handler.show_ui(Label(label="Hello, World!", minimal_display_time=3))

# Close the UI
ui_handler.stop_stream()

# Close the session with a successful result
result = ServiceResult(result=[Result.RESULT_SUCCESS])
openobd_session.finish(result)

The UI needs to be closed to re-enable the chat. This can be done by closing the UI stream.

Subsequent Control messages will only be shown after the user has interacted with the previous Control message. It is also possible to override what is currently being shown by starting a new stream and sending a message containing the same InterfaceType. This will cancel the previous stream and immediately display the new message. See the user interface examples for more info.

Control types

There are six control types available to facilitate interaction with the user and operator, and allow them to control the flow of the procedure. Each control type expects a label, which is a string that will be displayed along with any other functionality offered by the control type. Some control types require input from the user. In this case, the returned control type will have an answer field containing the input.

Below is an overview of each control type, what functionality it offers, and what value the answer field holds, if applicable.

Control type Functionality Answer
Label Shows a label without any user interaction.
Continue Shows a Continue button under the label.
FreeText Shows a text field and a Send button. Text must be entered before continuing. Entered text (string)
YesNo Allows the user to press either Yes or No. Choice made by the user (bool)
Options For each given string, shows a button displaying the string. Index of the selected option (uint32)
Numbers Shows a button for each number in the given range. Value of the selected number (uint32)

The default buttons shown for each control type are automatically translated when viewed in one of the following languages: cs-CZ, da-DK, de-DE, en-GB, es-ES, fi-FI, fr-FR, it-IT, nl-NL, nb-NO, pl-PL, pt-PT, sv-SE. Other languages will default to English. For translations of user-defined labels, please see the translations section.

Label

The Label control type can be used to display a string. A Label does not provide any interaction. It will return a response the moment it is displayed, or after displaying it for the amount of time specified by minimal_display_time.

# Displays a welcome message for 4 seconds before continuing
ui_handler.show_ui(Label(label="Welcome to the start of the procedure.",
                         minimal_display_time=4))
Operator's view
Operator's view
Customer's view
Customer's view

Continue

The Continue control type displays a string along with a Continue button. The response will be returned when the Continue button is pressed. This can be applied in situations where an action should be taken before proceeding with the procedure.

# Show an instruction and wait until the Continue button is pressed
ui_handler.show_ui(Continue(label="Turn the ignition on and press continue."))
Operator's view
Operator's view
Customer's view
Customer's view

FreeText

The FreeText control type displays a string along with a text entry field and Send button. Text will have to be entered before the Send button can be pressed. When pressed, the response will be returned, containing the entered text.

# Display a text entry field and wait until text is entered and sent
pin = ui_handler.show_ui(FreeText(label="Please enter the PIN of the vehicle."))
# Print the string that has been entered
print("Entered pin: " + pin)
Operator's view
Operator's view
Customer's view
Customer's view

YesNo

The YesNo control type displays a string along with buttons labelled Yes and No. When either button is pressed, the response will be returned, containing a boolean indicating which button was pressed.

# Display a question and wait until either Yes or No is selected
try_again = ui_handler.show_ui(YesNo(label="Do you want to try again?"))
# Determine what to do based on the response
if try_again:
    print("We should try again.")
Operator's view
Operator's view
Customer's view
Customer's view

Options

The Options control type displays a string, as well as multiple buttons, each displaying a given string. The buttons are displayed in the same order as in which the strings were given. When one of the options is selected, the response will be returned. The response contains the index of the selected option (i.e. 0 for the first option).

# Define the options that should be presented
key_types = ["Keyless", "Transponder"]
# Display the given options and wait until one has been selected
option_index = ui_handler.show_ui(Options(label="Do you have keyless or transponder keys?",
                                          options=key_types))
# Print the selected option
print("Selected key type: " + key_types[option_index])
Operator's view
Operator's view
Customer's view
Customer's view

Numbers

The Numbers control type can be used to display a string along with a range of numbers as buttons. The range of numbers displayed includes the minimum and maximum value given. When a number is selected, the response is returned, containing the number that was selected.

# Display the numbers 1 through 5 and wait until a number has been selected
key_amount = ui_handler.show_ui(Numbers(label=f"How many keys do you want to program?",
                                        minimum=1, maximum=5))
# Print the number that has been selected
print(str(key_amount) + " keys need to be programmed.")
Operator's view
Operator's view
Customer's view
Customer's view

Translations

The user interface can be displayed in different languages. In the openOBD script, you can provide translations for the labels in several languages.

A language can be provided either a

  • two-letter ISO 639-1 language code (e.g. en or nl)
  • or a locale code, consisting of a two-letter ISO 639-1 language code and a two-letter ISO 3166-1 country code (e.g. 'en-GB' or 'nl-NL')

The system will choose the translation with the most specific code. For example, if the customer has chosen en-GB as language, the system will search for a translation for en-GB. If that translation does not exist, a translation for en will be used. If the customer has selected a language for which no translation is given (e.g. French in the example below), the original label is used.

If you don't provide any translations, the original label is used, regardless of the chosen language.

# Define the options that should be presented
options = ["Car", "Truck"]

# Define the translations for all labels used in the control
label_translations = LabelTranslations(
    label="Do you want to configure a car or a truck?",
    translations=[
        Translation(language="nl", label="Wilt u een personenwagen of een truck configureren?"),
        Translation(language="de", label="Möchten Sie einen PKW oder LKW konfigurieren?")
    ]
)

car_translations = LabelTranslations(
    label="Car",
    translations=[
        Translation(language="nl", label="Personenwagen"),
        Translation(language="de", label="PKW"),
    ]
)

truck_translations = LabelTranslations(
    label="Truck",
    translations=[
        Translation(language="nl", label="Truck"),
        Translation(language="de", label="LKW"),
    ]
)

# Display the given options and wait until one has been selected
option_index = ui_handler.show_ui(Options(label="Do you want to configure a car or a truck?",
                                          options=options), translations=[label_translations, car_translations, truck_translations])
# Print the selected option
print("Selected type: " + options[option_index])

Images

An image can be shown on top of each of the controls. It will remain visible as long as the control is visible.

Supported images types include all types that are supported in the browser of the customer. Common image types are jpg, gif, png and svg. For security reasons, the image must be available via https (i.e. the url must start with https://).

# Show an instruction with an image and wait until the Continue button is pressed
ui_handler.show_ui(
    Continue(label="Turn the ignition on and press continue."), 
    image=Image(url="https://placehold.co/600x400")
)