The Hive Monitoring project (Part 2)

IOT Apr 30, 2020

Hey! In my last post I tried to describe my hardware setup. This contains the sensors that I used, which device and how it is wired together. Now it will be interesting, because we get it to run so that I get sensor data from it.

The IDE I use

Yes for my wemos it is right to use the Arduino IDE. But I like VSCode as IDE, so I try to find out a way to develop code for the arduino device with vscode.

And there I got one PlatformIO (opens new window).

This IDE contains the following features:

  • Debugger
  • Intellisense
  • Multi projects workflow
  • Build-In Terminal with custom Platform IO CLI
  • Build-In Serial Port Monitor

And the special one

  • IT integrated in Several IDE's also in vscode

Nice I have ma ideal IDE figured out, now let's get it on to install it.

Install platform IO in VSCODE

There is a handy documentation for the installation (opens new window)on the PlatformIO site.

I repeat the complex installation here 😉

  1. Open VSCode
  2. Search for the PlatformIO IDE (opens new window)extension
  3. Install Platform IO IDE extension

Image from Platform IO

Pew... that was stressful. 😉

Configuring the IDE

Before we can start to develop the code that will be placed on the Wemos board. We must setup the IDE to tell it that it must produce a binary especially for this board.

First of All create a new directory and open vscode

For now we have a emty directory and it is now time to create the Platform IO Project. This will contains the information about the used platform (our Wemos D1 Mini). There exists a wizard in PIO that will help us. Create a new project from the PIO homepage after this you will promoted to enter the used device and framework. We search then Wemos d1 mini and use arduino as framework.

The communication Infrastructure

Before we can start I must tell you that in the communication between host and IOT device will always (or the most time) by done by a message bus system. So I use Mosquitto as mqtt- server for this. This is a light server that can be easily configured, and support the actual mqtt protocol standards.

The Framework that I use

So one word about the framework that I use and why. So I didn't want to reinvent the wheel, then I looked about a toolset for my requirements. This tool must support the following requirements:

  • Deep Sleep
  • MQTT Communication (standardized)
  • Over the air update (Firmware / configuration)
  • Nice energy management support

So i will make it short. In the end I came to the Homie-esp8266 (opens new window)Framework. This has a huge support of all this requirements.

Let's go ... with the basics

Now after the project was create we can go and type some code to run it on our device. the source will come into the src folder. I created a file called node-wifi-mqtt-homie.cpp in it.

Why this name? This has an historical reason. Because before the PIo era I programmed it within the Ardunio-IDE. so the file name was reserved 😉.

In this file i got to main methods:


void setup(){

}

and

void loop(){

}

In the setup() there are the initialize methods in it. Be care full, the reset watchdog is very angry if there will be code executed that takes longer as 500 ms. So keep it reduced to the minimized set of methods.

In the loop() function comes the main code. That usually will be executed. Like measuring the temperatures and so on.

Let's go... with the requirements

So I owning some devices, so I must add some third party libaries to this project.

This is how it is done:

After the installation, it will be located in the libary folder. When you did this the first time you will notice that there will be create a MAKEFILE that contains the reference to the added libary.

So now you know how to add a libary, then you must add the following to the project:

Libary NamePurpose
HX711This is the required module for the Weight cell A/D converter
DallasTemperatureThis will be the preferred libary for the use of the Temperature sensor.
RunningMedianThis is a helper tool that compute a median value for the given metrics of the weight cell.

So now the libaries a assigned, now we must tell pio, what to build...

Because you cannot run a WeMos build on a small PyCom module. Because this has a different set of machine command. So there must be defined the target in PIO. For this exists the file platformio.ini in the root folder of the project.

For example, my file has the following content:

; Build darget
[env:esp12e]
; Platform to build
platform = espressif8266
; the device that will be used
board = d1_mini
; using the arduino system code
framework = arduino
; Adding Buildflags to indicate the low_memory use
build_flags = -D PIO_FRAMEWORK_ARDUINO_LWIP2_LOW_MEMORY
; Adding dependency to Homie, and ArduinoJson with the version 5.13.4 (BEcause the newer one contains some bugs actually)
lib_deps = Homie 
            ArduinoJson@5.13.4
; set the speed of the serial monitor
monitor_speed = 115200
; set the compat mode to strict
lib_compat_mode = strict

done?... so now...

Let's go... coding 🎉

Now after the basics now be clear (or not? write me in the comments below...) I can go to my code. But first some Todo's... what must the code do?

  • Configuration must be read from the config file
  • Measure the temperature
  • Measure the Weight
  • Sending the Data to the MQTT Server
  • Going into the powersave mode (DeepSleep)

pew.. so start with the first bullet point.

Set the configuration

The configuration mus be set from the config file. I knew that Homie has a support for configuration (opens new window)(luckily with json). I created in the root folder a subfolder homie. In this there will be create the config.json with my configuration:

{
    "wifi": {
        "ssid": "Ponyhof",
        "password": "XXXXXXXXXXXXX"
    },
    "mqtt": {
        "host": "192.168.178.201",
        "port": 1886,
        "auth": true,
        "username": "sascha",
        "password": "XXXXXXXXXXXXX"
    },
    "name": "dev-device",
    "ota": {
        "enabled": true
    },
    "device_id": "dev-device",
    "settings": {
        "sleepTime": 3600,
        "sendInterval": 3600,  
        "weightOffset": 244017,
        "kilogramDivider": 22.27
    }
}

for further explanation I will direct you to the complete guide (opens new window)of Homie 😉.

Interesting will be the Area settings This holds the settings that I will use in my program.

The Code itself

So instead to create the code line by line. There exists a github Repo (opens new window)for this... ehm... yes project 😃. This contains the complete sourcecode to measure the temperature, the weight and the battery state. Thanks to Homie ESP, it is easy to setup the transport to the mqtt Server.

So instead to go though every line I will comment some party of it.

Just clone the repo and bring it on your device. With the wiring of the provious post it will work fine.

Deep Sleep

The Deep Sleep function is the one, that is a must have function. Otherwise the battery will be empty in a short time. So there exists the normal call to the deep sleep (see the homie Spec for calling deep Sleep). Also there is a deep sleep called when the runtime of the code takes too long. Then it will go automatically go to sleep and send the data in the next interval.

  void max_run()
  {
    ++runtime_s;
    if (runtime_s == RUNTIME_MAX)
    {
      Homie.getLogger() << "DEBUG: Max. runtime of " << RUNTIME_MAX << "s reached, shutting down!" << endl;
      SLEEP_TIME = sleepTimeSetting.get();
      Homie.getLogger() << "✔ Preparing for " << SLEEP_TIME << " seconds sleep" << endl;
      Homie.prepareToSleep();
    }
  }

Sending to MQTT

The data will not be send by a method called from me. Instead it will be called when I am finished with the work. So this will help me to not implement any error handling or retry patterns. It's very simple.

But we must define what to send. Especially I must declare the Nodes to send.


  HomieNode weightNode("weight", "weight");
  HomieNode temperatureNode0("temperature0", "temperature");
  HomieNode temperatureNode1("temperature1", "temperature");
  HomieNode batteryNode("battery", "volt");
  HomieNode batAlarmNode("battery", "alarm");
  HomieNode jsonNode("data", "__json__"); 

With this configuration the Homie know on with topic the data will be set. In the MQTT Server it then look like this:

MQTT Topics

So How do we set data to this nodes? It's very simple. Here I will send the measurement from the temperature sensor to the first temperature node.

 temperatureNode1.setProperty("degrees").setRetained(false).send(String(temperature1));

Working with the data

So when the data is on the servicebus, we must work with it. Because the servicebus is only a service layer for me not a database. For me it was enought to forward the data to the hiveeyes project (opens new window). This portal is an open source portal and deliver (for private use only) a portal to send the messages to. So there is mine too.

The data will be there stored in a influx Database. This is a special database especially for timeseries. So perfect for this scenario.

As frontend there is Grafana. This will visualize the data from the Influx DB perfectly.

Here is an example

You can decide if you want to send it to the open Data pool, or you can host your own infrastructure (This will be described in my next post).

Conclusion

So with this post I want to show you how I create with minimal effort a huge benfit in measuring the weight, temperature and also the battery level.

The main part will be the visual presentation in Grafana like this weight level against the amount of precipitation

Dashboard

Or the Batterylevel:

Battery level

Please leave me a comment below, any suggestions are welcome ! 😃

Tags