An emulator for WoT applications programmed on top of WoTPy that is based on Docker Swarm Mode
4.6K
An emulator for Python applications to help in the design of IoT deployments based on the edge computing model. It is focused on the Web of Things paradigm by offering extended support for applications programmed with WoTPy.
As an emulator, WoTemu demands significantly higher computation resources than simulators in the same domain, it is, however, able to run real code, which simplifies the design process and provides more meaningful insights into the target architecture.
The main output of an emulation experiment is an HTML report describing the observed behaviour of the stack. Please see a demo report here.
This project leverages Docker Swarm Mode to offer simple horizontal scaling across heterogeneous nodes; this enables the emulation of scenarios with hundreds of actors.
The following image shows a high-level view of a simple emulation stack. This serves to illustrate the main design choices behind WoTemu.

pip install wotemu)Such a recent version of the Docker Engine is required to ensure that
cap_addis supported in Swarm Mode.
Emulation experiments are represented by instances of wotemu.topology.models.Topology.
The recommended workflow to run an experiment is as follows:
Topology.Topology.Please note that the commands in this section should be executed in a Swarm manager.
There is a Vagrant configuration file (Vagrantfile) in this repository that may be used to quickly create a Swarm cluster consisting of three virtual machines (one manager and two workers) for development and test purposes. All dependencies for WoTemu are installed in the provision stage.
Run vagrant up in your host to create and provision the three guest machines. Please note that you must manually run the /vagrant/scripts/join-swarm.sh script once in both worker1 and worker2 to join the swarm.
Topologies can be defined in a Python file exposing a topology function that takes no arguments and returns an instance of Topology. The following is such an example:
from wotemu.enums import NetworkConditions
from wotemu.topology.models import (BuiltinApps, Network, Node, NodeApp,
NodeResources, Topology)
_SERVER_GIST = "https://gist.github.com/agmangas/94cc5c3d9d5dcb473cff774b3522bbb6/raw"
def topology():
network_3g = Network(
name="3g",
conditions=NetworkConditions.REGULAR_3G)
node_server = Node(
name="server",
app=NodeApp(path=_SERVER_GIST, http=True),
networks=[network_3g],
scale=1)
host_server = "{}.{}".format(
node_server.name,
network_3g.name)
app_reader = NodeApp(
path=BuiltinApps.READER,
params={
"servient_host": host_server,
"thing_id": "urn:wotemu:quickstart:thing"
})
node_reader = Node(
name="reader",
app=app_reader,
networks=[network_3g],
resources=NodeResources(mem_limit="150M"),
scale=4)
topology = Topology(nodes=[
node_server,
node_reader
])
return topology
There are two types of nodes here:
READER built-in application, which takes a WoTPy Servient index URL (servient_host) and Thing ID (thing_id) as arguments and periodically reads all properties exposed by the Thing; this particular instance of READER is connected to the server node. All replicas of reader are constrained to 150MB of memory.Both nodes are connected in a network that uses the REGULAR_3G network conditions. The four replicas of reader will periodically read both properties from the single replica of server on a channel that displays the typical latency and bandwidth of a 3G connection.
An application (i.e. the code run by a Node) is a Python file that exposes an asynchronous app function that takes at least three positional arguments:
| Variable | Type | Description |
|---|---|---|
wot | wotpy.wot.wot.WoT | WoTPy WoT entrypoint decorated and pre-configured by WoTemu. |
conf | wotemu.config.EnvConfig | Environment configuration that is currently active. |
loop | asyncio.AbstractEventLoop | Loop that is running the application. |
The path parameter of a NodeApp instance should point to an application. There are three distinct options when setting the value of path:
BuiltinApps.READER).Loading applications from the filesystem of a custom Docker image based on agmangas/wotemu is arguably the most versatile option. To that end, you may use the optional image parameter in the Node class (set to agmangas/wotemu:latest by default).
Please note that although WoTemu does not impose any restrictions on what is actually executed in the application function, your code should follow the asynchronous I/O programming model to avoid blocking the main thread (there are some WoTemu background processes running in the loop that is passed as argument).
A Compose file describing the emulation experiment can be created automatically from a topology file using the wotemu compose CLI command:
wotemu compose --path ./examples/quickstart.py
This stack may then be deployed to the Swarm cluster in the usual fashion:
docker stack deploy -c ./examples/quickstart.yml quickstart
Metrics such as network packets, interactions or system usage data points will be periodically collected while the stack is active. The emulation stack can be stopped when the user considers that enough time has passed to gather a significant amount of data for the experiment:
wotemu stop --compose-file ./examples/quickstart.yml --stack quickstart
It is necessary to stop the stack with
wotemu stopinstead ofdocker stack rmto capture a final snapshot of the stack state and keep the Redis store online.
An HTML report containing useful insights into the behaviour of the emulation stack can be then generated with the following command.
wotemu report --out /report/ --stack quickstart
Content type
Image
Digest
Size
840.9 MB
Last updated
over 5 years ago
docker pull agmangas/wotemu