Flexible Driver Tutorial (Incoming Data)
This article explores the capabilities of the Flexible Driver and shows how to handle arbitrary incoming data from a TCP connection.
Iotellect includes drivers for many different devices, which simplifies integrating them into the system. In cases where there is no driver in Iotellect for a given device (for example, a device using a proprietary protocol), there are several options for integrating the device. The first option is to write a plugin for Iotellect in Java, and although this is straightforward, it can be labor-intensive. Another option is to configure one or more instances of the Flexible Driver to process incoming data as variables or events.
Introduction to Driver Operation
Throughout this tutorial, expressions read incoming bytes from the environment variable command, referenced as {env/command}. In an Iotellect using the Flexible Driver, configured to receive incoming data, this variable contains the data that was received and is being processed by the driver.
Configuring the Flexible Plugin
The first step is to configure the Flexible Driver plugin to correctly route incoming data to a specific Flexible Driver device. In the root context, open the Drivers/Plugins context, select Flexible, and choose Edit Driver/Plugin Properties.

From the Properties window, add a new row for every device which will be processing incoming data. Initially, add a single row with the values shown in the following table:
Property Name | Value | Notes |
|---|---|---|
Description |
| User-friendly name for the device configuration. |
Protocol |
| The data type which the Flexible driver device will be processing. |
Port |
| Indicates the port where Iotellect should listen to incoming |
Secure |
| Indicates whether the connection is encrypted with SSL/TLS. |
Input Stream Splitter Expression |
| Returns the byte count up to and including the first newline ( |
Input Stream Splitter Mode |
| Indicates when to trigger the Input Stream Splitter Expression. In this case, it will be triggered once, at the end of the message. If the option |
Encode Expression |
| Used when the driver is sending data. One usage example would be to calculate a checksum and append it before sending. In this example, we simply send the exact command. |
Decode Expression |
| Used when receiving a data packet. This expression pre-processes the data packet before further processing. This might be used to simply trim terminal characters from the packet or completely transform the data, e.g. by decrypting/decompressing it. |
Device ID Detection Method Expression |
| Expression that defines the method for calculating the ID, and which returns:
This example uses value 1, since we will be sending arbitrary data. |
Read Device ID Expression | Not used in this example. If the Device ID Detection Method Expression is The response to the device ID request command is then sent to the Device ID Processing Expression in order to determine the device ID. | |
Device ID Processing Expression |
| The result of this command determines the device ID. We set it to be If we were expecting different devices to be communicating on the same port, we could set this dynamically based on the incoming message, or the response to the Read Device ID Expression. As in previous examples, |
Encoding |
| There are several different encodings available. For this example, we use US-ASCII. |
The following screenshot shows a row of the Flexible Driver Global Settings configured according to the preceding table.

You have set the global configurations of the Flexible Driver plugin to accept TCP data on port 55040, decode the incoming data as US-ASCII text, and forward it to the Flexible Driver device with ID "1". The next section describes how to configure that device to process incoming messages.
Creating a Device
To create a Flexible device, click Add Device from the Devices context in the root context. Configure the device with the following parameters:
Property Name | Value | Notes |
|---|---|---|
Device Driver |
| This tutorial is for the Flexible driver. |
Device Name |
| This will be part of the context path for referencing the device in Iotellect. |
Device Description |
| User-friendly name for the device. |
Connection |
| Indicates that this device will be processing incoming connections. |
Device ID |
| This takes a string value, and must match the value indicated in Device ID Processing Expression during the previous step. |
The following screenshot shows the above configurations entered into the “Add Device” window. Click OK to save and open the Device Properties page.

Once the device has been created, the Device Properties window should open automatically. The window can also be opened by clicking Edit Device Properties from the context menu of the newly created device.
Adding a Variable to the Device
In order to associate incoming data with the device, create at least one variable. Navigate to the Static Variables tab and add a row with the following data:
Field Name | Value | Notes |
|---|---|---|
Name |
| This will be part of the context path for referencing the variable in Iotellect expression language. |
Description |
| User-friendly name for the variable. |
Format |
| Describes the fields of the variable’s Data Table. We describe a table with a single field named |
Readable |
| Allows reading the variable. |
Writable |
| Allows writing the variable. |
Configuring a row in the Static Variables tab results in the following:

The device now has a variable data, where incoming data can be written.
Configuring an Event for the Device
Another way of interacting with the device is to trigger specific events. Open the Static Events tab of the Device Properties, and add a row with the indicated data, leaving unmentioned fields blank:
Field Name | Value | Notes |
|---|---|---|
Name |
| This will be part of the context path for referencing the event in the Iotellect expression language. |
Description |
| User-friendly name for the event. |
Format |
| Describes the fields of the data table for the event. We describe a table with a single field named |
Level |
| Set the Event Level of the event to information. |
Configuring a static event with the above values results in the following:

The device will trigger events when certain data packets are received.
Configuring Operations Properties
The properties of the Operations tab determine how the device will respond to incoming data in the case of an incoming connection as well as how outgoing connections are processed. The following configurations are for devices which accept incoming connections.
Data Operations
Property Name | Value | Notes |
Asynchronous Command Detector Expression |
| This expression can access
|
Event/Variable Update Qualifier Expression | contains({env/command},"variable") ? 1 | Evaluated only if Asynchronous Command Detector Expression evaluates to
In this case, if the incoming command string contains the substring |
Command ID Expression |
| The Command ID Expression field and the Reply ID Expression field are used only if Asynchronous Command Detector Expression returns |
Reply ID Expression |
|
Asynchronous Variable Processing
Property Name | Value | Notes |
Variable Name Expression |
| Indicates the name of the variable which will be updated if the Event/Variable Update Qualifier Expression returns |
Variable Timestamp Expression |
| Timestamp to apply to the variable update. |
Variable Quality Expression |
| Data quality to apply to the variable update. |
Variable Value Expression |
| Data table with which to update the variable. Must match the format defined for the variable. |
Asynchronous Event Processing
Property Name | Value | Notes |
Event Name Expression |
| Indicates the name of the event which will be created if the Event/Variable Update Qualifier Expression returns |
Event Timestamp Expression |
| Timestamp to apply to the event update. |
Event Level Expression |
| The level at which the event will be created. |
Event Value Expression |
| Data table for the event. Must match the format defined for the event data table. |
The remaining sections can be left blank. Configure the properties of the Operations tab to match the example shown in the following screenshot:

Now that the Iotellect device is configured to process incoming messages with the Flexible Driver, it can be tested by sending some messages.
Sending Data to the Iotellect Device
There are a few ways to send arbitrary TCP data. One option is to use a specialized tool, such as Packet Sender. Another is to write a simple program which creates a TCP connection and sends the desired data.
Using Packet Sender to Send a Packet
Download and install packet sender on the same operating system where the Iotellect server is running.
Create a packet with the following configurations:
Property | Value | Description |
|---|---|---|
Name |
| If you want to save the packet for repeated usage |
ASCII |
| ASCII text to send. Press Enter at the end to send a newline character, |
HEX |
| Automatically encoded HEX value of the indicated ASCII text. |
Address |
| Host or IP address to send the packet to. |
Port |
| Port to send the packet to. |
Resend Delay |
| Delay before resending the packet. |
Communication Type |
| The connection type to establish with the server. |
The configured Packet Sender window will appear as follows.

Click Send to send the packet to the Iotellect Flexible Driver device.
Using Python to Send a Packet
Install Python 3 on the same machine running Iotellect server.
Save the following example script in a file called sendpacket.py:
import socket
# Set up the socket connection
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Hostname or IP address where server is running
host = 'localhost'
# Port where Flexible Driver is configured to listen to incoming data
port = 55040
# Start connection
s.connect((host, port))
# Send data
data = b'var: Update "data" variable with some arbitrary TCP data.\n'
s.sendall(data)
# Close the connection
s.close()Run the script from the command line with the command
python3 sendpacket.py.
Confirm the Packet was Received by the Flexible Driver Device
Open the context menu of the device from the root context, and click Manage Device.

This opens a window with all the device variables, in this case the variable data, with the data we sent as a packet:
var: Update "data" variable with some arbitrary TCP data.

Use the expression language to read the variable:
{users.admin.devices.flexible_incoming:data}
![]() | Use the device name you actually created earlier in the tutorial. If you named |
Triggering an Event in the Flexible Device
We can trigger the updateData event we configured above, rather than updating a variable, by simply changing the data being sent to the device.
Recall that the Event/Variable Update Qualifier Expression determines whether incoming data will be processed as an event or a variable update operation. We used the following expression:
contains({env/command},"variable") ? 1 : (contains({env/command},"event") ? 0 : 1)This expression first checks to see if the command contains the string “variable”. If so, it evaluates to 1 and the incoming message is interpreted as a variable update. If the command does not contain the string “variable”, it checks if the command contains the string “event”. If the command does contain the string “event”, the expression evaluates to 0, and the command is processed as an event. If neither “variable” nor “event” is present, it defaults to 1 and updates the variable.
To trigger an event, simply change the content of the test packet to contain the string “event” and remove the string “variable”. For example: event: This is an event!.
Using Packet Sender, update the ASCII and HEX data as indicated in the following table:
Property | Value | Description |
|---|---|---|
Name |
| If you want to save the packet for repeated usage. |
ASCII |
| ASCII text to send. Press Enter at the end to send a newline character, |
HEX |
| Automatically encoded HEX value of the indicated ASCII text. |
Address |
| Host or IP address to send the packet to. |
Port |
| Port to send the packet to. |
Resend Delay |
| Delay before resending the packet. |
Communication Type |
| The connection type to establish with the server. |
If using the Python script, update the data variable (which forms the payload sent to the device) as indicated in the following example:
...
# Send data
data = b'event: This is an event!\n'
...![]() |
|
In the Iotellect Context Tree, open the context menu of the Incoming Flexible device, and select Monitor Related Events.

A window appears, indicating all current events of the Incoming Flexible device. In our case, there are no active events, so the data table is empty.

Send the packet from Packet Sender, or run the Python script, and see that the event is fired:

Once you have created more events for the device, the Event Name Expression and Event Data Expression can be configured with more complex functions in order to trigger different events, based on the content of the command.
Was this page helpful?
