Skip to content

Functions

It is possible to create a custom procedure and define it as an openOBD function. When this function is registered with the function broker, it can then be called from other openOBD sessions, or be started from the ticket dashboard. This page demonstrates how to make use of this feature.

Function hosting

In order to call an openOBD function, it will first need to be registered as online. Below is a simple example that demonstrates how to register a function and handle function calls. In this example, a new function ID and signature are generated and used to register a function. The code will then keep waiting for FunctionCall messages, representing requests to run the function. Once received, the session contained in the message will be activated and a procedure will be simulated. The session is then finished to return control to the caller, and the next FunctionCall is awaited.

from openobd import *
import time


try:
    openobd = OpenOBD()

    # Generate a new function ID and a signature that acts as proof that we are allowed to register that function ID
    function_id_signature_pair = openobd.generate_function_signature()
    function_id, function_signature = function_id_signature_pair.id, function_id_signature_pair.signature

    # Define some information about the function that will be registered
    function_details = FunctionDetails(id=function_id,
                                       version="1.0.1",
                                       name="Example procedure",
                                       description="Waits a few seconds to simulate a procedure.")

    # Define the message used to register the function, specifying that it is online and visible in the ticket dashboard
    function_registration = FunctionUpdate(type=FunctionUpdateType.FUNCTION_UPDATE_TYPE_REQUEST,
                                           function_registration=FunctionRegistration(
                                               details=function_details,
                                               state=FunctionRegistrationState.FUNCTION_REGISTRATION_STATE_ONLINE,
                                               signature=function_signature,
                                               visibility=FunctionVisibility.FUNCTION_VISIBILITY_DASHBOARD))

    # Open a function stream to the broker and send the FunctionUpdate message to register the function
    function_stream_handler = StreamHandler(openobd.open_function_stream)
    function_stream_handler.send(function_registration)
    # Check the response to make sure the function registration was successful
    registration_response = function_stream_handler.receive()   # type: FunctionUpdate
    if registration_response.response == FUNCTION_UPDATE_SUCCESS:
        print("Function successfully registered.")

        while True:
            try:
                # Keep listening to incoming messages on the stream
                response = function_stream_handler.receive()    # type: FunctionUpdate
                if (response.type == FunctionUpdateType.FUNCTION_UPDATE_TYPE_REQUEST and
                        response.function_broker_token.value):
                    # Received a new function broker token, which acts as a keep-alive message, so simply send it back
                    print("Received new token.")
                    response.type = FunctionUpdateType.FUNCTION_UPDATE_TYPE_RESPONSE
                    function_stream_handler.send(response)

                elif (response.type == FunctionUpdateType.FUNCTION_UPDATE_TYPE_REQUEST and
                      response.function_call is not None):
                    # Received a function call request, so get the session from the message and authenticate it
                    print("The function has been called!")
                    session = OpenOBDSession(response.function_call.session_info)
                    SessionTokenHandler(session)

                    # Return a response to indicate that the function has started
                    response.type = FunctionUpdateType.FUNCTION_UPDATE_TYPE_RESPONSE
                    response.response = FunctionUpdateResponse.FUNCTION_UPDATE_SUCCESS
                    function_stream_handler.send(response)

                    # Simulate the procedure by waiting for a few seconds
                    print("Executing procedure...")
                    time.sleep(5)

                    # Give control back to the caller by calling finish() on the session
                    print("Procedure finished!")
                    session.finish(ServiceResult(result=[Result.RESULT_SUCCESS]))

            except KeyboardInterrupt:
                print("Interrupted.")
                break

except Exception as e:
    print(f"Encountered exception: {e}")