Home

Awesome

Magistrala IoT Agent

badge ci release go report card license chat

<p align="center"> <img width="30%" height="30%" src="./docs/img/agent.png"> </p>

Magistrala IoT Agent is a communication, execution and SW management agent for Magistrala system.

Install

Get the code:

go get github.com/absmach/agent
cd $GOPATH/github.com/absmach/agent

Make:

make

Usage

Get Nats server and start it, by default it starts on port 4222

go install github.com/nats-io/nats-server/v2@latest
nats-server

Create gateway configuration with Provision service or through Mainflux UI.

Start Agent with:

MG_AGENT_BOOTSTRAP_ID=<bootstrap_id> \
MG_AGENT_BOOTSTRAP_KEY=<bootstrap_key> \
MG_AGENT_BOOTSTRAP_URL=http://localhost:9013/things/bootstrap \
build/magistrala-agent

or,if Magistrala UI is used,

MG_AGENT_BOOTSTRAP_ID=<bootstrap_id> \
MG_AGENT_BOOTSTRAP_KEY=<bootstrap_key> \
MG_AGENT_BOOTSTRAP_URL=http://localhost:9013/bootstrap/things/bootstrap \
build/magistrala-agent

Config

Agent configuration is kept in config.toml if not otherwise specified with env var.

Example configuration:

[Agent]

  [Agent.channels]
    control = ""
    data = ""

  [Agent.edgex]
    url = "http://localhost:48090/api/v1/"

  [Agent.log]
    level = "info"

  [Agent.mqtt]
    ca_path = "ca.crt"
    cert_path = "thing.crt"
    mtls = false
    password = ""
    priv_key_path = "thin.key"
    qos = 0
    retain = false
    skip_tls_ver = false
    url = "localhost:1883"
    username = ""

  [Agent.server]
    broker_url = "localhost:4222"
    port = "9999"

Environment:

VariableDescriptionDefault
MG_AGENT_CONFIG_FILELocation of configuration fileconfig.toml
MG_AGENT_LOG_LEVELLog levelinfo
MG_AGENT_EDGEX_URLEdgex base urlhttp://localhost:48090/api/v1/
MG_AGENT_MQTT_URLMQTT broker urllocalhost:1883
MG_AGENT_HTTP_PORTAgent http port9999
MG_AGENT_BOOTSTRAP_URLMagistrala bootstrap urlhttp://localhost:9013/things/bootstrap
MG_AGENT_BOOTSTRAP_IDMagistrala bootstrap id
MG_AGENT_BOOTSTRAP_KEYMagistrala bootstrap key
MG_AGENT_BOOTSTRAP_RETRIESNumber of retries for bootstrap procedure5
MG_AGENT_BOOTSTRAP_SKIP_TLSSkip TLS verification for bootstraptrue
MG_AGENT_BOOTSTRAP_RETRY_DELAY_SECONDSNumber of seconds between retries10
MG_AGENT_CONTROL_CHANNELChannel for sending controls, commands
MG_AGENT_DATA_CHANNELChannel for data sending
MG_AGENT_ENCRYPTIONEncryptionfalse
MG_AGENT_BROKER_URLBroker urlnats://localhost:4222
MG_AGENT_MQTT_USERNAMEMQTT username, Magistrala thing id
MG_AGENT_MQTT_PASSWORDMQTT password, Magistrala thing key
MG_AGENT_MQTT_SKIP_TLSSkip TLS verification for MQTTtrue
MG_AGENT_MQTT_MTLSUse MTLS for MQTTfalse
MG_AGENT_MQTT_CALocation for CA certificate for MTLSca.crt
MG_AGENT_MQTT_QOSQoS0
MG_AGENT_MQTT_RETAINMQTT retainfalse
MG_AGENT_MQTT_CLIENT_CERTLocation of client certificate for MTLSthing.cert
MG_AGENT_MQTT_CLIENT_PKLocation of client certificate key for MTLSthing.key
MG_AGENT_HEARTBEAT_INTERVALInterval in which heartbeat from service is expected30s
MG_AGENT_TERMINAL_SESSION_TIMEOUTTimeout for terminal session30s

Here thing is a Magistrala thing, and control channel from channels is used with req and res subtopic (i.e. app needs to PUB/SUB on /channels/<control_channel_id>/messages/req and /channels/<control_channel_id>/messages/res).

Sending commands to other services

You can send commands to other services that are subscribed on the same Broker as Agent.
Commands are being sent via MQTT to topic:

when messages is received Agent forwards them to Broker on subject:

Payload is up to the application and service itself.

Example of on command can be:

mosquitto_pub -u <thing_id> -P <thing_key> -t channels/<control_channel_id>/messages/services/adc -h <mqtt_host> -p 1883  -m  "[{\"bn\":\"1:\", \"n\":\"read\", \"vs\":\"temperature\"}]"

Heartbeat service

Services running on the same host can publish to heartbeat.<service-name>.<service-type> a heartbeat message.
Agent will keep a record on those service and update their live status. If heartbeat is not received in 10 sec it marks it offline. Upon next heartbeat service will be marked online again.

To test heartbeat run:

go run -tags <broker_name> ./examples/publish/main.go -s <broker_url> heartbeat.<service-name>.<service-type> "";

Broker names include: nats and rabbitmq.

To check services that are currently registered to agent you can:

curl -s -S X GET http://localhost:9999/services
[
  {
    "name": "duster",
    "last_seen": "2020-04-28T18:06:56.158130519+02:00",
    "status": "offline",
    "type": "test",
    "terminal": 0
  },
  {
    "name": "scrape",
    "last_seen": "2020-04-28T18:06:39.58849766+02:00",
    "status": "offline",
    "type": "test",
    "terminal": 0
  }
]

Or you can send a command via MQTT to Agent and receive response on MQTT topic like this:

In one terminal subscribe for result:

mosquitto_sub -u <thing_id> -P <thing_key> -t channels/<control_channel_id>/messages/req -h <mqtt_host> -p 1883

In another terminal publish request to view the list of services:

mosquitto_pub -u <thing_id> -P <thing_key> -t channels/<control_channel_id>/messages/req -h <mqtt_host> -p 1883  -m  '[{"bn":"1:", "n":"config", "vs":"view"}]'

Check the output in terminal where you subscribed for results. You should see something like:

[
  {
    "bn": "1",
    "n": "view",
    "t": 1588091188.8872917,
    "vs": "[{\"name\":\"duster\",\"last_seen\":\"2020-04-28T18:06:56.158130519+02:00\",\"status\":\"offline\",\"type\":\"test\",\"terminal\":0},{\"name\":\"scrape\",\"last_seen\":\"2020-04-28T18:06:39.58849766+02:00\",\"status\":\"offline\",\"type\":\"test\",\"terminal\":0}]"
  }
]

How to save config via agent

Agent can be used to send configuration file for the Export service from cloud to gateway via MQTT.
Here is the example command:

mosquitto_pub -u <thing_id> -P <thing_key> -t channels/<control_channel_id>/messages/req -h localhost -p 1883  -m  "[{\"bn\":\"1:\", \"n\":\"config\", \"vs\":\"<config_file_path>, <file_content_base64>\"}]"

Here is an example how to make payload for the command:

b,_ := toml.Marshal(export.Config)
payload := base64.StdEncoding.EncodeToString(b)

Example payload:

RmlsZSA9ICIuLi9jb25maWdzL2NvbmZpZy50b21sIgoKW2V4cF0KICBsb2dfbGV2ZWwgPSAiZGVidWciCiAgbmF0cyA9ICJuYXRzOi8vMTI3LjAuMC4xOjQyMjIiCiAgcG9ydCA9ICI4MTcwIgoKW21xdHRdCiAgY2FfcGF0aCA9ICJjYS5jcnQiCiAgY2VydF9wYXRoID0gInRoaW5nLmNydCIKICBjaGFubmVsID0gIiIKICBob3N0ID0gInRjcDovL2xvY2FsaG9zdDoxODgzIgogIG10bHMgPSBmYWxzZQogIHBhc3N3b3JkID0gImFjNmI1N2UwLTliNzAtNDVkNi05NGM4LWU2N2FjOTA4NjE2NSIKICBwcml2X2tleV9wYXRoID0gInRoaW5nLmtleSIKICBxb3MgPSAwCiAgcmV0YWluID0gZmFsc2UKICBza2lwX3Rsc192ZXIgPSBmYWxzZQogIHVzZXJuYW1lID0gIjRhNDM3ZjQ2LWRhN2ItNDQ2OS05NmI3LWJlNzU0YjVlOGQzNiIKCltbcm91dGVzXV0KICBtcXR0X3RvcGljID0gIjRjNjZhNzg1LTE5MDAtNDg0NC04Y2FhLTU2ZmI4Y2ZkNjFlYiIKICBuYXRzX3RvcGljID0gIioiCg==

License

Apache-2.0