User interface
This page lists some examples on how the user interface can be used. For more extensive background information on implementing these examples in a different programming language, please see the reference documentation on the user interface.
Basic user interface example
Below is a basic example implementing the user interface. In this example, the user interface has been set up for a mock key programming procedure. It demonstrates several use cases for the different UI control types.
python -m openobd run --file academy/user_interface/customer_interface.py --ticket <TICKET_NR>
from openobd import *
class CustomerInterfaceExample(OpenOBDFunction):
def run(self):
# Create a UiHandler object and use it to show a welcome message
ui_handler = UiHandler(self.openobd_session)
ui_handler.show_ui(Label(label="Welcome to the start of the procedure!", minimal_display_time=4))
# Ensure the ignition is on before proceeding
if not ui_handler.show_ui(YesNo(label="Is the ignition on?")):
ui_handler.show_ui(Continue(label="Please turn the ignition on and press continue."))
# Ensure that the correct PIN of the vehicle is entered
while True:
pin = ui_handler.show_ui(FreeText(label="Please enter the PIN of the vehicle."))
if ui_handler.show_ui(YesNo(label=f"You entered: {pin}. Is this correct?")):
break
# Ask what type of keys should be programmed
key_types = ["Keyless", "Transponder"]
key_type_index = ui_handler.show_ui(Options(label="Do you want to program keyless or transponder keys?", options=key_types))
# Ask how many keys should be programmed, and display the key currently being programmed
key_amount = ui_handler.show_ui(Numbers(label=f"How many keys do you want to program?", minimum=1, maximum=5))
for i in range(key_amount):
ui_handler.show_ui(Label(label=f"{key_types[key_type_index]} key {i + 1} is currently being programmed...", minimal_display_time=3))
ui_handler.show_ui(Label(label=f"Successfully programmed key {i + 1}!", minimal_display_time=2))
# Show a final message and close the UI so that the chat becomes available to the customer again
ui_handler.show_ui(Label(label="Procedure finished!", minimal_display_time=3))
ui_handler.stop_stream()
# Close the session with a successful result
self.result = ServiceResult(result=[Result.RESULT_SUCCESS])
Displaying the operator interface
Besides being able to show the user interface to the customer, it is also possible to show a UI to the operator. Both of these UIs can be shown at the same time and can be updated independently. Below is an example demonstrating this.
InterfaceType.INTERFACE_OPERATOR not available - we are working on it
The option to show an operator interface is unfortunately not available for all partner dashboards! We are working on it and have this issue on our roadmap.
python -m openobd run --file academy/user_interface/operator_interface.py --ticket <TICKET_NR>
from openobd import *
class OperatorInterfaceExample(OpenOBDFunction):
def run(self):
# Create a UiHandler object for the customer/user (which is the default)
customer_ui = UiHandler(self.openobd_session)
# Create a second UiHandler object, explicitly stating that it should be shown to the operator
operator_ui = UiHandler(self.openobd_session, target=InterfaceType.INTERFACE_OPERATOR)
# Inform the operator that the customer is entering a PIN
operator_ui.show_ui(Label(label="The customer is currently entering a PIN."))
while True:
# Wait for the customer to enter a PIN
pin = customer_ui.show_ui(FreeText(label="Please enter the PIN of the vehicle."))
# Tell the customer to wait while asking the operator to check the PIN
customer_ui.show_ui(Label(label="Please wait while the operator checks if the PIN is correct."))
if operator_ui.show_ui(YesNo(label=f"The customer entered the PIN 'f{pin}'. Is this correct?")):
# Inform both the customer and operator that the procedure is finished
operator_ui.show_ui(Label(label="The procedure is finished."))
customer_ui.show_ui(Label(label="Your PIN is correct. The procedure is finished.", minimal_display_time=3))
break
else:
# Inform both the operator and customer that the customer needs to enter a PIN again
operator_ui.show_ui(Label(label="The customer is entering a PIN again."))
customer_ui.show_ui(Label(label="The operator has indicated that the entered PIN is incorrect. Please try again.", minimal_display_time=5))
# Close both UIs
customer_ui.stop_stream()
operator_ui.stop_stream()
# Close the session with a successful result
self.result = ServiceResult(result=[Result.RESULT_SUCCESS])
Overriding the UI
Whenever a Control message is displayed in the UI, the user must interact with it before the next message will be displayed. In case it is desired to not wait for user interaction, it is possible to immediately replace the message shown. This can be done by creating a new Control stream with the same InterfaceType as the target. This will cancel the initial Control stream and display the message sent on the new stream. Below is an example in which the user can press a button to cancel a simulated procedure. The button will be replaced if the user does not press the button before the procedure finishes.
python -m openobd run --file academy/user_interface/customer_ui_override.py --ticket <TICKET_NR>
from threading import Thread, Event
from openobd import *
import time
class CustomerUIOverrideExample(OpenOBDFunction):
ui_handler = None # type: UiHandler
procedure_cancelled = None # type: Event
def run(self):
# Create a UiHandler instance and let the user start the procedure
self.ui_handler = UiHandler(self.openobd_session)
self.ui_handler.show_ui(Continue(label="Press `Continue` to start the procedure."))
# Keep track of whether the procedure has been cancelled
self.procedure_cancelled = Event()
# Start a thread that simulates a procedure
procedure_thread = Thread(target=self.procedure)
procedure_thread.start()
try:
# Give the user the option to cancel the procedure
self.ui_handler.show_ui(Options(label="The procedure has started. Please wait.", options=["Cancel procedure"]))
# The user pressed "Cancel procedure", so set a flag that the procedure is cancelled
self.procedure_cancelled.set()
self.ui_handler.show_ui(Label(label="Procedure cancelled.", minimal_display_time=3))
except OpenOBDStreamStoppedException:
# The stream has closed because the procedure thread took over the UI using force_display
pass
# Wait for the procedure thread to finish
procedure_thread.join()
# Close the UI
self.ui_handler.stop_stream()
# Close the session with a result depending on if it was cancelled
self.result = ServiceResult(result=[Result.RESULT_FAILURE if self.procedure_cancelled.is_set() else Result.RESULT_SUCCESS])
def procedure(self):
# Simulate a procedure by waiting 5 seconds, checking each second if it was cancelled
for i in range(5):
time.sleep(1)
if self.procedure_cancelled.is_set():
return
# Show a label to the user. Use force_display to replace the UI in the main thread that is waiting for user interaction
self.ui_handler.show_ui(Label(label="The procedure was successful.", minimal_display_time=4), force_display=True)