<ui_settings>
    <version>2.8</version>
    <model_locked>False</model_locked>
    <canvas_bg_color>#ffffff</canvas_bg_color>
    <initialization_code><![CDATA[# NOTE: Variables and functions defined here will be
# available for use in all Macro and Expression scripts.
# NOTE: This code is always executed prior to simulation start.

# The variable 'SETTINGS_DIR' holds the directory where the loaded Panel .cus file is located.
# Also you can call the 'get_settings_dir_path()' function in any
# Macro and Expression script to get the same directory.
SETTINGS_DIR = get_settings_dir_path()

# The 'add_to_python_path(folder)' function can be used to add a custom folder
# with Python files and packages to the PYTHONPATH. After a folder is added, all Python
# files and Python packages from it can be imported into the SCADA Namespace.

# HIL API is imported as 'hil'
# SCADA API is imported as 'panel'
# SCADA API constants are imported as 'api_const'
# Numpy module is imported as 'np'
# Scipy module is imported as 'sp'
# Schematic Editor model namespace is imported as 'scm'
# Function for printing to the HIL SCADA Message log is imported as 'printf'.

]]></initialization_code>
    <components>
        <component_data>
                <id>533ffd334afd11ee9eb8e0d55ed46d81</id>
                <name><![CDATA[Macro]]></name>
                <type>Macro</type>
                <description><![CDATA[]]></description>
                <on_click_code active="True"><![CDATA[from can.interfaces.vector import VectorBus
from udsoncan.connections import *
import isotp
from udsoncan.client import Client
import cantools
from udsoncan import DataIdentifier, IOValues
from udsoncan.configs import default_client_config
import os.path, os
    
# Refer to isotp documentation for full details about parameters
isotp_params = {
    'stmin': 32,
    # Will request the sender to wait 32ms between consecutive frame. 0-127ms or 100-900ns with values from 0xF1-0xF9
    'blocksize': 8,  # Request the sender to send 8 consecutives frames before sending a new flow control message
    'wftmax': 0,  # Number of wait frame allowed before triggering an error
    'tx_data_length': 8,  # Link layer (CAN layer) works with 8 byte payload (CAN 2.0)
    'tx_data_min_length': None,
    # Minimum length of CAN messages. When different from None, messages are padded to meet this length. Works with CAN 2.0 and CAN FD.
    'tx_padding': 0,  # Will pad all transmitted CAN messages with byte 0x00.
    'rx_flowcontrol_timeout': 1000,  # Triggers a timeout if a flow control is awaited for more than 1000 milliseconds
    'rx_consecutive_frame_timeout': 1000,
    # Triggers a timeout if a consecutive frame is awaited for more than 1000 milliseconds
    'squash_stmin_requirement': False,
    # When sending, respect the stmin requirement of the receiver. If set to True, go as fast as possible.
    'max_frame_size': 4095  # Limit the size of receive frame.
}

sys.path.append("d:/path/to/python/file")
from uds_script import UDSclass, create_config_dict

uds_example_path = r"d:/path/to/.cdd/file"
module_path = "d:/path/to/.cus/file/thcc" 

database_uds_example = cantools.db.load_file(uds_example_path)
old_work_dir = os.getcwd()

bus = VectorBus(channel=0, bitrate=500000, app_name="UDSsim")                        # Link Layer (CAN protocol)
tp_addr = isotp.Address(isotp.AddressingMode.Normal_11bits, txid=0x700, rxid=0x600)  # Network layer addressing scheme
stack = isotp.CanStack(bus=bus, address=tp_addr, params=isotp_params)                # Network/Transport layer (IsoTP protocol)
conn = PythonIsoTpConnection(stack)                                                  # interface between Application and Transport layer

config = dict(default_client_config)
config = create_config_dict(database=database_uds_example, config=config)

try:
    os.chdir(module_path)

    with Client(conn=conn, request_timeout=3, config=config) as client:  # Application layer (UDS protocol)
        uds = UDSclass(client=client)
        client.tester_present()

        # Read and write data example for did = "Windows"
        uds.read_data(client=client, database=database_uds_example, did_ident=0x81)

        uds.write_data(client, database_uds_example, name="Windows", value=(0x04, 0x03, 0x02, 0x01))

        uds.read_data(client, database_uds_example, did_ident=0x81)

        uds.io_control_write(client, database_uds_example, name="Windows", values=(0x08, 0x07, 0x06, 0x05))

        client.close()
finally:
    os.chdir(old_work_dir)]]></on_click_code>
                <on_start_code active="True"><![CDATA[# NOTE: The code specified in this handler will be executed on simulation start.
# NOTE: Variables specified here will be available in other handlers.
# HIL API is imported as 'hil'
# SCADA API is imported as 'panel'
# SCADA API constants are imported as 'api_const'
# 'WIDGET_HANDLE' constant holds the WidgetHandle object of this widget.
# This object can be used as an argument in SCADA API functions.

]]></on_start_code>
                <on_timer_code active="True"><![CDATA[# NOTE: The code specified in this handler will be executed on timer event.
# HIL API is imported as 'hil'
# SCADA API is imported as 'panel'
# SCADA API constants are imported as 'api_const'
# 'WIDGET_HANDLE' constant holds the WidgetHandle object of this widget.
# This object can be used as an argument in SCADA API functions.

]]></on_timer_code>
                <run_each>250</run_each>
                <on_stop_code active="True"><![CDATA[# NOTE: The code specified in this handler will be executed after simulation is stopped.
# HIL API is imported as 'hil'
# SCADA API is imported as 'panel'
# SCADA API constants are imported as 'api_const'
# 'WIDGET_HANDLE' constant holds the WidgetHandle object of this widget.
# This object can be used as an argument in SCADA API functions.

]]></on_stop_code>
                <widget_settings>
                    <x>424</x>
                    <y>192</y>
                    <width>128</width>
                    <height>40</height>
                    <appearance><![CDATA[Flat]]></appearance>
                    <hierarchy_position><![CDATA[1]]></hierarchy_position>
                    <is_background><![CDATA[False]]></is_background>
                    <label><![CDATA[]]></label>
                    <use_label>False</use_label>
                </widget_settings>
            </component_data>
        </components>
</ui_settings>