Skip to main content

Echelon Behavior Server

The Echelon Python behavior server is the simplest way to get behaviors working on your asset.

Setup

Clone the echelon-behavior-py repo onto the companion computer of the asset you'd like to control to get started

git clone https://github.com/mavrikinc/echelon-behavior-py

Then, in the root, install the requirements and compile the protobufs

cd echelon-behavior-py
pip install -r requirements.txt
python3 src/compile_protos

How to use

The simplest way to use behaviors is via serial, this means you can configure the behavior panel to send different serial commands to ports that you've preconfigured to use. Each UI element is independent, ie clicking one button won't change the behavior of another, however, this behavior can be achieved using other techniques.

In order to do that, you will first need to confiture which port(s) you'd like to use in src/behaviors/serial_configs/. Create a .json file with whatever name (snake_cake_recommended) and configure the serial ports you'd like to use, an example format can be found in basic.json.

{
"serial_ports": [
{
"port": "/dev/ttyUSB0",
"baudrate": 57600
},
{
"port": "/dev/ttyACM0",
"baudrate": 115200
}
]
}

Then, run the code to enable the behavior server

python3 src/run_behavior_server.py -m serial_write -s basic

This uses the basic.json serial config and loads the serial_write module (which provides serial writing functionality), later you will see how to create your own modules to achieve more complicated behaviors.

info

Depending on your serial port configuration, you may need to run the script with sudo privileges

sudo -E python3 src/run_behavior_server.py -m <modules> -s <serial config>

Custom functions

You can use your own functions within a module to implement your own fully custom behaviors. Take a look at the example module for the basic syntax and working example.

It is recommended when creating a module that will work with Echelon behaviors to put it in the src/behaviors/ folder. Ie like

src/
├── behaviors/
│ ├── my_module/
│ │ ├── __init__.py
│ │ ├── my_behavior.py
│ │ └── ....py # Additional files for my_module
│ ├── example/
│ │ ├── __init__.py
│ │ └── example_behaviors.py
│ └── serial_configs/
│ ├── basic.json
│ └── ... # Additional serial config files
└── echelon/
└── ...

Your __init__.py file will need to have the following contents to enable automatic function registration via the CLI

# __init__.py in your custom behavior module
from echelon.behavior_registry import auto_register_module

# Call this within __init__.py to enable the registry to find all of your decorated functions.
auto_register_module(__name__)

In order to register a function you have to use the register_behavior decorator which takes an optional registration name that will trigger its callback in Echelon UIm, if no callback value is specified, the name of the function is used, this value should be unique.

from echelon.behavior_registry import register_behavior

@register_behavior()
def function_to_perform_behavior(something: string):
pass

@register_behavior("custom_callback")
def function_to_perform_behavior(something: string):
pass

If you want to have functions with more arguments, the last argument will be determined by the value and the first arguments will be determined by the callback. Essentially, this is equivalent to partial function application. For example, given this function

@register_behavior()
def multi_arg_test(arg1: str, arg2: str, value: int):
pass

and this json within Echelon UIm

"action": {
"callback": "multi_arg_test(value_for_arg1, value_for_arg2)",
"type": "int",
"value": 5
}

The function will be called as

multi_arg_test(arg1="value_for_arg1", arg2="value_for_arg2", value=5):

The first n-1 args are passed as strings, the last is passed as the specified type.

Debugging

Assuming you correctly followed the instructions (nani?!?!), the first step is probably to check the logs, this is available at log.log (you can change this or the logging behavior in the run_behavior_server.py file).

cat log.log

Usually this will provide some error message you can Google or AI. If you're in the ol' it runs but don't work situation, I'd suggest double checking that the network works correctly, making sure that the example demo works is a good way to check that. Make sure you have the right IP address and check the UIm for any errors.