Электронный термометр с web-интерфейсом на основе UniPing RS-485

в 13:02, , рубрики: diy или сделай сам, highstock, perl, snmp, биоинформатика, Веб-разработка, Железо, метки: , , ,

Как известно фенотип организма формируется под влиянием генотипа и окружающей среды. Один из моих проектов — система для анализа взаимоотношений генотипа, фенотипа и окружающей среды у пшеницы. Летом растения выращивают в поле. Хотелось после окончания сезона иметь доступ к подробным метеорологическим данным, именно в том месте, где росли растения. Эти данные нужны для сопоставления их с генотипами и различными фенотипическими характеристиками растений и проведения различных статистических анализов.

Поле, где работают биологи, располагается в некотором удалении от здания, в которое мы могли получить доступ, возможность установить свое оборудование и использовать Internet.

На схеме место установки датчика показано красной точкой. Так же отмечены основные достопримечательности: охлаждающие фонтаны Института Ядерной Физики, магазин «Карасик» и поле, где выращивают растения. Все это находится в Новосибирском академгородке.

место установки датчика

Выбор устройства

Стояла задача найти устройство, способное считывать параметры окружающей среды и передавать данные по сети Ethernet. При этом времени на эксперименты и размышления почти не было, т.к. через две недели должна была начаться посевная и к этому моменту уже все должно было работать. На eBay продают огромное множество недорогих китайских устройств стоимостью около 100$ и существуют проекты типа pywws, которые обеспечивают считывание данных с таких устройств. Однако, доставка с eBay заняла бы сильно много времени. При этом не факт, что в итоге мы получили бы, то что хотели. Тем временем наткнулся на статью с положительным отзывом об устройствах компании NetPing. Вообще, они специализируются на устройствах для систем безопасности и администрирования, однако помимо всего прочего производят датчики температуры и влажности. Было решено заказывать у них.

Заказ и описание UniPing RS-485

Было заказано устройство, которое считывает данные с различных датчиков, сам датчик температуры и влажности, удлинитель для датчика на 4 метра:

  • Датчик влажности WS-1 (1 м) — 1 056 р.
  • Удлинитель (4 м) — 160 р.
  • Устройство UniPing RS-485 — 2 700 р.
  • Доставка заказа (Экспресс-почта), УСЛУГА — 1 130 р.
  • Итого — 5 046 р.

Для наших целей RS-485 и RS-232 полностью идентичны. Выбор RS-485 обусловлен его наличием на складе.
RS-485
На фото UniPing RS-485. Комплект поставки: устройство, адаптер питания, ответная часть разъема, переходник для контактных датчиков. Датчик влажности контактным не является. Термодатчики — являются. Вот такая вот странная логика. Поэтому переходник для контактных датчиков никак использоваться не будет.

К UniPing RS-485 можно подключить один датчик влажности и 4 термодатчика. Для подключения нескольких датчиков лучше использовать NetPing Connection board, иначе придется все паять самому. В комплект поставки она не входит и заказывается отдельно.

Датчик влажности позволяет получить значение относительной влажности воздуха в процентах. Так же датчик влажности позволяет измерять температуру. Точность измерения влажности +-4,5%. Точность измерения температуры 0,5С.

датчик влажности

Просто датчик температуры стоит дешевле, чем датчик влажности: 352р. во влагозащищенном корпусе и 176р. за обычный.

Подключение датчика влажности

Для подключения датчика влажности надо использовать ответную часть разъема DHS-44. Ниже приведена схема распайки:

Цветной шлейф Номер контакта DHS-44
Желтый 28
Зеленый 32
Красный 23
Чёрный 24

Нумерация DHS-44M (номера указаны на самом разъёме и его ответной части)

DHS-44M

В документации сказано, что для длинных шлейфов, более 2 м., рекомендуется дополнительно включить резистор 10К между контактами 28 и 24. Но мне этого делать не пришлось, т.к. и без того все хорошо работает, хотя и использую шлейф длинной 5 метров.

Общение со службой поддержки

При попытке включения устройства выявилась первая и единственная неприятность. Устройство не включалось. Диагностика показала, что не работает блок питания. Написал в поддержку NetPing. Спросил, что будем делать. Предложили приехать к ним в Москву с неработающим блоком и заменить. Я возразил, что такой вариант для меня не приемлим. Предложили выслать не работающий блок по почте, они его проверят и если проблема есть, вышлют новый. При этом пересылка туда-обратно за мой счет! Опять возразил, что при этом расходы на пересылку во много раз превысят стоимость самого блока. После этого пошли на уступки: предложили что бы я выслал им не рабочий блок за свой счет, а новый они мне пришлют за свой. После этого я поблагодарил поддержку, пошел в радио-магазин и нашел там блок с точно такими же характеристиками и разъемом за 250 рублей. Повезло.

Резюме из этой небольшой истории следующее: компания NetPing никак не тестирует свою продукцию перед отправкой клиенту. Даже включать не пробует! К поддержке претензий нет — они просто выполняют установки руководства компании. Но могло бы быть все совсем по другому, вот отличный пример.

Настройка устройства

UniPing RS-485 имеет встроенный web-интерфейс для редактирования настроек. Заходим туда и меняем сетевые настройки и пароль администратора. Сетевые настройки можно задать только статически. Тут же можно посмотреть какие датчики подключены к устройству и убедиться, что они работают. На этом настройка закончена.

Считываем данных с датчика

Устройства NetPing поддерживают работу по протоколу SNMP v1. Получение данных по протоколу SNMP v1 сводится к чтению специальных адресов внутри устройства, называемых OID. Для получения значений влажности и температуры надо знать OID, которые соответствуют этим параметрам. Список всех OID, которые поддерживаются устройством можно считать из MID файла. По сути MID файл — это прошивка, точнее её описание. Её можно скачать на сайте производителя устройства. Для работы с MID файлом я использовал программу iReasoning MIB Browser — она бесплатная. С её помощью были получены нужные OID. Привожу скрипт на perl, который получает данные по SNMP и записывает их в базу MySQL. Этот скрипт помещен в cron, который срабатывает каждый час.

#!/usr/bin/perl

use strict;
use warnings;
use DBI;
use Net::SNMP;

# Параметры подключения с базе
my $database_login = 'login';
my $database_passwd = 'password';
my $database_name = 'db_name';

# Подключаемся к базе
my $dbh = DBI -> connect("DBI:mysql:$database_name;host=localhost;", $database_login, $database_passwd) || die $DBI::errstr;

# Что будем оправшивать
my $snmp_host = '172.25.13.5'; # IP или hostname
my $snmp_community = 'SWITCH'; # SNMP Community


#Температура
my $snmp_oid_temperature = '.1.3.6.1.4.1.25728.8400.2.4.0'; # OID для опроса

#Относительная влажность
my $snmp_oid_humidity = '.1.3.6.1.4.1.25728.8400.2.2.0'; # OID для опроса

# Пытаемся читать значение
# В -varbindlist должна быть ссылка на массив OID'ов
# В $result будет ссылка на хэш вида: OID => Значение

  my $snmp_session = Net::SNMP->session(
      -hostname => $snmp_host,
      -community => $snmp_community,
      -version => 1, # Явно указываем версию протокола
  ) or die "can't connect";

my $result = $snmp_session->get_request(-varbindlist => [$snmp_oid_temperature,$snmp_oid_humidity]) or die "can't execute requestn";

# Печатаем результат
print "$result->{$snmp_oid_temperature}n$result->{$snmp_oid_humidity}n";

# Пишем значения в базу
$dbh -> do("INSERT INTO netping1 SET temperature="$result->{$snmp_oid_temperature}", humidity="$result->{$snmp_oid_humidity}"") || die $DBI::errstr;

API

Для доступа к данным базы был реализован простой API, который возвращает данные в формате JSON. Данные возвращаются в виде двухмерного массива и сортированы по возрастанию времени. Пример такого массива из двух элементов:

[[
1338541272000, # время с начала эпохи в миллисекундах
12,            # температура
53             # влажность
],
[
1338544861000, # время с начала эпохи в миллисекундах
14,            # температура
49             # влажность
]]

Сейчас доступно следующее:

http://wheatdb.org/weather/json/now - получить последнее считанное значение
http://wheatdb.org/weather/json/1 - получить массив значение за последние сутки
http://wheatdb.org/weather/json/3 - получить массив значение за последние 3 дня
http://wheatdb.org/weather/json/7 - получить массив значение за последнею неделю
http://wheatdb.org/weather/json/30 - получить массив значение за последние 30 дней
http://wheatdb.org/weather/json/0 - получить массив значений за все время

Web-интерфейс

Реализованный web-интерфейс доступен по ссылке. На случай хаброэффекта привожу так же скриншот.

Web-интерфейс

Интерфейс показывает текущие значения влажности, температуры и графики изменения этих величин. Для построения графиков использовалась библиотека HighStock, бесплатная для не коммерческого использования. С учетом уже реализованного API код клиентской части выглядит очень просто:

<script type="text/javascript" src="http://wheatdb.org/static/js/stock/highstock.js"></script>
<script type="text/javascript" src="http://wheatdb.org/static/js/stock/modules/exporting.js"></script>

<script type="text/javascript">
$(document).ready(function() {
    $.getJSON("http://wheatdb.org/weather/json/3",{},
    function(data){
      
    // split the data set
var t = [],
h = [],
dataLength = data.length;

for (i = 0; i < dataLength; i++) {
t.push([
data[i][0], // date
data[i][1] // temperature
]);

h.push([
data[i][0], // date
data[i][2] // humidity
])
}
      
        // Create the chart
        window.chart = new Highcharts.StockChart({
          chart : {
            renderTo : 'container'
          },
    
          rangeSelector : {
            selected : 1
          },
    
          title : {
            text : ''
          },

          yAxis: [{
              title: {
                  text: 'Temperature'
              },
              height: 150,
              lineWidth: 2
          }, {
              title: {
                  text: 'Humidity'
              },
              top: 220,
              height: 150,
              offset: 0,
              lineWidth: 2
          }],
        
          series : [{
            name : 'Temperature',
            type : 'area',
            data : t,
            marker : {
              enabled : true,
              radius : 3
            },
            shadow : true,
            tooltip : {
              valueDecimals : 0
            },
            fillColor : {
              linearGradient : {
                x1: 0,
                y1: 0,
                x2: 0,
                y2: 1
              },
              stops : [[0, Highcharts.getOptions().colors[0]], [1, 'rgba(0,0,0,0)']]
            }
          } , {
            name : 'Humidity',
            type : 'area',
            data : h,
            marker : {
              enabled : true,
              radius : 3
            },
            shadow : true,
            tooltip : {
              valueDecimals : 0
            },
            fillColor : {
              linearGradient : {
                x1: 0,
                y1: 0,
                x2: 0,
                y2: 1
              },
              stops : [[0, Highcharts.getOptions().colors[1]], [1, 'rgba(0,0,0,0)']]
            },
            yAxis: 1
          }]
        });
    });
});
</script>
<div id="container" style="height: 500px; min-width: 500px"></div>

Выводы

Система работает уже около месяца. Никаких сбоев в работе не выявлено, данные исправно считываются. В целом выбранное устройство показало свою применимость для поставленной задачи. Буду очень признателен, если в комментариях вы поделитесь своим опытом автоматического получения данных о состоянии окружающей среды. Особенно интересуют беспроводные решения.

Автор: genaev

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js