# Standard Edge Module Operations
In this tutorial, you will find information on how to accomplish basic tasks common to any edge module development.
Edge Module API
You can find general information about the Edge Module APIs here.
# Connecting to the EdgeBroker
The first thing any Edge module does is read the configuration & connect to the edgeBroker
. All the properties required for such connection are passed
as environment variables. Let's look at the output of the docker service inspect referenceModule
command to see a sample list of the passed variables on
an already running edge.
"Env": [
"module_id=referenceModule",
"mqtt_client_id=referenceModule",
"mqtt_url=mqtt://edge-broker:1883",
"mqtt_password_file=/run/secrets/referenceModule",
"topics_model_in=modules/referenceModule/model/desired",
"topics_model_out=modules/referenceModule/model/reported",
"topics_methods_in=modules/referenceModule/methods/req",
"topics_methods_out=modules/referenceModule/methods/res",
"topics_messages_in=modules/referenceModule/messages/devicebound",
"topics_messages_out=modules/referenceModule/messages/events",
"topics_local_in=modules/local/referenceModule",
"topics_local_out=modules/local",
"topics_files_in=modules/referenceModule/files/notifications",
"topics_files_out=modules/referenceModule/files/upload",
"topics_lwt=modules/referenceModule/lwt",
"object_id=208f12f0-e6ce-4d25-8728-dde6f2489cd1"
]
As we can see, there is a list of topics_*
, an mqtt_password_file
,
mqtt_client_id
, but what's the most important an mqtt_url
. What do we need
that for? Well, every edge module communicates with the "outer world" by sending
and receiving MQTT messages. It doesn't matter if it is about sending a
telemetry to the cloud or communicating with the other module. To send such a
message, we need to first connect to the so called MQTT broker. To do this we
need to know the URL of the broker (mqtt_url
), the login (mqtt_client_id
)
and the password (mqtt_password_file
). The first two we take directly from the
variables and the password is written in plain text in the file located in
mqtt_password_file
. Let's check how these parts look in the code.
# Reading the configuration
The main class of each sample module in the provided projects inherit from the ModuleBase class. This is where you should look for the things that might be common to all modules.
The Configuration
property definition in the ModuleBase class:
private IConfiguration _configuration;
protected IConfiguration Configuration
{
get
{
if (_configuration == null)
{
//this environment variable is defined in the microsoft/dotnet:2.1-runtime-deps-alpine3.7 base image
var envVariable = Environment.GetEnvironmentVariable("DOTNET_RUNNING_IN_CONTAINER");
var isDocker = (envVariable ?? string.Empty).Equals(bool.TrueString, StringComparison.InvariantCultureIgnoreCase);
Console.WriteLine($"Is module running as a Docker container: {isDocker}");
_configuration = isDocker ? new EdgeConfiguration() : (IConfiguration)new ManualConfiguration();
}
return _configuration;
}
}
The EdgeConfiguration
initializer:
public EdgeConfiguration()
{
ClientId = Env.GetEnvironmentVariable("mqtt_client_id");
ServerUri = new Uri(Env.GetEnvironmentVariable("mqtt_url"));
Username = Env.GetEnvironmentVariable("module_id");
Password = File.ReadAllText(
Env.GetEnvironmentVariable("mqtt_password_file"));
MethodsInTopic = Env.GetEnvironmentVariable("topics_methods_in");
MethodsOutTopic = Env.GetEnvironmentVariable("topics_methods_out");
MessagesOutTopic = Env.GetEnvironmentVariable("topics_messages_out");
ModelInTopic = Env.GetEnvironmentVariable("topics_model_in");
CleanSession = true;
ObjectId = Env.GetEnvironmentVariable("object_id");
LocalInTopic = Env.GetEnvironmentVariable("topics_local_in");
LocalOutTopic = Env.GetEnvironmentVariable("topics_local_out");
FilesOutTopic = Env.GetEnvironmentVariable("topics_files_out");
FilesInTopic = Env.GetEnvironmentVariable("topics_files_in");
}
# Connecting to the MQTT broker
Let's now see how we connect with the edgeBroker
. In our examples we are
using MQTTnet
client which is easily downloadable as a nugget package.
private async void StartMessagingClient()
{
_mqttClient = new MqttFactory().CreateManagedMqttClient();
//Build options for the MQTT client based off of config values
//If running as a Docker container on Ability Edge, the Edge runtime will supply these values to the container
var options = new ManagedMqttClientOptionsBuilder()
.WithClientOptions(
new MQTTnet.Client.MqttClientOptionsBuilder()
.WithClientId(this.Configuration.ClientId)
.WithTcpServer(
this.Configuration.ServerUri.Host,
this.Configuration.ServerUri.Port)
.WithCredentials(
this.Configuration.Username,
this.Configuration.Password)
.WithKeepAlivePeriod(
TimeSpan.FromMilliseconds(
DEFAULT_KEEP_ALIVE_PERIOD_MS))
.WithCleanSession(this.Configuration.CleanSession)
.Build())
.WithAutoReconnectDelay(
TimeSpan.FromMilliseconds(DEFAULT_AUTO_RECONNECT_DELAY_MS))
.Build();
_mqttClient.ApplicationMessageReceived += OnApplicationMessageReceived;
await _mqttClient.StartAsync(options);
Console.WriteLine($"MQTT client created and started.");
}
# Summary
To deploy an edge module, you have to accomplish two tasks:
- Publish an image containing your module to the docker images repository
- Configure and run edge software installation scripts on your machine
The first step in more details would look like this:
- Compile the project
- Publish the project to dll
- Build a docker image and set your dll as an entry point
- Publish a docker image to a repository
And the second one like this:
- Prepare a type definition for your edge module in both abb.ability.device & abb.ability.configuration models
- Upload the type definitions through the type definition registry
- Configure the edge.env file to point to your edge type definition
- Run installation scripts
If you configured everything correctly, the edge should be up and running after
few minutes. You can check the running services by executing docker service list
from CLI.