# README
vd (virtual device)
vd is a tool for simulating devices that communicate using stream-based protocols, enabling testing of communication layers and accelerated device integration.
For who?
- Control system engineers integrating devices that are:
- Inaccessible
- Access-restricted
- Poorly documented
- Potentially hazardous to send commands to
- Device suppliers aiming for seamless integration of their devices into client systems
- Security experts validating the integrity of IOC communication
- Anyone seeking to enhance the quality of their device integrations
Quick Start
- Install vd by downloading the appropriate binary for your operating system.
- Create a
vdfile
configuration file describing the device communication (see example below). - Launch vd with the path to your
vdfile
:$ vd <path to vdfile>
- Connect to the simulated device on port
:9999
using an IOC or telnet. - Interact with the device parameters via the HTTP API on port
:8080
.
How It Works
The vd
tool can simulate devices that communicate using stream-based communication, i.e., those that can be integrated using StreamDevice. Creating a simulator doesn't require programming; communication is described in a file called vdfile
.
vd
is able to lex and parse incoming messages from the client and, based on them, determine action.
vdfile
The configuration file called vdfile
is a TOML file and captures communication details.
Note that some parameters do not contain specific communication patterns. Your configuration can include one or multiple parameters depending on your needs.
It starts with optional error message:
mismatch = "error"
then, it contains information about terminators:
interm = "CR LF"
outterm = "CR LF"
and finally describes parameters available in the simulated device:
[[parameter]]
name = "current"
typ = "int64"
val = 300
[[command]]
name = "get_current"
req = "CUR?"
res = "CUR {%d:current}"
[[command]]
name = "set_current"
req = "CUR {%d:current}"
res = "OK"
dly = "1s"
[[parameter]]
name = "state"
typ = "string"
val = "on"
opt = "ON|OFF|ERROR"
[[command]]
name = "set_state"
req = "SET {%s:state}"
res = "OK"
Here's a breakdown of the configuration:
name
: Parameter's name, not used in client communication but utilized in the HTTP API.typ
: Parameter type (available values -int
,float
,string
,bool
).req
: Client's request to the sumylated device to get or set value.res
: The response the simulated device sends to the client for the request.dly
: Response delay with time unit.opt
: (Optional) Limits the range of values a parameter can take (see below for example of usage).
Below is a sample configuration:
mismatch = "Wrong query"
interm = "CR LF"
outterm = "CR LF"
[[parameter]]
name = "version"
typ = "string"
val = "version 1.0"
[[command]]
name = "get_version"
req = "ver?"
res = "{%s:version}"
dly = "10s"
[[parameter]]
name = "current"
typ = "int64"
val = 300
[[command]]
name = "get_current"
req = "CUR?"
res = "CUR {%d:current}"
[[command]]
name = "set_current"
req = "CUR {%d:current}"
res = "OK"
dly = "2s"
[[parameter]]
name = "temperature"
typ = "float64"
val = 36.6
[[command]]
name = "get_temp"
req = "TEMP?"
res = "{%.2f:temperature}"
[[command]]
name = "set_temp"
req = "TEMP {%.2f:temperature}"
res = "{%.2f:temperature}"
[[parameter]]
name = "mode"
typ = "string"
opt = "NORM|SING|BURS|DCYC"
val = "NORM"
[[command]]
name = "get_mode"
req = "MODE?"
res = "{%s:mode}"
[[command]]
name = "set_mode"
req = "MODE {%s:mode}"
res = "ok"
[[command]]
name = "get_status"
req = "status?"
res = "mode:{%s:mode},temp:{%2f:temperature}"
Parameter
parameter
is a place where parameter together with its name, type, possible values, and initial value are defined.
Command
command
is section that keeps information about accepted request strings and responses to them. The command can reference none, one or more parameters. One can assign command to the parameter using {
}
with proper placeholder and parameter name between brackets e.g. {%d:parameter}
.
Delays
The vd
tool enables the introduction of delays when sending responses to requests. This feature allows you to define custom wait times for the vd
to hold off on every response and acknowledgment, enhancing the simulation of real-world network conditions or server response times.
The delays are specific for single command, you can use dly
to define delay time for the given command.
Mismatch
vd
allows to specify mismatch that is sent back to the client when received string does not match any of the expected commands. It is send back to the client automatically without delay.
Triggering reply
The vd
tool enables the triggering of responses, simulating scenarios where a device sends data autonomously, without a specific request from the client. It is done by sending proper request via HTTP API.
Installation
vd
is supplied as a binary file. Download the appropriate version for your operating system and you are good to go.
Usage
After creating the configuration file, you can launch the program with:
$ vd <path to vdfile>
By default, the simulator is accessible on port :9999
. You can connect to this port using an IOC or via telnet.
The simulator also starts an HTTP server with an API that allows direct parameter value changes via HTTP. By default, it listens on port :8080
.
To fetch the current value of a parameter, e.g., temperature:
$ curl localhost:8080/temperature
To set a new value:
$ curl -X POST localhost:8080/temperature/36.6
To make our lifes easier, vd
comes with a built-in client.
To change the value of a parameter, e.g., temperature:
$ vd get temperature
$ vd set temperature 36.6
To change the value of command delay:
$ vd get delay get_status
$ vd set delay get_status 200ms
To change mismatch message string:
$ vd get mismatch
$ vd set mismatch "wrong message"
To trigger a response related to a parameter, e.g., temperature:
$ vd trigger temperature
If in doubt, check the help
$ vd -h