137 lines
7.9 KiB
Markdown
137 lines
7.9 KiB
Markdown
|
---
|
||
|
title: "Do your sensors yourself"
|
||
|
date: 2020-08-17T18:00:00+02:00
|
||
|
---
|
||
|
|
||
|
A big question I've asked myself during this project is what is the best place to put my storage servers? There are
|
||
|
multiple environmental variables to watch out: **temperature**, **humidity** and **noise**. If components are too hot,
|
||
|
they could be damaged in the long run. Of course, water and electricity are not friends. You can add a fan to move air
|
||
|
out of the case and reduce both temperature and humidity but the computer will become noisy. We need to measure those
|
||
|
variables. Unfortunately, all systems have different set of built-in sensors but not all of them are exposed to the
|
||
|
operating system. So I decided to build my own sensors.
|
||
|
|
||
|
# Sensors hardware
|
||
|
|
||
|
I'm a newbie in electronics. I never weld anything. In the DIY[^1] world, there is a open-source micro-controller, the
|
||
|
[Arduino Uno](https://store.arduino.cc/arduino-uno-rev3), that costs only a few bucks (20€). There are cheaper
|
||
|
alternatives available like the Elegoo Uno (11€). To build sensors, you'll need good sensors like the
|
||
|
[DHT22](https://www.waveshare.com/wiki/DHT22_Temperature-Humidity_Sensor) for temperature and humidity and
|
||
|
[KY-037](https://electropeak.com/learn/how-to-use-ky-037-sound-detection-sensor-with-arduino/) for capturing sound. To
|
||
|
connect everything together, you'll need a [breadboard](https://en.wikipedia.org/wiki/Breadboard),
|
||
|
[resistors](https://en.wikipedia.org/wiki/Resistor) and cables.
|
||
|
|
||
|
Components:
|
||
|
- [Elegoo Uno R3](https://www.amazon.fr/dp/B01N91PVIS/ref=cm_sw_r_tw_dp_x_8NtkFbHZ6X6K9)
|
||
|
- [DHT22 sensor](https://www.amazon.fr/dp/B07TTJNY1C/ref=cm_sw_r_tw_dp_x_QOtkFbBM2ZAAD)
|
||
|
- [KY-037 sensor](https://www.amazon.fr/dp/B07ZHGX5T6/ref=cm_sw_r_tw_dp_x_kPtkFbXRRK7ZP)
|
||
|
- [10k Ω resistor](https://www.amazon.fr/dp/B06XKQLPFV/ref=cm_sw_r_tw_dp_x_EPtkFbB24855X)
|
||
|
- [breadboard](https://www.amazon.fr/dp/B06XKZWCJB/ref=cm_sw_r_tw_dp_x_.PtkFb01X4WNW)
|
||
|
- [cables](https://www.amazon.fr/dp/B01JD5WCG2/ref=cm_sw_r_tw_dp_x_QQtkFbRA6PSG0)
|
||
|
|
||
|
In electronics, you need to build closed circuits going from the power supply ("+") to the ground ("-"). The Arduino
|
||
|
card can be plugged on an USB port which provides power to the card, on the "5V" pin. The end of the circuit should
|
||
|
return to the "GND" pin, which means "ground". The breadboard can help you extending the circuit and plug more than one
|
||
|
element (resistors and sensors at the same time). The top and bottom parts are connected horizontally. The central part
|
||
|
connects elements vertically. Horizontal and vertical parts are isolated from each other. Resistors role is to regulate
|
||
|
electrical intensity. They act like a tap for distributing water. If there is too much water at a time, the glass can be
|
||
|
full too quickly and water can spit everywhere. We'll put a resistor in front of the DHT22 to have valid values and to
|
||
|
prevent damages.
|
||
|
|
||
|
The circuit looks like this:
|
||
|
|
||
|
{{< rawhtml >}}
|
||
|
<p style="text-align: center;"><img src="/sensors.svg" alt="Sensors circuit" style="width: 65%;"></p>
|
||
|
{{< /rawhtml >}}
|
||
|
|
||
|
The DHT22 sensor has three pins: **power**, **digital** and **ground** (and not four like in the schema). The KY-037
|
||
|
sensor has four pins: **analog**, **ground**, **power** and **digital** (and not three like in the schema). We'll use
|
||
|
the analog pin to gather data from the sound sensor.
|
||
|
|
||
|
# Sensors software
|
||
|
|
||
|
The circuit is plugged to a computer via USB and it's ready to be used. To be able to read values, we need to compile
|
||
|
low-level code and execute it on the board. For this purpose, you can install the [Arduino
|
||
|
IDE](https://www.arduino.cc/en/Main/Software) which is available on multiple platforms. My personal computer runs on
|
||
|
Ubuntu (no joke please) and I tried to use the packages from the repositories. However, they are too old to work. You
|
||
|
should [install the IDE yourself](https://www.arduino.cc/en/Guide/Linux). I've added my own user to the "dialout" group
|
||
|
to be able to use the serial interface to send compiled code to the board. The code itself is called a "sketch". You can
|
||
|
find mine [here](https://github.com/jouir/arduino-sensors-toolkit/blob/master/sensors2serial.ino). Click on "Upload",
|
||
|
job done.
|
||
|
|
||
|
# Multiplexing
|
||
|
|
||
|
Values are sent to the serial port but only one program can read this interface at a time. No luck, we would like to
|
||
|
send those metrics to the alerting and trending systems. Both have their own schedules. They will try to access this
|
||
|
interface at the same time. Moreover, programs that would like to read the serial port will have to wait for, at least,
|
||
|
four seconds. In the IoT[^2] world, we often see the usage of [MQTT](https://en.wikipedia.org/wiki/MQTT), a queuing
|
||
|
protocol. To solve the performance issue, I've developed a simple daemon that reads values from the serial interface and
|
||
|
publishes them to an MQTT broker called [serial2mqtt](https://github.com/jouir/arduino-sensors-toolkit/#serial2mqtt).
|
||
|
I've installed [Mosquitto](https://mosquitto.org/) on storage servers so the multiplexing happens locally.
|
||
|
|
||
|
# Thresholds
|
||
|
|
||
|
What is the **critical temperature**? I [found](https://www.apc.com/us/en/faqs/FA157464/) that UPS batteries should not
|
||
|
run in an environment where temperatures exceed 25°C (warning) and must not go over 40°C (critical). This summer, I had
|
||
|
multiple buzzer alerts on storage3 and the temperature was over 29°C every time.
|
||
|
|
||
|
What is the **critical humidity**? Humidity is the concentration of water in a volume of air. In tropical regions of the
|
||
|
world, we often see a 100% humidity level, with working computers. Humidity is proportional to the temperature. The
|
||
|
hotter it is, the more water can be contained in the air. Generally, temperature in a computer case is warmer than the
|
||
|
ambient temperature. What is dangerous is not the quantity of water in the air, it's when water condense. A good rule of
|
||
|
thumb is to avoid going over 80%. But 100% should not be a problem.
|
||
|
|
||
|
# Alerting
|
||
|
|
||
|
On Nagios, I use the [check-mqtt](https://github.com/jpmens/check-mqtt) script on the monitored storage host under an
|
||
|
NRPE command:
|
||
|
|
||
|
```
|
||
|
# Sensors
|
||
|
command[check_ambient_temperature]=/usr/local/bin/python3.7 /usr/local/libexec/nagios/check-mqtt.py -m 10 --readonly -t sensors/temperature -H localhost -P 1883 -u nagios -p ***** -w "float(payload) > 25.0" -c "float(payload) > 40.0"
|
||
|
command[check_ambient_humidity]=/usr/local/bin/python3.7 /usr/local/libexec/nagios/check-mqtt.py -m 10 --readonly -t sensors/humidity -H localhost -P 1883 -u nagios -p ***** -w "float(payload) > 80.0" -c "float(payload) > 95.0"
|
||
|
```
|
||
|
|
||
|
[![storage2](/sensors-storage2-alert.png)](/sensors-storage2-alert.png)
|
||
|
|
||
|
# Observability
|
||
|
|
||
|
Telegraf has a [mqtt_consumer](https://github.com/influxdata/telegraf/tree/master/plugins/inputs/mqtt_consumer) input
|
||
|
plugin:
|
||
|
|
||
|
```
|
||
|
[[inputs.mqtt_consumer]]
|
||
|
servers = ["tcp://localhost:1883"]
|
||
|
topics = [
|
||
|
"sensors/humidity",
|
||
|
"sensors/temperature",
|
||
|
"sensors/sound"
|
||
|
]
|
||
|
persistent_session = true
|
||
|
client_id = "telegraf"
|
||
|
data_format = "value"
|
||
|
data_type = "float"
|
||
|
username = "telegraf"
|
||
|
password = "*****"
|
||
|
```
|
||
|
|
||
|
Grafana is able to display environmental variables now:
|
||
|
|
||
|
[![storage1](/sensors-storage1.png)](/sensors-storage1.png)
|
||
|
[![storage2](/sensors-storage2.png)](/sensors-storage2.png)
|
||
|
[![storage3](/sensors-storage3.png)](/sensors-storage3.png)
|
||
|
|
||
|
# In the end
|
||
|
|
||
|
I tried to measure noise but I failed. The KY-037 sensor is designed to detect sound variations like a big noise for a
|
||
|
short period of time. When we try to measure the ambient noise level, it requires a lot of conversions to get values in
|
||
|
[decibel](https://en.wikipedia.org/wiki/Decibel). So I decided to ignore values coming from the sensor and to hear it
|
||
|
myself.
|
||
|
|
||
|
I can put my storage servers in the attic, in a room or in the cellar. The attic is right under the roof which is too
|
||
|
hot in the summer (over 40°C). Rooms are occupied during the night and noise is a problem. I am lucky to have a free
|
||
|
room right now but it's too hot during the summer (over 25°C). There is the cellar left, where all the conditions are
|
||
|
optimal, even humidity. Remote locations all have a cellar which is perfect!
|
||
|
|
||
|
[^1]: Do It Yourself
|
||
|
[^2]: Internet of Things
|