Skip to content

Repository files navigation

MQTTHub with Go!

Description

This is a part of my Bachelor of Engineering Final Project. The main goal is gathering environmental variables generated by diferent sensors deployed on the field using IoT, specifically MQTT. The gathered data will be stored to be consulted by a Web App and analyzed in the future.

This program is the "hub" part of the project, therefore it receives the incoming data, process it, and inserts it into the database.

Index

  1. Run with Docker (Recommended)
  2. Run without Docker
  3. Understanding the App

1. Run With Docker

This is the easy way but it requires Docker! The repo provides a "docker compose" file with the name:

"example-docker-compose.yaml"

You can copy this file into the same directory as "docker-compose.yaml". Using Linux distros:

cp ./example-docker-compose.yaml ./docker-compose.yaml

This will automatically run the containerized app and its dependencies with testing environmental variables.

In order to fully understand the program and customize it you should read the "Understanding the App" section.

2. Run Without Docker

This is the hard way! You will need installed Go in your environment, also there should be a database (check testdb/db.sql) running somewhere (SQL Server is required, but tweaking the code you should be able to run with any SQL database), and a MQTT broker (I used Mosquitto). Once you have this requirements:

  • Get the dependencies listed in the "go.mod" file.

  • Set your OS environment with this variables:

    DB_SERVER: "your_database_URI"
    DB_USER: "your_database_user"
    DB_PASSWORD: "your_database_user_password"
    DB_PORT: "your_database_port"
    DB_NAME: "your_database_name"
    
    MQTT_PROTOCOL: "your_broker_protocol_under_MQTT"
    MQTT_SERVER: "your_broker_URI"
    MQTT_PORT: "your_broker_port"
    
    HUB_SETTINGS_PATH: "./internal/adapters/mqtt/hub-settings.json"
    
  • Run or build the go app with "go run cmd/main.go" or "go build cmd/main.go"

3. Understanding the App

The software is based on the Hexagonal Architecture, also known as "ports and adapters". This will allow the devs to separate and to "loosely couple" the domain logic in a "core" and the dependencies reliant code as a surrounding layer. Both will communicate to each other through ports and adapters.

More specifically, this app defines three concentric layers:

  • The core with the domain logic and the data models.
  • The application layer with the ports and the api which holds every use case of the app.
  • The adapters that interact with the external dependencies and the core logic through the ports defined in the inner layer.

This division will help the devs to write "cleaner" and more testable code.

All of the adapters should be instantiated in the "main.go" file, this should also be "injected" (D.I.) to the application ports.

Paho MQTT

The software uses a "Paho" client subscribed to all the sensor topics in order to gather environmental data. Some MQTT client configuration can be achieved by modifying the "hub-settings.json" file, but the broker URL and other sensitive information should be handled with environmental variables from the OS.

The whole project defines a topic tree that groups sensor topics in the sensor branch. For instance:

root/sensor/temperature/device_address

Each MQTT message should have a JSON payload. I.E:

{"value": 20.34, "unit": "Celcius"}

The domain logic takes this unfinished model and the device address to complete it. This allows the app to receive all kinds of sensor measurables within a single endpoint by subscribing to a wildcard "#" (check MQTT doc for more info).

GORM

The database comms are managed by an adapter with GORM with SQL Server, (I know maybe PostgreSQL would have been a better choice but the B.Eng project required an SQL Server DB). This adapter will handle the connection and the queries generated by each use case in the application layer.

An example of the DB can be found inside the "testdb" directory as a SQL script.

Note: Following GORM's approach, the db adapter receives data as references!

Docker

Containerizing the app allows the entire project to scale better (as a hub, this program may become a bottleneck), also, a developer will find easier to perform tests this way.

The Dockerfile will create an image from Alpine Linux with Go (chosen because of its low size), source files will be copied inside the "/app" directory and the compiled binary to the "/usr/local/bin/". A simple entrypoint script is added just for waiting the DB initialization before launching the app.

An example of a docker compose file is included in the repo, this file contains the configuration of the app and its dependencies (also included in the testdb and testmqtt directories).

About

Part of my "Bachelor of Engineering" project

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages