MQTT (для приборов с обратной связью) и JSON для одновременной передачи данных сразу нескольких приборов и интеграции с другими системами мониторинга. Максимальный размер пакета данных 4 КБ для TCP/POST, 2 КБ для GET, 512 байт для UDP (ограничение MTU). Если с момента TCP подключения прошло 10 секунд (кроме MQTT), то такие подключен" /> MQTT (для приборов с обратной связью) и JSON для одновременной передачи данных сразу нескольких приборов и интеграции с другими системами мониторинга. Максимальный размер пакета данных 4 КБ для TCP/POST, 2 КБ для GET, 512 байт для UDP (ограничение MTU). Если с момента TCP подключения прошло 10 секунд (кроме MQTT), то такие подключен" />

API для передачи показаний датчиков в IoT проект Интернет вещей - Народный Мониторинг

+ Общие сведения и ограничения передачи показаний датчиков

Передавать показания датчиков можно посредством протоколов TCP/UDP (в большинстве случаев) или HTTP(S) GET/POST (для начинающих или с шифрованием), а также MQTT (для приборов с обратной связью) и JSON для одновременной передачи данных сразу нескольких приборов и интеграции с другими системами мониторинга. Максимальный размер пакета данных 4 КБ для TCP/POST, 2 КБ для GET, 512 байт для UDP (ограничение MTU).
Если с момента TCP подключения прошло 10 секунд (кроме MQTT), то такие подключения закрываются принудительно, поэтому настоятельно рекомендуем сперва опросить все датчики на вашем приборе, записать их показания в буфер, а только потом устанавливать подключение и передать пакет данных на сервер.

Данные обрабатываются и загружаются в базу пакетно 1 раз в минуту (команды MQTT немедленно), соответственно и показания датчиков также обновляются ежеминутно. При отправке показаний чаще чем 1 раз в минуту прибор попадает в бан до устранения проблемы его владельцем.
Допустимый интервал записи показаний датчиков в историю (для построения графиков, выгрузки во внешние системы и CSV) составляет 5 минут и может быть уменьшен для партнеров и коммерческих клиентов.

Запрещается разглашать свои уникальные MAC-адреса приборов и датчиков на сторонних ресурсах и при публикации исходных кодов для передачи показаний на narodmon.ru следует их маскировать во избежание проблем слепого копирования чужого кода среди новичков и, как следствие, конфликтов уникальности MAC в проекте.

При наличии ошибок в протоколе прибора, его IP блокируется на 15 минут. Мера вынужденная ибо боты-сканеры уязвимостей утомили и их активность растет.

+ Как отладить (проверить на ошибки и активность) данные с прибора

В процессе разработки новых приборов нередко возникает необходимость отладить его протокол передачи показаний с целью обнаружения и исправления ошибок в нем, но как быть, если лимит приборов в проекте не позволяет вам это сделать ?

1. Если ваш прибор находится в вашей домашней/офисной сети и стало быть имеет тот же публичный IP адрес, что и ваш браузер, то для отладки вы можете воспользоваться разделом сайта Профиль \ Данные с моего IP (после авторизации) или же по короткой ссылке narodmon.ru/me

2. Если же вы отлаживаете прибор, подключенный к мобильному интернету (т.е. его публичный IP не совпадает с вашим браузером), то вы можете воспользоваться ссылкой вида: narodmon.ru/dev/DEVICEMAC
* DEVICEMAC заменить на MAC вашего прибора (без : и -) в любом регистре. Если прибор уже зарегистрирован в проекте, то читаем далее п.3.

3. Для успешно зарегистрированных приборов отладочная информация находится в разделе сайта Датчики \ Настройка \ данные, полученные от прибора.

PS В отладочной информации доступны данные обо всех пакетах данных полученных сервером за последние пару часов от вашего прибора, а также ошибках в его протоколе (если таковые имеются). Если же этих данных нет, значит или IP/MAC прибора отличается от указанного вами или у прибора нет доступа в Интернет (неверно настроен или не оплачен).

+ Перечень типичных ошибок в ответе сервера:

* INTERVAL...<5m - прибор передает данные чаще, чем ему дозволено (по умолчанию 5 минут).
* Sensor...invalid value... - датчик передал на сервер недопустимое показание (например буквы вместо цифр).
* Sensor...out of range... - датчик передал показание за пределами допустимого диапазона для его типа данных.
* ...is too big - датчик передал слишком большое показание.
* UnixTime > NOW - указанное время в UnixTime (UTC+0) показания больше текущего.
* MAC_MISSED - пропущена метрика датчика или MAC (серийный номер) прибора.
* Device MAC...is invalid - недопустимый MAC (серийный номер) прибора.
* ##_MISSED_AT_THE_END - отсутствует признак конца пакета данных ## (пакет обрезался при отправке).
* BANNED - прибор заблокирован владельцем или администратором.
* IP binding enabled. Data from...is ignored - у прибора включена привязка к IP, но данные поступают с другого IP и поэтому игнорируются (возможно провайдер сменил Ваш IP или обнаружен конфликт уникальности MAC приборов).

Данные, необходимые для передачи на сервер проекта

+ Поле MAC (ID) - уникальный идентификатор прибора в проекте

Чаще всего состоит из 12-18 символов A-Z и 0-9 иногда разделенных '-' или ':'.
Предназначен для идентификации прибора (и поставщика по префиксу) в проекте и его привязки к владельцу и к карте в разделе Датчики.
Разработчикам приборов рекомендуется использовать персональный префикс для своих приборов для обеспечения уникальности в проекте и установления авторства, а также избегать часто повторяющихся знаков как в примере ниже.

TCP/UDP:
#00:00:00:00:00:00
...
##

GET/POST:
id=00:00:00:00:00:00&...

+ Поле NAME - название прибора в проекте

Необязательное к передаче название прибора в кодировке UTF-8 или Windows-1251 по факту переименования. Передается в TCP/UDP в 1й строке после MAC прибора и разделителя #, а в GET/POST передается отдельным параметром NAME. Рекомендуется для приборов с веб-интерфейсом или с утилитой конфигурации, в которых можно указать алиасы (названия).

TCP/UDP:
#MAC#Название
...
##

GET/POST:
ID=MAC&NAME=Название&...

+ Поле OWNER - владелец прибора в проекте

Необязательное к передаче поле (на выбор: USER, LOGIN, OWNER), содержащее логин или e-mail или мобильный номер владельца прибора в Профиле участника проекта для автоматической регистрации прибора. Передается в виде отдельной метрики виртуального датчика с текстовым значением. Учитывается 1 раз для автоматической привязки ничейных приборов к учетной записи в проекте и не подходит для смены текущего владельца прибора.

TCP/UDP:
#MAC
#OWNER#UserName
...
##

GET/POST:
ID=MAC&OWNER=UserName&...

+ Поля LAT,LON,ALT - широта, долгота, высота местоположения прибора

Необязательные к передаче геокоординаты местоположения прибора в десятичном виде!
Передаются отдельными метриками виртуальных датчиков LAT, LON, ALT.
Может быть полезно для мобильных приборов с GPS/ГЛОНАСС и подключенными к ним датчиками.

TCP/UDP:
#MAC
#LAT#39.962502
#LON#-83.006104
#ALT#545
...
##

GET/POST:
ID=MAC&LAT=39.962502&LON=-83.006104&ALT=545...

Для GSM и WiFi приборов можно использовать специальные метрики AP* и BS* для приблизительного местоположения по вышкам сотовой связи и/или точек доступа WiFi. Средняя погрешность 100м - 10км, что значительно точнее GeoIP.
Чем больше подобных метрик передадите в пакете данных, тем точнее определение местоположения.

TCP/UDP:

WiFi BSSID = 00:00:00:00:00:00 и RSSI = -70:
#AP:00:00:00:00:00:00#-70

GSM MCC(000h) + MNC(000h) + LAC(0000h) + CID(0000000h) и RSSI = -50:
#BS:000:000:0000:0000000#-50


+ Поля mac1..macN - уникальные метрики датчиков подключенных к прибору

Предназначены для идентификации датчиков и привязки их показаний к приборам.
Регистрация всех датчиков, подключенных к прибору, происходит автоматически при первой отправке их показаний на narodmon.ru.
Для датчиков температуры семейства DS18x20 метрика(серийный номер) представляет собой 16 знаков 0-F.
Для прочих датчиков рекомендуется использовать следующие метрики для автоматического определения типа данных (* - любое число):

* Температура: T\d+, TEMP*, BMPT*, DHTT*, DSW*, DS18T*, BATTEMP
* Влажность: H\d+, RH, RH*, DHTH*, HUM, HUMID*
* Давление: BMPP*, MMHG, HPA, PRESS, BAROM*
* Осадки: RAIN, RAIN*
* Скорость(ветер): WS, WS*, *KMH, *MPH, *SPD, WIND
* Азимут(направление): *DEG, *DIR
* Напряжение: U*, V*, VOLT, VCC, UACC, VBAT, BATVOLT
* Сила тока: I*
* Мощность: P, P*, W, W*
* Электроэнергия: WH, KWH, WH*, KWH*
* Водосчетчики: WM, WM* (ХВС=CWM, ГВС=HWM)
* Освещенность: L*, LUX, LIGHT
* Радиация: R*, RAD
* Логический(реле): S*, RL*, GPIO*, OUTPUT*, SIM*, RELAY
* Сетевой трафик: RX, TX, RX*, TX*
* Концентрация: CO, CO2, CO*, CH4, PPM
* Время(работы): NOW, TIME, UPTIME, CURTIME, WORKTIME
* Сигнал(уровень): DBM, RSSI, WIFI, GSM, SIGNAL
* Индекс УФ: UV, UV*
* Заряд батареи: MB2BAT, BATCHARGE
* Пыль(частицы): PM, PM*, DUST, SDS_P*
* Точка росы: DP, DP*, DEW
* Местоположение: LAT, LON, ALT (широта, долгота, высота) размещения датчиков.

Можно указать в качестве метрики название датчика на латинице без пробелов и знаков, но в этом случае тип данных придется указать вручную в разделе Датчики \ Настройка.

TCP/UDP:
#MAC
#T1#00.00
...
##

GET/POST:
ID=MAC&T1=00.00&...

+ Поля value1..valueN - показания датчиков с точностью до сотых долей

Крайне не рекомендуется округлять показания дабы не получать ложные уведомления выходе из строя датчика и график показаний был более читабельным, дискретность у DS18B20 = 0.0625С

Десятичное значение со знаком с точностью до 0.01. Дробная часть отделяется точкой, хотя запятая тоже допускается. Пример показания: -13.54 или -13,54 или 760 (для атм.давления).

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

Сетевой трафик SNMP можно передавать как в Мбит/сек (Mbps) так и накопительный итог в байтах(октетах) выбрав тип датчика трафик, Rx/Tx будет автоматически пересчитан в Mbps.

TCP/UDP:
#MAC
#T1#00.00
...
##

GET/POST:
ID=MAC&T1=00.00&...

+ Поля time1..timeN - время актуальности показаний

Если показания датчиков передаются сразу после замера, то данный параметр передавать не нужно!
Необязательное к передаче целочисленное значение UnixTime или по стандарту ISO 8601.
Пример: 1438772570 или 2015-08-05T14:03:11+03:00 или в hex виде 55C1ED5A (для экономии).
При передаче UnixTime НЕ НАДО прибавлять свой часовой пояс, т.к. оно всегда по UTC+0.
Местное время передавать "как есть" НЕЛЬЗЯ ибо у сервера часовой пояс Europe/Moscow.
Время снятия показаний нужно передавать только в случае их кеширования перед отправкой или при массовой выгрузке показаний датчиков.

TCP/UDP:
#MAC
#T1#00.00#1733366743
...
##

GET/POST:
ID=MAC&T1=00.00&TIME=1733366743&...

+ Поля name1..nameN - названия датчиков

Необязательное к передаче название датчика в кодировке UTF-8 или Windows-1251 по факту переименования однократно. Передается только в TCP/UDP после показания датчика и timeN(если указано).
Рекомендуется для приборов с веб-интерфейсом или с утилитой конфигурации, в которых можно указать названия датчиков. В случае, если данный параметр не пустая строка и не является временем, то название датчика на сервере меняется на полученное от прибора.

TCP/UDP:
#MAC
#T1#00.00#ИмяДатчика
...
##


+ Передача показаний по протоколам TCP/UDP на narodmon.ru:8283

Если Ваш прибор допускает только ввод IP адреса или у Вас проблемы с DNS, то используйте любой IP из списка nslookup narodmon.ru до которого у Вас наименьший ping, но помните, что IP-адрес сервера может сменится, а DNS-имя - нет. TCP также можно использовать для массовой загрузки показаний на сервер "задним числом" путем передачи в одном пакете данных показаний датчика в разные моменты времени, но не более 4КБ на пакет для TCP и 512 байт для UDP. Предпочтительно отправлять показания всех датчиков в одном пакете данных для минимизации издержек на инициализацию соединения с сервером и импорт показаний датчиков.
Ответ сервера при успешной отправке будет OK (или текст ошибки или команда на исполнение), что рекомендуется использовать в качестве подтверждения получения данных, а при отсутствии ответа повторить отправку когда восстановится связь с сервером. При сообщениях об ошибках НЕ ПОВТОРЯТЬ!
Конец строки ответа сервера завершается спецсимволом \n код 10(0A). Для оперативного отслеживания состояния логических входов и выходов рекомендуется в ответ на получение команды от сервера возвращать новое состояние логических датчиков в уже открытый ранее сокет согласно протоколу, но только в случае изменений дабы не получить ошибку малого интервала показаний.
При использовании протокола UDP ответа сервера не последует.


Три датчика реалтайм:
#53-56-72-CE-C3-F1
#T1#-29.04
#H1#64
#P1#704.43
##
Формат пакета данных:
#MAC[#NAME]\n
#mac1#value1[#time1][#name1]\n
...
#macN#valueN[#timeN][#nameN]\n
##
Загрузка истории показаний:
#53-56-72-CE-C3-F1
#T1#-29.04#1733366743
#T1#29.52#1733366143
#T1#29.99#1733365543
##
C названием и координатами:
#53-56-72-CE-C3-F1#Метео
#OWNER#неизвестен
#T1#-29.04#Улица
#T2#29.99#Дом
#P1#704.43#Барометр
#LAT#39.962502
#LON#-83.006104
#ALT#177
##

\n - спецсимвол конца строки - код 10(0A).
## - признак окончания пакета данных (после него разрыв соединения), в [..] заключен необязательный параметр.

+ Пример передачи показаний по TCP на PHP

$fp = @fsockopen("tcp://narodmon.ru", 8283, $errno, $errstr);
if(!$fp) exit("ERROR(".$errno."): ".$errstr);
fwrite($fp, "#53-56-72-CE-C3-F1\n#T1#-29.04\n#H1#64\n#P1#704.43\n##");
fclose($fp);

+ Пример передачи показаний по TCP на Bash

#!/bin/bash
# by Tuinov Andrey voytmar @ yandex.ru

SERVER="narodmon.ru"
PORT="8283"

# MAC адрес прибора. Заменить на свой!
DEVICE_MAC="A0B1C2D3E4F5"

# идентификатор прибора, для простоты добавляется 01 (02) к MAC прибора
SENSOR_ID_1=$DEVICE_MAC"01"
SENSOR_ID_2=$DEVICE_MAC"02"

# значения датчиков
sensor_value_1=20
sensor_value_2=-20.25

# устанавливаем соединение
exec 3<>/dev/tcp/$SERVER/$PORT

# отсылаем единичное значение датчика
printf "#%s\n#%s#%s\n##" "$DEVICE_MAC" "$SENSOR_ID_1" "$sensor_value_1" >&3

# отсылаем множественные значения датчиков
#printf "#%s\n#%s#%s\n#%s#%s\n##" "$DEVICE_MAC" "$SENSOR_ID_1" "$sensor_value_1" "$SENSOR_ID_2" "$sensor_value_2" >&3

# получаем ответ
read -r MSG_IN <&3
echo "$MSG_IN"

# закрываем соединение
exec 3<&-
exec 3>&-

+ Пример передачи показаний по TCP на Python2

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
# by Roman Vishnevsky aka.x0x01 @ gmail.com

import socket

# MAC адрес прибора. Заменить на свой!
DEVICE_MAC = 'A0B1C2D3E4F5'

# идентификатор прибора, для простоты добавляется 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))

+ Пример передачи показаний по TCP на Python3 для Domoticz

# Скрипт с помощью модуля Питона request и запроса json запрашивает
# данные избранного датчика у Domoticz и отправляет часть из них на
# сервис Народный мониторинг (narodmon.ru)
# Авторы tudimon, bigmak, Maker39 @ 4PDA

# подключаем модули
import requests
import socket

ip = '127.0.0.1' # ip-адрес Domoticz
port = '433' # порт
user = 'dz_user' # пользователь Dz
password = 'dz_user_password' # пароль пользователя
idx = 66 # номер датчика в Domoticz, который будем опрашивать

# Строка запроса если нужна авторизация
#get_url = 'http://'+user+':'+password+'@'+ip+':'+port+'/json.htm?type=devices&rid={}'.format(idx)

# Строка запроса если не нужна авторизация
# в случае если скрипт выполняется на том же приборе что и Dz и в
# Настройки - Настройки - Система
# Локальные сети (без имени/пароля) указан ip адрес
get_url = 'https://'+ip+'/json.htm?type=devices&rid={}'.format(idx)

# раскомментировать если нужно строку вывести в консоль для контроля
#print ('================================')
#print (get_url)
#print ('================================')

# запрос данных избранного датчика
get_data = requests.get(get_url, verify=False).json()

# ключ verify=False пришлось добавить потому что у меня Dz работает только на 433 порту
# а SSL сертификат самоподписанный, соответственно request ругался на ошибку сертификата

# ответ придет в виде JSON, где необходимо выбрать интересующее поле,
# например температура, влажность и уровень заряда батарейки

humidity = get_data['result'][0]['Humidity']
temperature = get_data['result'][0]['Temp']
batt_level = get_data['result'][0]['BatteryLevel']

#Выведем данные в консоль pi
# когда скрипт отлажен, следующие три строки необходимо закомментировать
print ("Влажность " + str(humidity))
print ("Температура " + str(temperature))
print ("Заряд батарейки " + str(batt_level))

# ============== передача данных в сервис narodmon ==================

# MAC адрес прибора. Заменить на свой!
DEVICE_MAC = 'ffffffffffffff' # MAC dz Raspberry Pi

# идентификатор прибора
SENSOR_ID_1 = 'dz_t'
SENSOR_ID_2 = 'dz_h'

# значения датчиков, тип float/integer
sensor_value_1 = temperature
sensor_value_2 = humidity

# создание сокета
sock = socket.socket()

# обработчик исключений
try:
# подключаемся к сокету
sock.connect(('narodmon.ru', 8283))

# формируем строку для сокета при единичном значении датчика
#s_sock = ("#{}\n#{}#{}\n##".format(DEVICE_MAC, SENSOR_ID_1, sensor_value_1))

# формируем строку для сокета при множественном значение датчиков
s_sock = ("#{}\n#{}#{}\n#{}#{}\n##".format(DEVICE_MAC, SENSOR_ID_1, sensor_value_1, SENSOR_ID_2, sensor_value_2))

# Пишем строку с консоль для контроля
# эти три строки после отладки закомментировать
print('======================================')
print(s_sock)
print('======================================')

# Пишем в сокет
sock.send(s_sock.encode('utf8'))

# читаем ответ
data = sock.recv(1024)
sock.close()
except socket.error as e:
print('ERROR! Exception {}'.format(e))


+ Передача показаний по протоколу HTTP GET/POST на http(s)://narodmon.ru/get (/post) и TLS шифрование

Рекомендуется использовать только в случае, если доступ в Интернет осуществляется через прокси-сервер, т.к. возможны проблемы с кеширующими прокси и выше риск перехвата / подмены данных без шифрования, а также увеличивается время обработки данных в "часы пик" из-за большого числа посетителей сайта и мобильных клиентов, что практически никак не влияет на наш протокол TCP/UDP (описанный выше). Максимальная длина запроса до 4КБайт (4096 знаков).
Предпочтительно отправлять показания всех датчиков в 1 запросе для минимизации издержек на инициализацию соединения и обработку показаний.

Ответ сервера при успешной отправке будет OK (или текст ошибки), что рекомендуется использовать в качестве подтверждения получения данных, а при отсутствии ответа повторить отправку когда восстановится связь с сервером. При сообщениях об ошибках НЕ ПОВТОРЯТЬ!

Шифрование: если Вы подозреваете, что враги хотят перехватить/подделать показания ваших датчиков, то следует использовать в строке адреса https://narodmon.ru/post и передавать данные с TLS шифрованием (SSL устарел).

+ Образец запроса передачи показаний методом HTTP GET

Следует знать, что это самый простой способ для новичков, но небезопасный и ненадежный в плане легкости перехвата/подделки данных без шифрования и зависимости от нагрузки на веб-сайт проекта и API для приложений. Максимальная длина запроса 2 КБайт (2048 знаков).
Для включения TLS шифрования используйте адрес https://narodmon.ru/get?...

http://narodmon.ru/get?ID=MAC&mac1=value1&...&macN=valueN[&time=UnixTime][&name=название][&owner=владелец][&lat=широта][&lon=долгота][&alt=высота_над_морем]

+ Образец запроса передачи показаний методом HTTP POST

Следует знать, что надежность данного метода зависит от нагрузки на веб-сайт проекта и API для приложений в отличии от TCP, UDP и MQTT.
Максимальная длина запроса до 4 КБайт (4096 знаков). Для включения TLS шифрования используйте адрес https://narodmon.ru/post

POST http://narodmon.ru/post HTTP/1.0\r\n
Host: narodmon.ru\r\n
Content-Type: application/x-www-form-urlencoded\r\n
Content-Length: NN(кол-во байт в строке данных ниже)\r\n
\r\n
ID=MAC&mac1=value1&...&macN=valueN[&time=UnixTime][&name=название][&owner=владелец][&lat=широта][&lon=долгота][&alt=высота_над_морем]

+ Пример передачи показаний по HTTP POST на Python2

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
# by Roman Vishnevsky aka.x0x01 @ gmail.com

import urllib2
import urllib

# MAC адрес прибора. Заменить на свой!
DEVICE_MAC = 'A0B1C2D3E4F5'

# идентификатор прибора, для простоты добавляется 01 (02) к mac прибора
SENSOR_ID_1 = DEVICE_MAC + '01'
SENSOR_ID_2 = DEVICE_MAC + '02'

# значения датчиков, тип float/integer
sensor_value_1 = 28
sensor_value_2 = -12.34

# формирование POST запроса для единичного датчика
data = urllib.urlencode({
'ID': DEVICE_MAC,
SENSOR_ID_1: sensor_value_1
})

# формирование POST запроса для 2х датчиков
# data = urllib.urlencode({
# 'ID': DEVICE_MAC,
# SENSOR_ID_1: sensor_value_1,
# SENSOR_ID_2: sensor_value_2
# })


# формирование заголовков запроса
headers = {
'Content-Length': str(len(data)),
'Content-Type': 'application/x-www-form-urlencoded',
'Host': 'narodmon.ru'
}

# непосредственно запрос
request = urllib2.Request('http://narodmon.ru/post.php', data, headers)
response = urllib2.urlopen(request)
print response.headers

+ Пример передачи показаний по HTTP POST на PHP с cURL

$data = array('ID'=>'53-56-72-CE-C3-F1', 'T1'=>-29.04, 'H1'=>64, 'P1'=>704.43);
$ch = curl_init("http://narodmon.ru/post");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
$reply = curl_exec($ch);
curl_close($ch);

+ Пример передачи показаний по HTTP POST на PHP без cURL

$data = array('ID'=>53-56-72-CE-C3-F1, 'T1'=>-29.04, 'H1'=>64, 'P1'=>704.43);
$context = stream_context_create(array('http' => array('method'=>'POST','content' => http_build_query($data))));
$fp = @fopen("http://narodmon.ru/post", 'r', false, $context);
if($fp) { fpassthru($fp); fclose($fp); }


+ Передача показаний в формате JSON протоколами TCP/UDP narodmon.ru:8283 или http(s)://narodmon.ru/json

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

Передавать пакет данных можно как по протоколам TCP или UDP на порт narodmon.ru:8283, так и использоваться HTTP(S) POST с шифрованием TLS или без него на http(s)://narodmon.ru/json. Ограничения по размеру пакета аналогичное другим способам передачи: 4 КБайт (для UDP 512 байт из-за MTU).

Ответ сервера при успешной отправке, ошибке или при получении команд тоже будет в формате JSON, что рекомендуется использовать в качестве подтверждения получения данных, т.е. при отсутствии ответа от сервера повторить отправку когда восстановится связь. При сообщениях об ошибках НЕ ПОВТОРЯТЬ!

Примеры ответов сервера:
{"error":"OK","errno":200} - данные успешно получены, ошибок нет;
{"error":"INTERVAL < 1 min","errno":429} - слишком частая отправка данных;
{"error":"JSON_ERROR_SYNTAX","errno":400} - данные получены, но в них была ошибка.

+ Формат передаваемых данных JSON

Ниже приведен пример развернутой структуры пакета JSON со всеми возможными параметрами при передаче показаний датчиков (для экономии трафика можно записать все в 1 строку и удалить лишние пробелы). Обязательные параметры выделены жирным, остальные опциональные и их рекомендуем слать только при их изменении. После // указаны комментарии к параметрам, отправлять их на сервер разумеется не нужно.

{
  "devices": [
    {
      "mac": "DEVICE_MAC", // уникальный для проекта серийный номер прибора;
      "name": "DEVICE NAME", // название прибора в кодировке UTF-8;
      "owner": "USERNAME", // логин или email или сотовый владельца прибора для авторегистрации;
      "lat": 39.962502, // широта места установки прибора;
      "lon": -83.006104, // долгота места установки прибора;
      "alt": 68, // высота над уровнем моря места установки прибора;
      "sensors": [
        {
          "id": "T1", // метрика датчика, уникальная для прибора;
          "name": "SENSOR NAME", // название датчика в кодировке UTF-8;
          "value": 00.00, // показание датчика;
          "unit": "C", // единица измерения для датчика в UTF-8;
          "time": 1733366743 // время актуальности показания датчика UnixTime (UTC+0);
        },
        {
         // прочие датчики на приборе
        }
      ]
    },
    {
    // прочие приборы
    }
  ]
}

+ Образец передачи показаний в JSON методом HTTP POST

Максимальная длина запроса до 4 КБайт (4096 знаков).
Для включения TLS шифрования используйте адрес https://narodmon.ru/json

POST http://narodmon.ru/json HTTP/1.0\r\n
Host: narodmon.ru\r\n
Content-Type: application/x-www-form-urlencoded\r\n
Content-Length: NN(кол-во байт в строке данных ниже)\r\n
\r\n
{ "devices": [{ "mac": "MAC", "sensors": [{ "id": "..", "value": 00.00 }, {..} ]}, {..} ]}


+ Передача показаний в формате InfluxDB по протоколу HTTP POST на http(s)://narodmon.ru/post

Данный вариант передачи показаний является расширением протокола HTTP POST для прошивок приборов с поддержкой временных рядов InfluxDB, например luftdaten.info для измерения качества воздуха (кол-во частиц пыли).

В качестве ID/MAC для регистрации прибора в проекте следует использовать значение узла node.

Пример формата (набор метрик датчиков может отличаться):
device,node=MAC SDS_P1=15.55,SDS_P2=6.57,BME280_temperature=6.37,BME280_pressure=99535.03,BME280_humidity=40.34,interval=300000,signal=-44

PS С подробным описанием процедуры подключения приборов с прошивкой luftdaten.info к нашему проекту вы можете ознакомиться в статье Алексея Надёжина (ammo1) за что ему огромное спасибо!


+ Передача показаний по протоколу MQTT на narodmon.ru:1883 (бесплатно с ограничениями)

При бесплатном использовании сервер не будет поддерживать постоянные (keep-alive) соединения, т.е. будет постоянно сбрасывать подключение после приема пакета данных.

Данный способ передачи показаний достаточно сложен в реализации и требует более высокий уровень технической подготовки. Консультации и обучение по работе с ним не проводятся и при возникновении проблем с его использованием лучше перейдите на более простые протоколы описанные выше. Использование данного протокола оправдывает себя только со сложными устройствами с обратной связью, где требуется немедленная реакция на команды с сервера.

MQTT (Message Queuing Telemetry Transport) – открытый протокол, разработанный IBM специально для Интернета вещей и применяется для обмена данными между приборами. MQTT-сеть включает в себя MQTT-брокера, который служит посредником во взаимодействии MQTT-агентов – издателей и подписчиков. Издатели публикуют информацию, предназначенную для подписчиков. Подробное описание протокола изложено в спецификации MQTT Version 3.1.1.

MQTT является бинарным протоколом поверх TCP, что существенно сокращает объем передаваемых данных и крайне полезно в нестабильных низкоскоростных мобильных сетях. Кроме того, соединение с брокером(сервером) инициируется клиентским прибором, что позволяет работать и с "серыми" IP адресами (за NAT провайдера), при этом соединение с сервером как правило не разрывается (при стабильном канале), что позволяет максимально оперативно передавать показания датчиков и принимать команды на исполнение с сервера.

При настройке подключения по MQTT к нашему брокеру(серверу) следует указать хост narodmon.ru порт 1883. Интервал передачи показаний по умолчанию как и для других протоколов = 5 мин. При этом ваш прибор будет автоматически привязан к указанной вами учетной записи в проекте, если в CONNECT вы передали логин и пароль (или ваш код 0) в проекте. В случае, если в настройках своего прибора вы указали неверный логин/пароль, то ваш IP будет заблокирован на 15 минут, после чего вы сможете повторить попытку.

Поддерживаемые команды нашего MQTT-брокера:

CONNECT (код 1)
Подключение к серверу, необходимые параметры:
Client Identifier (ClientID) = MAC Вашего прибора
UserName = Ваш логин в проекте (если нужна автопривязка)
Password = Ваш пароль или ваш код 0 в проекте (если нужна автопривязка)

В ответ отправляется CONNACK (код 2) с результатом:
0 - подключение успешно;
2 - недопустимый MAC прибора (ClientID);
3 - технический сбой брокера / недоступность СУБД;
4 - неверный логин или пароль (если они передаются);
5 - в доступе отказано (например из-за неуплаты).

PUBLISH (код 3)
Публикация показаний датчиков, необходимые параметры:
Topic = логин/девайс/датчик (пример: username/devname/sensor1)
Value = показание датчика.
В ответ отправляется PUBACK (код 4) для QoS = 1 или PUBREC (код 5) для QoS = 2.

При использовании формата JSON:
Topic = логин/девайс/json (пример: username/devname/json)
Value = показания всех датчиков в одной строке (пример: {"sensor1":1,"sensor2":2}).

PUBACK (код 4)
Подтверждение приема данных клиентом с QoS = 1 после команды PUBLISH (код 3) с сервера.

PUBREL (код 6)
Подтверждение приема данных клиентом с QoS = 2, ответ на PUBREC (код 5).
В ответ отправляется PUBCOMP (код 7).

SUBSCRIBE (код 8)
Подписка на топики, команды UI и REST API.
В ответ отправляется SUBACK (код 9).
Если вам нужна отработка подписки на топики других приборов или иных событий, то для рассмотрения возможности её внедрения пишите в техподдержку проекта с подробным описанием вашего информационного обмена по MQTT и желаемого функционала нашего брокера.

UNSUBSCRIBE (код 10)
Отписка от топиков. Нет действий.
В ответ отправляется UNSUBACK (код 11).

PINGREQ (код 12)
Проверка активности клиента/сервера.
В ответ отправляется PINGRESP (код 13).

DISCONNECT (тип 14)
Завершение сеанса с сервером, параметры не требуются.