Шаманство с датчиком
Для нам нужно подключить сам датчик. Я буду работать с датчиком температуры DS18B20. Статей на эту тему полно, не будем их дублировать. Про подключение можно почитать здесь. Затем нам нужно получить данные с датчика. Мы сделаем так же, как указано в статье выше. Там есть замечательный пример на Python, фанатом которого я являюсь.
import os
tfile=open("/sys/bus/w1/devices/28-000000d7970b/w1_slave")
ttext=tfile.read()
tfile.close()
temp=ttext.split("\n")[1].split(" ")[9]
temperature=float(temp[2:])/1000
print temperature
Не забываем заменить данные на свой датчик.
Как мы можем заметить, значение температуры принимает переменная temperature (кто бы мог подумать), что и понадобится нам дальше.
Колдуем с мониторингом
Ну во первых нужно зарегистрироваться narodmon.ru, тем, кто ещё это не сделал. API сервиса предлагает нам передавать данные по протоколу TCP. Так и поступим. Нас просят передать текст следующего формата:
#MAC[#NAME][#LAT][#LNG][#ELE]\n
#mac1#value1[#time1][#name1]\n
...
#macN#valueN[#timeN][#nameN]\n
##
Но по факту нам нужно передать всего три параметра: MAC устройства, имя датчика и его значение. Остальное не обязательно, и не очень нам нужно.
В первой строке нам нужно передать решётку, MAC и символ перевода строки \n.
Во второй и последующих строках мы опять передаём решётку, имя датчика, опять решётка и показания датчика. Завершаем это символом перевода строки \n.
В последней строке надо передать две решётки, для завершения пакета.
В итоге формат остаётся таким:
#MAC\n
#mac1#value1\n
#macN#valueN\n
##
Пишем программу на Python
Программу мы будем писать на Python 2. Алгоритм будет такой. Получаем данные с датчика и записываем в переменную temperature. Затем мы формируем пакет и отправляем его на сервер Народного Мониторинга. Запускать скрипт будем каждые 10 минут (минимальный разрешённый интервал отправки показаний 5 минут) через cron.
Отправка происходит так (пример приведённый на сайте мониторинга):
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
# by Roman Vishnevsky aka.x0x01 @ gmail.com
import socket
# MAC адрес устройства. Заменить на свой!
DEVICE_MAC = '0123456789012'
# идентификатор устройства, для простоты добавляется 01 (02) к mac устройства
SENSOR_ID_1 = DEVICE_MAC + '01'
SENSOR_ID_2 = DEVICE_MAC + '02'
# значения датчиков, тип float/integer
sensor_value_1 = 20
sensor_value_2 = -20.25
# создание сокета
sock = socket.socket()
# обработчик исключений
try:
# подключаемся к сокету
sock.connect(('narodmon.ru', 8283))
# пишем в сокет еденичное значение датчика
sock.send("#{}\n#{}#{}\n##".format(DEVICE_MAC, SENSOR_ID_1, sensor_value_1))
# пишем в сокет множественные значение датчиков
# sock.send("#{}\n#{}#{}\n#{}#{}\n##".format(DEVICE_MAC, SENSOR_ID_1, sensor_value_1, SENSOR_ID_2, sensor_value_2))
# читаем ответ
data = sock.recv(1024)
sock.close()
print data
except socket.error, e:
print('ERROR! Exception {}'.format(e))
Подключаемся мы к серверу narodmon.ru:8283
В итоге у нас получается вот такой скрипт:
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import socket
import os
# MAC адрес устройства. Заменить на свой!
DEVICE_MAC = 'FF:FF:FF:FF:FF:FF'
#Имена датчиков
SENSOR_ID_1 = 'T1'
SENSOR_ID_2 = 'T2'
#Читаем значения датчиков
temperature = []
IDs = []
for filename in os.listdir("/sys/bus/w1/devices"):
if fnmatch.fnmatch(filename, '28-031652ddbdff'):
with open("/sys/bus/w1/devices/" + filename + "/w1_slave") as fileobj:
lines = fileobj.readlines()
if lines[0].find("YES"):
pok = lines[1].find('=')
temperature.append(float(lines[1][pok+1:pok+7])/1000)
IDs.append(filename)
else:
logger.error("Error reading sensor with ID: %s" % (filename))
temperature2 = []
for filename in os.listdir("/sys/bus/w1/devices"):
if fnmatch.fnmatch(filename, '28-011563e8d2ff'):
with open("/sys/bus/w1/devices/" + filename + "/w1_slave") as fileobj:
lines = fileobj.readlines()
if lines[0].find("YES"):
pok = lines[1].find('=')
temperature2.append(float(lines[1][pok+1:pok+7])/1000)
IDs.append(filename)
else:
logger.error("Error reading sensor with ID: %s" % (filename))
sock = socket.socket()
#Подключаемся
try:
sock.connect(('narodmon.ru', 8283))
#Создаём маску, заносим в неё данные и передаём их
sock.send("#{}\n#{}#{}\n#{}#{}\n#{}#{}\n#{}#{}\n##".format(DEVICE_MAC, SENSOR_ID_1, str(temperature)[1:-1], SENSOR_ID_2, str(temperature2)[1:-1])
#Получаем ответ
data=sock.recv(1024)
sock.close()
print data
except socket.error, e:
print('ERROR! Exception {}'.format(e))
print str(temperature)[1:-1]
print str(temperature2)[1:-1]
Вот так выглядит отправка данных с двух датчиков. Если дать датчику название, начинающееся на T, то сервер сам определит, что это датчик температуры.
Теперь нам нужно добавить датчик в cron. Набираем:
crontab -e
и добавляем туда вот такую строчку:*/10 * * * * sudo python /home/pi/narod.py
Ждём пока скрипт запустится.
Теперь идём сюда narodmon.ru/ip и смотрим передались ли данные. Если всё в порядке, то нажимаем на главной странице в меню кнопку «Добавить устройство» и указываем MAC. Теперь мы можем всё настроить по вкусу (название, тип, местоположение и т.д.). Сделать датчик публичным можно через сутки после начала передачи показаний.
На этом всё. Желаю Вам удачи в подключение датчиков. Делайте это чаще, ведь так удобно из дома заранее посмотреть температуру в том месте, куда ты собираешься.
До новых встреч :)
Комментарии (29)
DARK-ADMIN
10.02.2017 04:06Даже в данном случае, как систему мониторинга я бы выбрал Zabbix, тем более на то есть все ресурсы
chelaxe
10.02.2017 20:53Nexx WT3020H + RODOS-5 (MP707) Результат в Zabbix. Сейчас хочу SMALL METEO V4 прикупить.
general2201
10.02.2017 04:06-1Сейчас бы в 2017 писать на python 2
LumberJack
10.02.2017 09:35+2В Raspbian-e он есть по умолчанию. Меньше проблем, никаких левых библиотек качать не нужно. Так что выбор вполне оправдан.
Ungla
10.02.2017 14:23Python3 там так же есть, все «DIY»-библиотеки для третьего питона есть, синтаксис у них лучше и они быстрее. Так что выбор оправдан только тем, что автор не нашёл ничего другого. Я не чтобы поогрызаться, а к тому что Python3 уже всюду предпочтительнее.
teleghost
10.02.2017 04:22+6здравствуйте, уважаемый автор,
Чтобы метеостанция не сдохла через полгода-год от самозапиливающейся флэшки, настоятельно рекомендую монтировать её в read-only, см., например, https://geektimes.ru/post/283802/. Остальные рекомендации помещаю в спойлеры.
про 1-wire, sysfs и hardcodeНесмотря на имеющиеся ссылки, неплохо было бы посвятить хотя бы один абзац текста описанию того, что DS18B20 работает через интерфейс 1-wire, что доступ к нему получаете черезsysfs
, и что для этого подгружаются модули
иw1-gpio
. Для тех, кто предпочитает активировать 1-wire по-простому, можно указать и на утилитуw1_therm
. Хорошо бы объяснить смысл параметров типаraspi-config pullup
и питанию. Те, кто раньше не работал с датчиками черезsysfs
, наверняка оценят и разъяснения к схеме именования, по которой все устройства появляются в
, а каждому устройству сопоставляется каталог вида/sys/bus/w1/devices YY-xxxxxxxxxxxx , где YY суть Family Code (28 для DS18B20), а остальное — уникальный номер устройства. И если Вы свои устройства зашиваете в скрипт хардкодом, предупредите, пожалуйста, об этом явно в комментариях. Хотя резиденты местного клуба и так разберутся, но для гостей портала все вышеперечисленное не будет лишним.nikitos_2002
10.02.2017 04:31+2Учту ошибки. Вечером исправлю)
xcore78
10.02.2017 15:52Поправьте заголовок заодно, пожалуйста.
AVX
10.02.2017 09:02-1Этот датчик разве не может работать как триггер? Насколько помню, что 1820, что 1821 — примерно одного класса устройства. Имел опыт работы с 18С21 (может быть неточно, там ещё что-то было в маркировке) в триггерном режиме. Суть в том, что датчик можно запрограммировать, так, что он перестаёт выдавать по 1-wire температуру, но выход принимает только два значения: лог.1 и лог.0. Запрограммировать верхний предел температуры и нижний можно специальным программатором (например, тут описано http://www.rtcs.ru/article_detail.asp?id=73). Точность в таком случае 1 градус, что для Вашего случая (насколько понял, теплица) вполне подойдёт для автоматической регулировки без каких либо микроконтроллеров и прочего — просто усилитель на транзисторе и реле, управляющее обогревом.
Конечно, если микроконтроллер/компьютер уже есть, то всё это и на нём можно сделать, я просто хотел сказать, что для регулировки температуры не нужно закупать компьютер.LumberJack
10.02.2017 09:36А на narodmon что передавать: 0 или 1?
AVX
10.02.2017 11:00+1Я просто думал, что датчики ставят как раз с целью автоматизации — чтобы была автоматическая регулировка. Но если нужен именно мониторинг значений температуры — то триггерный режим не подойдёт. Правда, можно передавать 0 или 1 — только трактовать это надо будет так — 1 — превышение TH, 0 — температура ниже TL (или наоборот, инвертировать можно хоть логикой в программе, хоть аппаратно).
ta4ukoma
10.02.2017 14:31Может я не так понял — подскажите, а MAC устройства это разве не MAC самой малинки которая данные отправляет? Если да, то почему вы не берете адрес из системы и вбиваете его руками?
nikitos_2002
10.02.2017 14:33Можно и автоматизировать. Просто я обычно не меняю WIFI адаптеры на малинке, так что MAC не меняется. Каждый раз проверять его не нужно.
ta4ukoma
10.02.2017 14:42Я вообще то был уверен что программисты унифицируют код в порядке хорошего тона, чтобы голова не болела о таких мелочах. То есть вот случись чего с вашей малинкой или с wifi адаптером, или кто-то воспользуется вашим скриптом — придётся править этот кусок кода руками. Да банально — вам пришлось лезть в систему и копировать оттуда MAC адрес сетевухи в ручную! Не лень разве было?)
nikitos_2002
10.02.2017 15:03Я думаю, Вы конечно правы. Просто в первую очередь я делал это для себя, и такое не предусмотрел. Добавлю это в статью. Спасибо )
ta4ukoma
10.02.2017 15:19+1Опять же) если вы делитесь своим творением с окружающими, то это уже точно не для вас одного код. Подумайте над этим)))
aivs
10.02.2017 15:48+3Удобно, когда на GPIO Raspberry Pi ничего другого не подключено, кроме одной шины с датчиками. Как в мануалах написано подключать к 4 ноге ds18b20, так все и подключают.
Пара лет назад мне потребовалось подключить ds18b20, на Raspberry оставались свободные пару ног и как оказалось в ядре захардкожена нога 4 для 1-wire. После пары дней танцов с бубнами, пересборкой модулей ядра я добился того, что 1-wire заработал на 22 ноге.
Сейчас по прежнему по умолчанию нога для 1-wire это 4. Но можно и поменять:
pi@raspberrypi:~ $ tail /boot/config.txt #dtoverlay=lirc-rpi # Additional overlays and parameters are documented /boot/overlays/README # Enable audio (loads snd_bcm2835) dtparam=audio=on gpu_mem=160 dtoverlay=lirc-rpi,gpio_in_pin=11,gpio_out_pin=9 dtoverlay=w1-gpio,gpiopin=22
delvin-fil
11.02.2017 04:51Своего датчика пока нет(но все готово для запуска).
Мониторю температуру с чужих
http://pastebin.com/7wGGZNtW
Snowtomcat
ИМХО в статье на хватает линка на Ваш работающий датчик. Можете опубликовать?
nikitos_2002
Попробую. Сейчас зима, теплица работает с перебоями.