Sending temperature data from the TL-MR3020 router and Raspberry Pi to People’s Monitoring
Introduction
As a result of questions, I allow myself a short comment, clarifying the meaning of the article a little. The article describes two devices that are independent of each other and perform identical tasks of sending data to the site "People’s Monitoring"
When I first saw the article on the hub "People’s temperature monitoring (vs forecast) in different cities. Is it necessary? ” , Dedicated to monitoring the environmental parameters of narodmon.ru , I was somehow skeptical of such an undertaking and forgot about it. Before the new year, I had a Raspberry Pi, and for some time it took me to learn and review the possibilities , as a result, something would not stop the raspberry, and so on for the general development of the article"The history of the interaction of the" teapot "and the DS18B20 through the Raspberry Pi" did the same, but taking into account the source of the original source , which has already been amended based on the above article with reference to the Habr. The temperature was measured, the graphs were built, but somehow it became boring to watch it, and the use of raspberries for this purpose is like a cannon on sparrows, and one fine day I remembered “People’s Monitoring”, on which all the information displayed on the site it is displayed only on the basis of information about the current environmental parameters (temperature, humidity, atmospheric pressure, etc.) transmitted from client devices of users of this service. I started searching and found the article “The best implementation is the implementation of UART => 1-wire and I2C / SPI based on routers”. Then I got the idea to make such a device, though in the hope that someone had already done it, but I will only repeat it, since the TL-MR3020 router was already in the household, and inhuman experiments were being made on it to screw it to " scooter cart ”with a camera based on the article“ A simple wifi bot for monitoring rooms or “kitchen” robot building ” .
So let's get started
I started with experiments on the router, at that time it had OR-WRT 0.70 firmware based on OpenWRT . The temperature sensor is connected to the router via the USB-UART adapter. The connection diagram is extremely simple. Text and photo from the site http://cyber-place.ru You can
connect the sensor to UART using the figure below
Connect RX and TX together and connect the data line 1-Wire of the DS18B20
VCC sensor to VCC
GND to GND to them
When I tried to connect and read data through my native UART router, it turned out that I couldn’t do it right away. At one bourgeois forum, information was found that the limitation is hardware and it is imposed by the router port itself, which is sharpened by 8 bits of data, and only 6 are used in digitemp (a package for reading data from 1-wire sensors). It was decided - it would have to be set USB-COM adapter to FT232 or PL2303, another option is possible on CP2102, but I don’t have it, and therefore I will use what I have. After that, I decided to try my hand at writing a script to send the received data to “People’s Monitoring”. Data should be sent to this service using two methods, either telnet TCP / UDP (recommended) or HTTP POST. Examples of sending data to PHP are available on the site. PHP is a dark forest for me, but still it's better than nothing. After the first attempt to install PHP on the router, it became clear that the 4MB of memory available in it was not enough, and the focus would fail. Then I started thinking about increasing the amount of flash memory and came across the samecyber-place.ru on the topic "Replacing and restoring Flash ROM in the router MR3020 and WR703n". But after some thought, I came to the conclusion that this is not Feng Shui, for me and for most it is quite laborious, plus a programmer is required, which not everyone has, and scored on this matter. I decided to write the necessary script on bash, but advice with Google did not bring any result, and a couple of days passed in vain. As a result, it was decided to put a USB-HUB (I saw on the network successful experiments on implanting them in the inside of the router), and connect an external drive and a USB-UART bridge to it. It is said - done, but in the future, after the successful completion of experiments with Raspberry Pi and PHP, and at that moment I just spread to these experiments. Fast forward to the future, the conceived experiments on raspberries and PCPs are successfully completed, as I will write below, we will continue experiments with the router. To increase the amount of memory, its transfer to an external flash drive is used, and this means that the router that I was configured to work with the "scooter cart" will be finally and irrevocably transferred to use with additional memory, which I categorically did not want to do. The next day, another 1 router and the smallest USB-HUB were purchased, since it was a pity to lose the results, especially since these should still be different devices.
For the "thermometer" I decided to use pure OpenWRT. Having downloaded it when I tried to install in the file name selection field by first letter search, I found that I had as many as 3 firmware with the same size and file name, only the file upload sequence number was different. I decided that I had once downloaded this firmware and selected one of three for guessing. After the firmware, I did not succeed in any initial actions from the OpenWRT manual. I already thought that something went wrong during the firmware and began to study methods for extracting a router from a brick via TFTP. All evening I put this on, the benefit of the hands did not reach practice, in theory there was a lot of incomprehensible. And at the end of the evening, something jerked me to try to perform the initial settings as for OR-WRT 0.70. I was lucky, it turned out that I flooded it. Then, when comparing the names of the downloaded files, it turned out that both OpenWRT and OR-WRT have the same name. Next, I spent an nth amount of time trying to expand the memory to an external flash drive, after which it was decided to upload another firmwareOR-WRT 0.75 alpha with existing flash drive support. I flashed and configured my router according to the instructions without any problems and proceeded to further actions.
Using the thumb in /etc/opkg.conf, I changed the repository address to downloads.openwrt.org/snapshots/trunk/ar71xx/packages , updated the list of packages,
opkg update
installed digitemp-a packages.
opkg install digitemp-usb
opkg install digitemp
After that, I
dmesg
found out where the FTDI adapter is connected, I got ttyUSB0. We search for 1-wire devices, digitemp_DS9097 -i -s /dev/ttyUSB0
if any, then read the temperature and write to the file
digitemp_DS9097 -a -A -l /tmp/1wire_log
to see the result, we enter.
cat /tmp/1wire_log
Everything works. Next, install the packages for PHP
opkg install php5
opkg install php5-cgi
And we begin to write scripts. In this case I’m not an expert, so I ask you not to kick much for the curvature of the code and the huge crutches set up to make it work. Two scripts were written, one in bash, the other in php. Rather, the one that was made on php based on the source from the site "People's Monitoring". The first script fishes out the data received from the digitemp package and recorded in the 1wire_log file, and drives it into a digestible form. Then it transfers control to the second script in php to send data to the server.
First script get_send.sh
#! / bin / bash
rm / temperatureura / 1wire_log
rm / temperatureura / temp
rm / temperatureura / temper
cd /
digitemp_DS9097 -i -s / dev / ttyUSB0
sleep 1s
digitemp_DS9097 -a -A -l / temperatureura / 1wire_log
sleep 2s
cd / temperatureura
cut -c29-33 1wire_log | sed 's / $ //'> temp
cat temp | tr -d '\ n'> temper
php-cgi /temperatura/send.php
echo "OK \ n"
rm / temperatureura / 1wire_log
rm / temperatureura / temp
rm / temperatureura / temper
cd /
digitemp_DS9097 -i -s / dev / ttyUSB0
sleep 1s
digitemp_DS9097 -a -A -l / temperatureura / 1wire_log
sleep 2s
cd / temperatureura
cut -c29-33 1wire_log | sed 's / $ //'> temp
cat temp | tr -d '\ n'> temper
php-cgi /temperatura/send.php
echo "OK \ n"
The second script takes data from the file prepared by the first script and sends it to the server.
Second send.php script
$ file_name = "/ temperatura / temper";
$ file = fopen ("$ file_name", "r");
$ gradus_out = fread ($ file, filesize ($ file_name));
echo "$ gradus_out \ n";
fclose ($ file);
$ fp = @fsockopen ("tcp: //narodmon.ru", NNNN, $ errno, $ errstr);
# where NNNN is the port number available after registration
if (! $ fp) exit ("ERROR (". $ errno. "):". $ errstr);
fwrite ($ fp, "# 01-23-45-67-89-AF \ n # 0123456789ABCDEF # $ gradus_out \ n ##");
fclose ($ fp);
echo "OK \ n";
?>
$ file = fopen ("$ file_name", "r");
$ gradus_out = fread ($ file, filesize ($ file_name));
echo "$ gradus_out \ n";
fclose ($ file);
$ fp = @fsockopen ("tcp: //narodmon.ru", NNNN, $ errno, $ errstr);
# where NNNN is the port number available after registration
if (! $ fp) exit ("ERROR (". $ errno. "):". $ errstr);
fwrite ($ fp, "# 01-23-45-67-89-AF \ n # 0123456789ABCDEF # $ gradus_out \ n ##");
fclose ($ fp);
echo "OK \ n";
?>
where 01-23-45-67-89-AF is the mac address of the wlan network card (Wi-Fi), and 0123456789ABCDEF is the serial number of the DS16 (x) 20 temperature sensor.
For both implementations of the device, I used the wlan mac address to bind the device on the site "People’s Monitoring". To find this address, you can enter a command
ifconfig
. Next, we need to automate the receipt and sending of data to the server using cron. At the time of debugging the scripts, I sent data to the server with a frequency of 5 minutes, but as soon as they were debugged, the period increased to 10 minutes. To do this, create a simple crontab for the root user with the contents
Crontab for root
SHELL = / bin / sh
PATH = / usr / local / sbin: / usr / local / bin: / sbin: / bin: / usr / sbin: / usr / bin
0,10,20,30,40,50 * * * * sh /temperatura/get_send.sh
PATH = / usr / local / sbin: / usr / local / bin: / sbin: / bin: / usr / sbin: / usr / bin
0,10,20,30,40,50 * * * * sh /temperatura/get_send.sh
For this task, the sensor is polled and data is sent every 10 minutes. The last line of the script may well look
*/10 * * * * sh /temperatura/get_send.sh
like Since at the moment I have two devices turned on to send temperature data, and on the site data coming in more than once every five minutes is ignored, data from one of my devices is ignored. Therefore, for each device, the time for sending data with an interval between devices of 5 minutes was clearly set in the crown. Download scripts and crontab here . Next, copy the crontab of the root user to / etc / crontabs and the temperature folder in / (the root of the file system).
To start and enable cron, you must run in the terminal
/etc/init.d/cron start
/etc/init.d/cron enable
Go to the assembly site
After everything has been checked in the work, it's time to start assembling the entire economy into a single device. After opening the USB hub and the router, I began to figure out the layout of the devices inside the case, consulting Google and peering at the page on the modding of the router. It turned out that I bought the USB-HUB the same as the author of the first version of the improvements. Already good, since he managed to do this, then it will work out for me. After the initial layout of the internals of the device, it became clear that you can try to fit the USB-UART adapter there too. As a USB-UART adapter, I tested and sacrificed a data cable from some old PL2303 chip, which appeared from nowhere to use USB-UART as a bridge. Before that, it was being finalized by someone; not the smallest details that set the thickness of the board itself were soldered. After studying the circuits for telephone lanyards, these dimensional details were removed. The power switch was also removed and the protruding legs of the output elements were bitten off. The scarf immediately lost weight. You could use a handkerchief on FTDI, whose dimensions are at least 2 times less than the applied board, but it was a pity because it has a useful DTR signal used to reset the Arduino, and in PL2303 it is inverse and for its use the inverter would have to be fenced. And for our purposes, this signal is absolutely not important.
After finalizing the USB-UART adapter, the turn came for the USB hub, the protruding pins of which were also cut off. For him, this weight loss was almost not noticeable, but in general for the design I think it became useful. Based on the experience of people who have already done this, he began a second try-on. Those options that were offered did not suit me because I would have to remove the fiber. I threw it to the side opposite from the fiber, already better. But all the same, part of the LEDs will close the existing flash drive and you will also have to remove part of the fiber. But according to estimates, you can do without extreme measures by buying a flash drive shorter. I began to search the computer stores and found a decent option at the right price, which I bought the next day. As it turned out, the same flash drive model was already used by the author of another version of modding. It turns out that the choice of applied details is not so great, since I accidentally hit the same 2 times, completely independent of the authors who got ahead of me.
Next, I began to think about how to most elegantly place the UART port on the router case to connect an external sensor. It turned out that the USB port, which is no longer used now, whose power pins continue to fulfill the functions assigned to them, and the + D and -D pins cut off from the circuit, can quite be adapted for Rx and Tx. Excellent. Soldered everything together, checked.
To fix the boards between each other, I used the usual 2-sided tape. When assembling, you must be extremely careful that nothing is shorted anywhere and not push the tape with sharp soldered conclusions. When gluing the hub, I used two layers of scotch tape to increase the distance between the boards, 2 strips per layer folded with a “palenica”. For tests, I used the remaining tail from the same hub. That's what happened in the end.
The result pleased, even a little space left, and there was an unused built-in UART. In the bins, the HC-04 Bluetooth module was found and exemplified at a possible installation location. I got up as a native. It was immediately soldered and glued to the same tape on the USB port of the router.
Why do I need it? As I said above, it is a pity that the place and UART are disappearing. Plus, the router will not do anything for 10 minutes, not an order. You can hang some more functions. For example, the first reason I did this was to look at the thermometer on the Internet well, but not always conveniently. So I’m thinking of putting the simplest arduino with a 7-segment indicator. Or maybe a sign-synthesizing one, in order to also show the time / date. In general, a lot of options.
Close the lid prevented only one pin on it, which should rest on the board, and rests on the USB connector of the hub. I tried on an eye and cut off half.
After that, the lid fell into place normally. The truth also failed to put it tightly and it protrudes slightly upward. But this is normal and it does not interfere with all my improvements. I have the same thing on the first unfinished router. As a result, I received a seemingly almost virgin new router, not counting the traces of a neat opening.
To take the sensor out to the street, I used a collapsible USB connector on the cable and the cord from the mouse, it is softer than the other cords that I had, with a small piece of flat cable soldered to let it pass between the window seals when closing the window.
.
Issue price when using a router
Router TL-MR3020 910р.
USB-HUB Ginzzu 210p.
Flash drive Sandisk Cruzer Fit 8 GB 248 rub.
USB-UART adapter to PL2303 from China ~ 50r.
HC-04 Bluetooth module from China ~ $ 7 = 210r.
Temperature sensor DS16 (x) 20 ~ 60r.
Total ~ 1688 rub.
Naturally, the Bluetooth module can be thrown away, and then the price will approach the bar ~ 1500r.
Improvement Options
The first is the optimization of the scripts given in the article.
The second is that if you manage to get rid of the PHP script and switch to bash completely, you will get rid of the USB flash drive and USB hub, which will significantly reduce the complexity and cost of the end device.
The third (just an assumption) - it is possible if you clean the firmware by deleting unused modules, you can free up space for PHP, achieve the same results as in the second version.
Fourth - getting a hardware UART to work will reduce the cost, but will slightly increase the complexity. All I could find on this subject was an incomprehensible pastebin script to me without comment, and a link to a lying site, where the link to pastebin came from. I tried to run this script to no avail.
Fifth, enable GPIO output by writing the appropriate driver.
Dispatch with Raspberry Pi
As I already mentioned, I already had a raspberry configured properly to measure temperature on two sensors and draw up schedules. Thus, the matter remains small, pull out the temperature data and send it to the server.
A further description of the process will be given that you have already set up the raspberry for receiving data from sensors and plotting graphs. However, I will briefly tell you the principle of operation of those scripts, and those who wish can fully download my scripts for quick setup. In the version that I repeated and suggest you repeat, there are 3 scripts in bash, one in perl and one database file for RRDTool. The first bash script runs once and creates a database file. The second bash script is added to cron and all it does is run the rest of the scripts. First of all, he runs the get_temp.pl script, which is responsible for reading readings from temperature sensors and putting these readings into the database. The second line, he runs the create_graphs.sh script, which takes the temperature values from the database and builds graphs on them. Based on the fact that my raspberry is already able to do all this, I proceed to the implementation of the rest of the plan. Here, one PHP script is already used to send data to the server. In addition, several lines of processing the data received from the sensors are added to the existing get_temp.pl script and one line to the get.sh script.
My script for receiving data from sensors with the addition of processing temperature readings looks like this
get_temp.pl
####################################################### #######################
Here, I ask you to forgive me, either something is interfering with the script, or some kind of glitch, but I couldn’t insert it normally under the spoiler , for this I bring a piece of the original code with my modifications inserted.
####################################################### ######################
foreach $ device (@deviceIDs)
{
$ reading = & read_device ($ device);
if ($ reading == 9999) {
$ reading = "U";
}
push (@ temp_readings, $ reading);
}
if ($ temp_readings [0] ne 'U') {$ temp_readings [0] - = $ in_correction;}
if ($ temp_readings [1] ne 'U') {$ temp_readings [1] - = $ out_correction;}
# update the database
`/ usr / bin / rrdtool update /home/pi/temperature/multirPItemp.rrd N: $ temp_readings [0]: $ temp_readings [1]`;
print "Temp 1 = $ temp_readings [0] Temp 2 = $ temp_readings [1] \ n";
####################################################### ######################
# My add-ons are
open (FILE, "> / home / pi / temperature / temp_out");
print FILE "$ temp_readings [0]";
close (FILE);
open (FILE, "> / home / pi / temperature / temp_in");
print FILE "$ temp_readings [1]";
close (FILE);
####################################################### #######################
Here, I ask you to forgive me, either something is interfering with the script, or some kind of glitch, but I couldn’t insert it normally under the spoiler , for this I bring a piece of the original code with my modifications inserted.
####################################################### ######################
foreach $ device (@deviceIDs)
{
$ reading = & read_device ($ device);
if ($ reading == 9999) {
$ reading = "U";
}
push (@ temp_readings, $ reading);
}
if ($ temp_readings [0] ne 'U') {$ temp_readings [0] - = $ in_correction;}
if ($ temp_readings [1] ne 'U') {$ temp_readings [1] - = $ out_correction;}
# update the database
`/ usr / bin / rrdtool update /home/pi/temperature/multirPItemp.rrd N: $ temp_readings [0]: $ temp_readings [1]`;
print "Temp 1 = $ temp_readings [0] Temp 2 = $ temp_readings [1] \ n";
####################################################### ######################
# My add-ons are
open (FILE, "> / home / pi / temperature / temp_out");
print FILE "$ temp_readings [0]";
close (FILE);
open (FILE, "> / home / pi / temperature / temp_in");
print FILE "$ temp_readings [1]";
close (FILE);
####################################################### #######################
The essence of my additions is to capture temperature data that is recorded in the database, and write it to separate files for each sensor.
After all this has worked, you can do the script to send data to the server. For this we need to install PHP.
sudo apt-get install php5-cgi
The script for sending data is made from an example presented on the site "People's Monitoring". It accesses the files created by the previous script, takes temperature data from them and sends them.
My send.php script looks like this
send.php
#! / usr / bin / php-cgi -q
$ file_name = "/ home / pi / temperature / temp_out";
$ file = fopen ("$ file_name", "r");
$ gradus_out = fread ($ file, filesize ($ file_name));
echo "$ gradus_out \ n";
fclose ($ file);
$ file_name = "/ home / pi / temperature / temp_in";
$ file = fopen ("$ file_name", "r");
$ gradus_in = fread ($ file, filesize ($ file_name));
echo "$ gradus_in \ n";
fclose ($ file);
$ fp = @fsockopen ("tcp: //narodmon.ru", NNNN, $ errno, $ errstr);
# where NNNN is the port number available after registration
if (! $ fp) exit ("ERROR (". $ errno. "):". $ errstr);
fwrite ($ fp, "# 01-23-45-67-89-AF \ n # 0123456789ABCDEF # $ gradus_out \ n # 0123456789ABCDEF # $ gradus_in \ n ##");
fclose ($ fp);
?>
$ file_name = "/ home / pi / temperature / temp_out";
$ file = fopen ("$ file_name", "r");
$ gradus_out = fread ($ file, filesize ($ file_name));
echo "$ gradus_out \ n";
fclose ($ file);
$ file_name = "/ home / pi / temperature / temp_in";
$ file = fopen ("$ file_name", "r");
$ gradus_in = fread ($ file, filesize ($ file_name));
echo "$ gradus_in \ n";
fclose ($ file);
$ fp = @fsockopen ("tcp: //narodmon.ru", NNNN, $ errno, $ errstr);
# where NNNN is the port number available after registration
if (! $ fp) exit ("ERROR (". $ errno. "):". $ errstr);
fwrite ($ fp, "# 01-23-45-67-89-AF \ n # 0123456789ABCDEF # $ gradus_out \ n # 0123456789ABCDEF # $ gradus_in \ n ##");
fclose ($ fp);
?>
where, as in the version with router 01-23-45-67-89-AF, is the mac address of the wlan (Wi-Fi) network card or lan, if the raspberry is connected through it, and 0123456789ABCDEF is the serial number of the DS16 temperature sensor ( x) 20.
Then we add a line to the get.sh script indicating the execution of the send.php script.
Get.sh script
#! / bin / bash
/home/pi/temperature/get_temp.pl
/home/pi/temperature/create_graphs.sh
######################### ####################################################
# My addition
/home/pi/temperature/send.php
echo "OK \ n"
#################################### #########################################
/home/pi/temperature/get_temp.pl
/home/pi/temperature/create_graphs.sh
######################### ####################################################
# My addition
/home/pi/temperature/send.php
echo "OK \ n"
#################################### #########################################
In the crown I changed the schedule for sending data every 10 minutes with a clear reference to the time that does not overlap with the time the data was sent by the router.
The task in the crown looks like this.
5,15,25,35,45,55 * * * * /home/pi/temperature/get.sh
After that, everything should work. Download these scripts here
Issue price when using Raspberry Pi
Here it’s already impossible to count so unequivocally. The fact is that the cost of the raspberry itself and the additional components to it can vary greatly from person to person.
Conclusion
In my opinion, if you do not have either one, the most rational is the use of a router. Using raspberries makes sense only if you already have it, constantly turned on and perform any tasks.
But in general, it arrived in the regiment of devices sending data to the People Monitoring service, and this is good.
UPD
Together, we managed to get rid of the PHP script and write everything in BASH, for which thanks to all who responded. I want to express special gratitude to the user Ssar , his prompt turned out to be decisive in writing a script for the router. At the moment, there is only one get_send.sh script left, and two auxiliary files.
get_send.sh
#! / bin / bash
rm / temperatureura / 1wire_log
rm / temperatureura / temp
rm / temperatureura / out
cd /
digitemp_DS9097 -i -s / dev / ttyUSB0
sleep 1s
digitemp_DS9097 -a -A -l / temperatureura / 1wire_log
sleep 2s
cd / temperatureura
cut -c29-33 1wire_log | sed 's / $ //'> temp
cat / temperature / mac_id> / temperature / out
cat / temperature / temp >> / temperature / out
cat / temperature / end >> / temperature / out
cat / temperature / out | / usr / bin / nc narodmon.ru NNNN
# where NNNN - port number available after registration
echo “OK”
rm / temperatureura / 1wire_log
rm / temperatureura / temp
rm / temperatureura / out
cd /
digitemp_DS9097 -i -s / dev / ttyUSB0
sleep 1s
digitemp_DS9097 -a -A -l / temperatureura / 1wire_log
sleep 2s
cd / temperatureura
cut -c29-33 1wire_log | sed 's / $ //'> temp
cat / temperature / mac_id> / temperature / out
cat / temperature / temp >> / temperature / out
cat / temperature / end >> / temperature / out
cat / temperature / out | / usr / bin / nc narodmon.ru NNNN
# where NNNN - port number available after registration
echo “OK”
Download the archive here . Unpack the subfolder to the root of the file system without forgetting about crontab.
This script performed the second point of optimization of the device, and this leads to a cheaper and simplified design.
UPD 2
Ssar user wrote an improved BASH script to automatically determine the mac address of the device and connect several sensors with automatic detection of sensor IDs. Thus, now there is no need to manually register this data in a script, he will do it for you.