jpdias / iot-mesh-experiments

πŸ“‘ Experiments with mesh networks and ESP-things.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Internet-of-Things Mesh Network Experiments

Context

This project is being developed under the supervision of a summer internship @Software Engineering Laboratory @FEUP.

The goal of this project is to connect 3 or 4 ESP8266 relying on communication through end-to-end MQTT queues. These ESP8266 are to collect different types of data through their sensores and to act, (through their relayed actuactors), upon that same data.

This project is meant to be iterative and incremental.

On a higher level this venture is meant to help reduce energy consuption through the use of radio communication on such devices. Power harvesting on Potatoes will be also considered. A browser based of the mesh network shall be available as well.

Tasks/Ideas

  • Set up a Mesh network foundation
  • Integrate the Mesh Network with MQTT
  • Explore the use of power harvesting
  • Create a network web visualization
  • Do small experiments with sensors/actuators

Tings used in this project

Hardware

Hardware Quantity
NodeMCU ESP8266 6

Story

Background


What is a Mesh Network?

A mesh network is a network topology in which each node relays data for the network. All mesh nodes cooperate in the distribution of data in the network. It can be applied to both wired and wireless networks.

Wireless mesh networks can be considered a type of Wireless ad hoc network. Thus, wireless mesh networks are closely related to mobile ad hoc networks (MANETs). Although MANETs are not restricted to a specific mesh network topology, Wireless ad hoc networks or MANETs can take any form of network topology.

Borrowed from Wikipedia

Mesh Networks vs IoT

Mesh networking is emerging as an attractive option for a wide range of low-power, low-data-rate IoT applications.

The key concept behind Internet of Things (IoT) meshing is to enable connected things -- such as lights and thermostats that contain embedded sensor technologies -- to communicate without relying on PCs or dedicated hub services. This makes it much simpler to build a network of connected things and is, as a bonus, relatively inexpensive.

While IoT is mainly discussed in terms of home and building automation, mesh networks are ideal for supporting not only these but also other IoT low-power and low-data-rate applications such as industrial automation, monitoring medical supplies and other things inside hospitals, and even agriculture or oil and gas operations in some of the world's most remote locations.

Borrowed from IoT Agenda

Approaches


Approach #1: ESP8266MQTTMesh

Library: https://github.com/PhracturedBlue/ESP8266MQTTMesh

Description:

Self-assembling mesh network built around the MQTT protocol for the ESP8266 with OTA support

Overview

Provide a library that can build a mesh network between ESP8266 devices that will allow all nodes to communicate with an MQTT broker. At least one node must be able to see a wiFi router, and there must me a host on the WiFi network running the MQTT broker. The broker is responsible for retaining information about individual nodes (via retained messages) Each node will expose a hidden AP which can be connected to from any other node on the network. Note: hiding the AP does not provide any additional security, but does minimize the clutter of other WiFi clients in the area.

Additionally the library provides an OTA mechanism using the MQTT pathway which can update any/all nodes on the mesh.

This code was developed primarily for teh Sonoff line of relays, but should work with any ESP8266 board with sufficient flash memory

OTA

While all nodes must run the same version of the ESP8622MQTTMesh library, each node may run a unique firmware with independent purposes. The main purpose behind this library was to provide a backbone on which several home-automation sensors could be built. As such each node may need different code to achieve its purpose. Because firmwares are large, and memory is limited on the ESP8266 platform, there is only a single memory area to hold the incoming firmware. To ensure that a given firmware is only consumed by the proper nodes, The firmware defines a unique identifier that distinguishes itself from other code. A given firmware is broadcast from the MQTT broker to all nodes, but only nodes with a matching ID will update.

Borrowed from PhracturedBlue/ESP8266MQTTMesh

Result: It didn't work Long story short, we managed to softbrick a Wemos D1 Mini twice. Granted. We only tested this on one device, but we decided to abandon the idea anyway, because we can't affort to lose 2 to 3 hours unbricking the percentage of devices that we manage to screw up.


Approach #2:painlessMesh

Library: https://gitlab.com/BlackEdder/painlessMesh

Description:

painlessMesh is a library that takes care of the particulars of creating a simple mesh network using Arduino and esp8266. The goal is to allow the programmer to work with a mesh network without having to worry about how the network is structured or managed.

True ad-hoc networking

painlessMesh is a true ad-hoc network, meaning that no-planning, central controller, or router is required. Any system of 1 or more nodes will self-organize into fully functional mesh. The maximum size of the mesh is limited (we think) by the amount of memory in the heap that can be allocated to the sub-connections buffer… and so should be really quite high.

JSON based

painlessMesh uses JSON objects for all its messaging. There are a couple of reasons for this. First, it makes the code and the messages human readable and painless to understand and second, it makes it painless to integrate painlessMesh with javascript front-ends, web applications, and other apps. Some performance is lost, but I haven’t been running into performance issues yet. Converting to binary messaging would be fairly straight forward if someone wants to contribute.

Wifi & Networking

painlessMesh is designed to be used with Arduino, but it does not use the Arduino WiFi libraries, as I was running into performance issues (primarily latency) with them. Rather the networking is all done using the native esp8266 SDK libraries, which are available through the Arduino IDE. Hopefully though, which networking libraries are used won’t matter to most users much as you can just include the .h, run the init() and then work the library through the API.

painlessMesh is not IP networking

painlessMesh does not create a TCP/IP network of nodes. Rather each of the nodes is uniquely identified by its 32bit chipId which is retrieved from the esp8266 using the system_get_chip_id() call in the SDK. Every esp8266 will have a unique number. Messages can either be broadcast to all of the nodes on the mesh, or sent specifically to an individual node which is identified by its nodeId.

Borrowed from BlackEdder/painlessMesh

Result: It worked Worked like a charm. Plug and Play. The only downside to this library is that implementing MQTT over it is going to require a ton of code. However we can easily extract how the network is stuctured, so we can visualize the network and the messages going through it.


Diagrams

Overall Diagram

File structure

β”œβ”€β”€ Mesh-Node
β”‚   β”œβ”€β”€ lib
β”‚   β”‚   β”œβ”€β”€ 
β”‚   β”œβ”€β”€ src
β”‚   β”‚   β”œβ”€β”€ main.ino
β”‚   β”œβ”€β”€ .gitignore
β”‚   β”œβ”€β”€ .travis.yml
β”‚   └── platformio.ini
β”œβ”€β”€ Network-Viz
β”‚   β”œβ”€β”€ css
β”‚   β”‚   β”œβ”€β”€ **.css
β”‚   β”œβ”€β”€ js
β”‚   β”‚   β”œβ”€β”€ **.js
β”‚   β”œβ”€β”€ .eslintrc.json
β”‚   β”œβ”€β”€ .gitignore
β”‚   β”œβ”€β”€ index.html
β”‚   └── package.json
β”œβ”€β”€ Serial-to-ELK
β”‚   β”œβ”€β”€ .eslintrc.json
β”‚   β”œβ”€β”€ .gitignore
β”‚   β”œβ”€β”€ index.js
β”‚   └── package.json
β”œβ”€β”€ Docker-ELK
β”‚   β”œβ”€β”€ elasticsearch
β”‚   β”‚   β”œβ”€β”€ config
β”‚   β”‚   β”‚   └── elasticsearch.yml
|   |   Dockerfile
β”‚   β”œβ”€β”€ extensions
β”‚   β”‚   β”œβ”€β”€ 
β”‚   β”œβ”€β”€ kibana
β”‚   β”‚   β”œβ”€β”€ config
β”‚   β”‚   β”‚   └── kibana.yml
|   |   Dockerfile
β”‚   β”œβ”€β”€ logstash
β”‚   β”‚   β”œβ”€β”€ config
β”‚   β”‚   β”‚   └── logstash.yml
|   |   Dockerfile
β”‚   β”œβ”€β”€ .gitignore
β”‚   β”œβ”€β”€ README.md
β”‚   └── docker-compose.yml
β”œβ”€β”€ README.md
└── LICENSE

Modules

Docker-ELK

Runs the latest version of the ELK (Elasticsearch, Logstash, Kibana) stack with Docker and Docker Compose.

It gives you the ability to analyze any data set by using the searching/aggregation capabilities of Elasticsearch and the visualization power of Kibana.

It has 3 containers being those:

Elastic Search:

Elasticsearch is a search engine based on Lucene. It provides a distributed, multitenant-capable full-text search engine with an HTTP web interface and schema-free JSON documents.

It is developed alongside a data-collection and log-parsing engine called Logstash, and an analytics and visualization platform called Kibana. The three products are designed for use as an integrated solution, referred to as the "Elastic Stack" (Formerly the "ELK stack").

Borrowed from Wikipedia

Kibana:

Kibana is an open source data visualization plugin for Elasticsearch. It provides visualization capabilities on top of the content indexed on an Elasticsearch cluster. Users can create bar, line and scatter plots, or pie charts and maps on top of large volumes of data.

Borrowed from Wikipedia

Logstash:

Logstash is a tool to collect, process, and forward events and log messages. Collection is accomplished via configurable input plugins including raw socket/packet communication, file tailing, and several message bus clients. Once an input plugin has collected data it can be processed by any number of filters which modify and annotate the event data. Finally logstash routes events to output plugins which can forward the events to a variety of external programs including Elasticsearch, local files and several message bus implementations.

Borrowed from Wikitech

Mesh Node

Since we used the painless mesh library we did a proof of concept in top of it in oirder to se how the mesh would be created and how it would change during its life spawn (life cicle). In order to do so we used json output strings through the serial port.
The possibility of embodying messages that would trigger the built-in led with the goal of demonstrating the mesh network's proper behavior.

Serial-to-Elk:

This module is written in nodejs and uses the following dependencies:

  • serialport: Node-Serialport provides a stream interface for the low-level serial port code necessary to control Arduino chipsets and others.
  • yargs: Yargs be a node.js library fer hearties tryin' ter parse optstrings.

Taking the output logs from one of the mesh work's nodes we parsed such data and sent it to elastic search

Sample network configuration log entry

{
  "nodes": [
    {
      "id": 2786275551
    },
    {
      "id": 2785081432
    },
    {
      "id": 2785176007
    },
    {
      "id": 2786205540
    }
  ],
  "edges": [
    {
      "id": "2786275551-2785081432",
      "weight": 1,
      "source": 2786275551,
      "target": 2785081432
    },
    {
      "id": "2785081432-2785176007",
      "weight": 1,
      "source": 2785081432,
      "target": 2785176007
    },
    {
      "id": "2785176007-2786205540",
      "weight": 1,
      "source": 2785176007,
      "target": 2786205540
    }
  ]
}

Sample message log entry

"_source": {
    "message": {
      "msgtype": 1,
      "self": 2786275551,
      "body": {
        "from": 2785176007,
        "msg": "Hello from node 2785176007"
      }
    },
    "date": "2017-08-22T16:27:12.403Z"
  }

Netowrk Viz: The data the mesh networks provides is asked to the Elastic Search database through pooling (since ElasticSearch does not provide the use of websockets out-of-the-box) using the axius library: Promise based HTTP client for the browser and node.js For the visulaization cytoscape is used: Graph theory (a.k.a. network) library for analysis and visualisation

Set up

1. Docker-elk:

Start the ELK stack using docker-compose:

$ docker-compose up

You can also choose to run it in background (detached mode):

$ docker-compose up -d

Give Kibana about 2 minutes to initialize, then access the Kibana web UI by hitting http://localhost:5601 with a web browser.

By default, the stack exposes the following ports:

  • 5000: Logstash TCP input.
  • 9200: Elasticsearch HTTP
  • 9300: Elasticsearch TCP transport
  • 5601: Kibana

2. Mesh node:

To be able to properly run this repository you must install platformio and run:

$ platformio run --target upload <

If you use Visual Studio Code with the platformio plug in then you just need to click send.

If you need wish to see what's being written on the serial port then run:

$ platformio device monitor <

If you use Visual Studio Code with the platformio plug in then you just need to click on the serial monitor.

3.Serial-to-Elk:

Requirements:

  • Install nodejs
  • Run: $ npm install

Run:

$  node .\index.js --port [str] --baud [num] --server [str]
  • Example:
$  node .\index.js --port COM3

This script sends the information from the serial port to ElasticSearch.

4.Netowrk Viz:

Requirements:

  • Install nodejs
  • Run: $ npm install

Run:

$  npm run start

This module starts an HTTP server and opens a browser window with a mesh network graphical real time representation.


Side-notes

Authors

About

πŸ“‘ Experiments with mesh networks and ESP-things.

License:MIT License


Languages

Language:JavaScript 51.0%Language:C++ 31.9%Language:Dockerfile 6.8%Language:HTML 3.8%Language:Shell 3.6%Language:Go 1.9%Language:CSS 1.0%