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}")