Обновление от :
- 23/03/2022 — 22 марта 2022 г. встроенная в CCU функция интеграции с narodmon.ru перестала работать (произошёл какой-то конфликт между narodmon.ru и RADS Electronics). Но интеграция с narodmon.ru, описанная в данной статье, продолжает работать.
- 17/01/2020 — В прошивке 2.22 появилась поддержка прямой работы с сервисом «Народный мониторинг»
- 26/05/2019 — Сделал округление температуры до сотых. Нужно для сервиса «Народный мониторинг»
- 15/07/2018 — Начиная с версии прошивки 2.17 для контроллера CCU, изменился формат JSON ответа с уровнями сигнала сотовой связи. Обновил скрипт для совместимости с новой прошивкой.
- 14/04/2018 — Добавлено отображение на графике значения уровня сигнала сотовой сети в dBm
- 14/03/2018 — Доработан скрипт для получения значения уровня сигнала сотовой сети
- 21/06/2017 — Интересный график измерения 220В
- 30/04/2016 — Добавлено описание интеграции с сервисом «Народный мониторинг»
Статья также опубликована на сайте: https://2keep.net/gsm_ccu825_json
В процессе эксплуатации GSM контроллера CCU825 возникали похожие вопросы: как можно из внешних приложений управлять GSM контроллером CCU, получать с него данные, строить графики и т.д и т.п.
С выходом прошивки версии 2 такая возможность появилась. Во второй версии прошивки, реализовали текстовый формат обмена данными JSON API как раз для таких задач.
В данной статье, будет описан процесс получения данных с входов контроллера для построения графиков температуры, напряжения в сети, заряда аккумулятора и т.д.
Данная статья не очень сочетается с тематикой данного сайта и больше посвящена программированию, но возможно она кого-то подтолкнёт к изучению чего-то нового и полезного.
Прошу воспринимать ниже приведенные скрипты как пример реализации, а не законченное решение, т.к. я не являюсь профессиональным программистом.
Что такое JSON
JSON (JavaScript Object Notation) — простой формат обмена данными, удобный для чтения и написания как человеком, так и компьютером. Он основан на подмножестве языка программирования JavaScript … JSON — текстовый формат, полностью независимый от языка реализации, но он использует соглашения, знакомые программистам C-подобных языков, таких как C, C++, C#, Java, JavaScript, Perl, Python и многих других. Эти свойства делают JSON идеальным языком обмена данными.
Используя JSON, можно легко организовать передачу данных между приложениям и серверами, а это как раз то, что нам и нужно.
Схема работы CCU825 с сервером ccu.sh
- GSM контроллер CCU825 (1), через GSM GPRS (2) и далее Интернет, используя закрытый протокол (3), организует двухсторонний канал передачи данных до сервера ccu.sh (4).
- На сервере ccu.sh (3) поднят HTTP(S) сервер, который обеспечивает следующие функции:
- удалённое управления контроллером CCU825 через WEB интерфейс (для CCU825 публичный IP не нужен),
- организация взаимодействия с внешними (вашими) приложениям через JSON API.
- Для взаимодействия с сервером ccu.sh через JSON (5), запускаем на нашем сервере (6) скрипты, которые будут приведены ниже.
- На основе полученных через JSON данных, строим графики (7).
Подробнее про роль сервера ccu.sh
Теперь, когда стала понятна общая схема работы, слегка опишу как работает сервер ccu.sh (это моё предположение основанное на опыте).
Сервер ccu.sh выполняет функцию прокси сервера (посредника) между нами, находящимися где-то в Интернете и GSM контроллером, который так же, не известно где подключен к Интернет через GSM GPRS и скорей всего, у него нет публичного IP адреса, что не даёт возможности получить к контроллеру прямой доступ.
Упрощенный принцип работы
- При включении CCU825 и доступности GPRS (и если указано в настройках), контроллер инициализирует исходящее соединение к серверу (1) для организации с сервером ccu.sh двухстороннего канала передачи данных (2).
- Тут важно заметить, что именно контроллер начинает исходящее соединение в сторону сервера ccu.sh у которого заранее известен публичный адрес (в отличии от контроллера). Любой контроллер, через Интернет, не имея публичного адреса, может к нему подключиться пройдя процедуру аутентификации.
- После прохождения всех процедур установления двухстороннего канала передачи данных (2), у сервера ccu.sh появляется возможность управлять контроллером. В дальнейшем, для управления контроллером CCU, мы взаимодействием с сервером ccu.sh, а он, уже с контроллером (как говорил выше — функция прокси сервера).
- С нашего сервера, мы отправляем JSON запрос (3) к серверу ccu.sh.
- Сервер ccu.sh, преобразует JSON запрос в свой закрытый протокол и по ранее организованному двухстороннему каналу (2) отправляет запрос (4) на CCU контроллер.
- Контроллер CCU, обработав запрос (4), возвращает на сервер ccu.sh ответ (5) с запрошенными данными.
- Сервер ccu.sh преобразует полученный ответ в JSON формат и уже в JSON формате отдаёт (6) его нашему серверу.
- Наш сервер, используя скрипты, парсит (извлекает данные) полученный JSON ответ (6) и строит графики или, если заложено логикой скрипта, отправляет какую либо команду на контроллер CCU (например для включения реле).
Подготовка рабочего окружения
Основной акцент в описании я буду делать на работу с JSON в PHP. На остальных аспектах, таких как установка и настройка Apache, PHP, rrdtool и т.д. я акцентировать своё внимание не буду и предполагаю, что они у вас установлены и работают.
И так, что необходимо для работы:
- CentOS 7 (или другой Linux дистрибутив, но могут быть небольшие отличия в работе)
- Apache — HTTP сервер
- PHP — язык программирования
- RRDtool — средство построения графиков
Работа с JSON
Описание протокола интеграции контроллера CCU в стороннее ПО (JSON API): https://radsel.ru/files/docs/ext-manual/ext-manual.html
JSON запрос
У нас будет простая задача, отправить запрос на контроллер и получить от него ответ о его полном состоянии (входы/выходы, баланс, аккумулятор и т.д.).
Из документации приведенной выше, мы видим, что запрос должен выглядеть следующим образом:
https://ccu.sh/data.cgx?cmd={"Command":"GetStateAndEvents"}
В запросе нужно учесть базовую HTTP-аутентификацию.
JSON ответ
Ответ на выше приведённый запрос будет следующим:
{"Inputs":[{"Active":0,"Voltage":1063},{"Active":0,"Voltage":1031},{"Active":0,"Voltage":2096},{"Active":0,"Voltage":2102},{"Active":0,"Voltage":2103},{"Active":0,"Voltage":4095},{"Active":0,"Voltage":4095},{"Active":0,"Voltage":0}],"Outputs":[0,0,0,0,0,0,0],"Partitions":["Protect"],"Battery":{"Charge":100,"State":"OK"},"Case":0,"Power":15.3,"Temp":11,"Balance":22.50}
Ниже приведенный скрипт будет извлекать необходимые нам данные из выше приведённого ответа и преобразовать значения входов контроллера в нужные нам значения (по JSON запросу, отдаётся не напряжение на входе контроллера, а значение в дискретах).
Скрипт работы с JSON
Выше приведённый JSON ответ, скрипт, используя функцию json_decode преобразует в массив, а дальше уже всё просто.
Результат работы функции json-decode:
Array ( [Inputs] => Array ( [0] => Array ( [Active] => 0 [Voltage] => 1063 ) [1] => Array ( [Active] => 0 [Voltage] => 1031 ) [2] => Array ( [Active] => 0 [Voltage] => 2096 ) [3] => Array ( [Active] => 0 [Voltage] => 2102 ) [4] => Array ( [Active] => 0 [Voltage] => 2103 ) [5] => Array ( [Active] => 0 [Voltage] => 4095 ) [6] => Array ( [Active] => 0 [Voltage] => 4095 ) [7] => Array ( [Active] => 0 [Voltage] => 0 ) ) [Outputs] => Array ( [0] => 0 [1] => 0 [2] => 0 [3] => 0 [4] => 0 [5] => 0 [6] => 0 ) [Partitions] => Array ( [0] => Protect ) [Battery] => Array ( [Charge] => 100 [State] => OK ) [Case] => 0 [Power] => 15.3 [Temp] => 11 [Balance] => 22.5 )
Теперь, стандартными средствами PHP, извлекаем значения массива и работам с ними.
Код скрипта
Скрипт для CCU прошивки 2.17 и старше.
<?php # Имя пользователя для доступа к серверу ccu.sh. # Имя должно быть введено в формате user@IMEI. # IMEI должен состоять из 15 десятичных цифр и совпадать с IMEI контроллера. $jsonUser = "name@IMEI"; # Пароль для доступа к серверу ccu.sh $jsonPass = "password"; # Функция HTTP Basic аутентификации и обращения к JSON. function http_auth_get($url,$username,$password){ $cred = sprintf('Authorization: Basic %s', base64_encode("$username:$password")); $opts = array('http'=>array('method'=>'GET','header'=>$cred)); $ctx = stream_context_create($opts); $handle = fopen ( $url, 'r', false,$ctx); return stream_get_contents($handle); } $json = http_auth_get('https://ccu.sh/data.cgx?cmd={"Command":"GetStateAndEvents"}',$jsonUser,$jsonPass); $obj = json_decode($json, TRUE); # Делаем второй запрос JSON для получения уровня сигнала сотовой сети $jsonSignal = http_auth_get('https://ccu.sh/data.cgx?cmd={"DataType":"ControlPoll"}',$jsonUser,$jsonPass); $objSignal = json_decode($jsonSignal, TRUE); # Если массив пустой (нет связи с контроллером) тогда выжидаем паузу в 10 секунд и делаем ещё запрос (бывает, что из-за плохого GPRS, контроллер не может ответить с первого раза). if( empty($obj) ) { echo "\nНет связи с контроллером!\n\n"; echo "\nВторая попытка JSON запроса. Пауза 10 сек.\n\n"; sleep(10); $json = http_auth_get('https://ccu.sh/data.cgx?cmd={"Command":"GetStateAndEvents"}',$jsonUser,$jsonPass); $obj = json_decode($json, TRUE); } if( empty($objSignal) ) { echo "\nНет связи с контроллером!\n\n"; echo "\nВторая попытка JSON запроса. Пауза 10 сек.\n\n"; sleep(10); $jsonSignal = http_auth_get('https://ccu.sh/data.cgx?cmd={"DataType":"ControlPoll"}',$jsonUser,$jsonPass); $objSignal = json_decode($jsonSignal, TRUE); } # Если ЕСТЬ связь с контроллером (массив непустой), то обрабатываем массив полученный из JSON. if( !empty($obj) ) { # Извлекам данные из массива. $input = $obj['Inputs']; # Вход 1. Датчик RTD-03, температура в помещении. $input1 = $input['0']; # Преобразуем дискреты на входе контроллера в напряжение. $inputVoltage1 = $input1['Voltage']*10/4095; # Используя формулу из uGuard преобразуем напряжение в градусы и округляем до десятых. $inputVoltageRtd1 = round(($inputVoltage1/5-0.5)/0.01,2); # Вход 2. Датчик RTD-03, температура на улице. $input2 = $input['1']; # Преобразуем дискреты на входе контроллера в напряжение. $inputVoltage2 = $input2['Voltage']*10/4095; # Используя формулу из uGuard преобразуем напряжение в градусы и округляем до десятых. $inputVoltageRtd2 = round(($inputVoltage2/5-0.5)/0.01,2); # Вход 8. Вольтметр. Измерение напряжение в сети (220В). $input8 = $input['7']; # Преобразуем дискреты на входе контроллера в напряжение. $inputVoltage8 = $input8['Voltage']*10/4095; # Используя заранее высчитанный коэффициент (в моём случае 29,6) высчитываем напряжение и округляем до целого числа. $inputVoltageVolt8 = round($inputVoltage8*29.6,0); # Заряд аккумулятора. $battery = $obj['Battery']; $batteryCharge = $battery['Charge']; # Температура CCU. $ccuTemp = round($obj['Temp'],1); # Напряжение питания CCU. $ccuVolt = round($obj['Power'],1); # Баланс на SIM карте. $ccuBalance = $obj['Balance']; # Файл состояние соединения CCU через GPRS с сервером ccu.sh # Записываем пустой файл. Если файл пустой, то соединение есть. # Укажите свой путь к файлу! $fd = fopen("/srv/www/your.site/public_html/ccu/ccujson_gprs_status.txt", 'w') or die("не удалось создать файл"); $str = ""; fwrite($fd, $str); fclose($fd); } else { # Если нет связи с контроллером (массив пустой), то все переменные обнуляем. $inputVoltageRtd1 = 0; $inputVoltageRtd2 = 0; $inputVoltageVolt8 = 0; $batteryCharge = 0; $ccuTemp = 0; $ccuVolt = 0; $ccuBalance = 0; echo "\nНет связи с контроллером!\n\n"; # Файл состояние соединения CCU через GPRS с сервером ccu.sh # Записываем в файл информацию об отсутствии соединения. # Укажите свой путь к файлу! $fd = fopen("/srv/www/your.site/public_html/ccu/ccujson_gprs_status.txt", 'w') or die("не удалось создать файл"); $str = "<p style='font-size:20px; color: red'>Нет связи с контроллером CCU!</p>"; fwrite($fd, $str); fclose($fd); } # Если ЕСТЬ связь с контроллером (массив непустой), то обрабатываем массив полученный из JSON. # Получаем из массива значение уровня сигнала сети if( !empty($objSignal) ) { # Уровень сигнала модема $control = $objSignal['ControlPoll']; $signalLevel = $control['Signal']; $signal = $signalLevel['Percent']; $signalDbm = $signalLevel['dBm']; } else { # Если нет связи с контроллером (массив пустой), то все переменные обнуляем. $signal = 0; $signalDbm = 0; echo "\nНет связи с контроллером!\n\n"; # Файл состояние соединения CCU через GPRS с сервером ccu.sh # Записываем в файл информацию об отсутствии соединения. # Укажите свой путь к файлу! $fd = fopen("/srv/www/your.site/public_html/ccu/ccujson_gprs_status.txt", 'w') or die("не удалось создать файл"); $str = "<p style='font-size:20px; color: red'>Нет связи с контроллером CCU!</p>"; fwrite($fd, $str); fclose($fd); } # Отображение полученных значений (для диагностики проблем). echo "Температура: $inputVoltageRtd1:$inputVoltageRtd2:$ccuTemp \n"; echo "Напряжение: $inputVoltageVolt8:$ccuVolt \n"; echo "Баланс: $ccuBalance \n"; echo "Аккумулятор: $batteryCharge \n"; echo "Уровень сигнала сети (%): $signal \n"; echo "Уровень сигнала сети (dBm): $signalDbm \n"; # Записываем во временный файл значения температуры. В дальнейшем будем их использовать в другом скрипте для RRDtool. $fd = fopen("/tmp/ccujson_temp.txt", 'w') or die("не удалось создать файл"); $str = $inputVoltageRtd1.":".$inputVoltageRtd2.":".$ccuTemp; fwrite($fd, $str); fclose($fd); # Записываем во временный файл значения напряжения. В дальнейшем будем их использовать в другом скрипте для RRDtool. $fd = fopen("/tmp/ccujson_volt.txt", 'w') or die("не удалось создать файл"); $str = $inputVoltageVolt8.":".$ccuVolt; fwrite($fd, $str); fclose($fd); # Записываем во временный файл значения баланса. В дальнейшем будем их использовать в другом скрипте для RRDtool. $fd = fopen("/tmp/ccujson_balance.txt", 'w') or die("не удалось создать файл"); $str = $ccuBalance; fwrite($fd, $str); fclose($fd); # Записываем во временный файл значения заряда аккумулятора. В дальнейшем будем их использовать в другом скрипте для RRDtool. $fd = fopen("/tmp/ccujson_batterycharge.txt", 'w') or die("не удалось создать файл"); $str = $batteryCharge; fwrite($fd, $str); fclose($fd); # Записываем во временный файл значения уровня сигнала сотовой сети. В дальнейшем будем их использовать в другом скрипте для RRDtool. $fd = fopen("/tmp/ccujson_signal.txt", 'w') or die("не удалось создать файл"); $str = $signal.":".$signalDbm; fwrite($fd, $str); fclose($fd); ?>
В результате работы скрипта будут созданы следующие файлы:
- /tmp/ccujson_temp.txt — значение температур (улица, дом и контроллер)
- /tmp/ccujson_volt.txt — напряжение в сети
- /tmp/ccujson_balance.txt — баланс на SIM карте
- /tmp/ccujson_batterycharge.txt — заряд аккумулятора
- /tmp/ccujson_signal.txt — уровень сигнала сотовой сети
- /srv/www/your.site/public_html/ccujson_gprs_status.txt — состояние соединения CCU с сервером ccu.sh
Эти файлы будут использоваться в работе скрипта создания графиков.
Замечание на тему получения уровня сигнала сети
Информация акутальная для версии прошивки CCU 2.16 и ниже.
Начиная с версии 2.17 формат отображения уровня сигнала значительно упростился, нет необходимости ни чего расчитывать. Уровень сигнала в процентах и dBm, получаем сразу из JSON ответа контроллера.
Создание графиков
Для построения графиков будем использовать RRDtool.
Создание баз данных
Укажите свои пути к базам данных.
Хранение значений температуры
/usr/bin/rrdtool create /srv/www/your.site/public_html/rrd_base/temperature.rrd -s 300 \ DS:temp_inside:GAUGE:600:U:U \ DS:temp_outside:GAUGE:600:U:U \ DS:temp_ccu:GAUGE:600:U:U \ RRA:AVERAGE:0.5:1:288 \ RRA:AVERAGE:0.5:6:336 \ RRA:AVERAGE:0.5:24:372 \ RRA:AVERAGE:0.5:144:730 \ RRA:MIN:0.5:1:288 \ RRA:MIN:0.5:6:336: \ RRA:MIN:0.5:24:372 \ RRA:MIN:0.5:144:730 \ RRA:MAX:0.5:1:288 \ RRA:MAX:0.5:6:336 \ RRA:MAX:0.5:24:372 \ RRA:MAX:0.5:144:730 \ RRA:LAST:0.5:1:288
Хранение значений напряжения
/usr/bin/rrdtool create /srv/www/your.site/public_html/rrd_base/voltage.rrd -s 300 \ DS:volt_220:GAUGE:600:U:U \ DS:volt_ccu:GAUGE:600:U:U \ RRA:AVERAGE:0.5:1:288 \ RRA:AVERAGE:0.5:6:336 \ RRA:AVERAGE:0.5:24:372 \ RRA:AVERAGE:0.5:144:730 \ RRA:MIN:0.5:1:288 \ RRA:MIN:0.5:6:336: \ RRA:MIN:0.5:24:372 \ RRA:MIN:0.5:144:730 \ RRA:MAX:0.5:1:288 \ RRA:MAX:0.5:6:336 \ RRA:MAX:0.5:24:372 \ RRA:MAX:0.5:144:730 \ RRA:LAST:0.5:1:288
Хранение значений баланса
/usr/bin/rrdtool create /srv/www/your.site/public_html/rrd_base/balance.rrd -s 300 \ DS:balance:GAUGE:600:U:U \ RRA:AVERAGE:0.5:1:288 \ RRA:AVERAGE:0.5:6:336 \ RRA:AVERAGE:0.5:24:372 \ RRA:AVERAGE:0.5:144:730 \ RRA:MIN:0.5:1:288 \ RRA:MIN:0.5:6:336: \ RRA:MIN:0.5:24:372 \ RRA:MIN:0.5:144:730 \ RRA:MAX:0.5:1:288 \ RRA:MAX:0.5:6:336 \ RRA:MAX:0.5:24:372 \ RRA:MAX:0.5:144:730 \ RRA:LAST:0.5:1:288
Хранение значений заряда аккумулятора
/usr/bin/rrdtool create /srv/www/your.site/public_html/rrd_base/batterycharge.rrd -s 300 \ DS:batterycharge:GAUGE:600:U:U \ RRA:AVERAGE:0.5:1:288 \ RRA:AVERAGE:0.5:6:336 \ RRA:AVERAGE:0.5:24:372 \ RRA:AVERAGE:0.5:144:730 \ RRA:MIN:0.5:1:288 \ RRA:MIN:0.5:6:336: \ RRA:MIN:0.5:24:372 \ RRA:MIN:0.5:144:730 \ RRA:MAX:0.5:1:288 \ RRA:MAX:0.5:6:336 \ RRA:MAX:0.5:24:372 \ RRA:MAX:0.5:144:730 \ RRA:LAST:0.5:1:288
Хранение значений уровня сигнала сети
/usr/bin/rrdtool create /srv/www/your.site/public_html/rrd_base/signal.rrd -s 300 \ DS:signal:GAUGE:600:U:U \ DS:signalDbm:GAUGE:600:U:U \ RRA:AVERAGE:0.5:1:288 \ RRA:AVERAGE:0.5:6:336 \ RRA:AVERAGE:0.5:24:372 \ RRA:AVERAGE:0.5:144:730 \ RRA:MIN:0.5:1:288 \ RRA:MIN:0.5:6:336: \ RRA:MIN:0.5:24:372 \ RRA:MIN:0.5:144:730 \ RRA:MAX:0.5:1:288 \ RRA:MAX:0.5:6:336 \ RRA:MAX:0.5:24:372 \ RRA:MAX:0.5:144:730 \ RRA:LAST:0.5:1:288
Скрипт обновления баз данных и создания графиков
#/bin/bash # Укажите везде свои пути расположения баз данных, скриптов, графиков! # Запускам скрипт JSON опроса CCU и записи результатов во временные файлы tmp=$(php /home/ccujson/ccujson.php) echo $tmp LASTUPDATE=$(date +%d/%m/%Y%t%R:%S%t%Z) ############################################################# # START Уровень сигнала сотовой сети ############################################################# # Укажем к какой базе данных мы будем обращаться. BASE="/srv/www/your.site/public_html/rrd_base/signal.rrd" # Зададим папку, куда будем сохранять картинки с графиками. WWWPREFIX="/srv/www/your.site/public_html/ccu/signal" SIGNAL=$(cat /tmp/ccujson_signal.txt) echo $SIGNAL # Обновление БД #LC_ALL=C LANG=C /usr/bin/rrdtool update $BASE N:$SIGNAL # Создание графика (сутки) rrdtool graph $WWWPREFIX/signal.png \ --width 500 \ --height 200 \ --imgformat PNG \ --start -24h \ --end now \ --slope-mode \ --font-render-mode light \ --x-grid HOUR:1:HOUR:3:HOUR:3:0:"%R%n%d/%m" \ --units-exponent 0 \ --upper-limit 80 \ --lower-limit -115 \ --alt-autoscale-max \ --units-length 7 \ --vertical-label "Уровень сигнала GSM модема" \ --title "Уровень сигнала за 24 часа. Обновление $LASTUPDATE" \ DEF:signal=$BASE:signal:LAST \ DEF:signalDbm=$BASE:signalDbm:LAST \ COMMENT:"\s" \ COMMENT:"\s" \ HRULE:0#000000:"" \ AREA:-113#A1A1A1:"(-113 dBm) Нет сигнала" \ COMMENT:"\s" \ COMMENT:"\s" \ AREA:-105#FF5857:"(-105 dBm) Очень низкий уровень сигнала" \ COMMENT:"\s" \ COMMENT:"\s" \ AREA:-95#FDAB6D:"(-95 dBm) Низкий уровень сигнала" \ COMMENT:"\s" \ COMMENT:"\s" \ AREA:-85#E5FF94:"(-85 dBm) Средний уровень сигнала" \ COMMENT:"\s" \ COMMENT:"\s" \ AREA:-75#8FFF8F:"(-75 dBm) Высокий уровень сигнала" \ COMMENT:"\s" \ COMMENT:"\s" \ COMMENT:"\s" \ LINE3:signalDbm#021BAC:"Сигнал (dBm)" \ GPRINT:signalDbm:LAST:"Last %3.0lf " \ GPRINT:signalDbm:MAX:"Max %3.0lf " \ GPRINT:signalDbm:AVERAGE:"Avg %3.0lf " \ GPRINT:signalDbm:MIN:"Min %3.0lf \l" \ AREA:signal#FF9EFE: \ LINE1:signal#DB00DA:"Сигнал (%) " \ GPRINT:signal:LAST:"Last %3.0lf " \ GPRINT:signal:MAX:"Max %3.0lf " \ GPRINT:signal:AVERAGE:"Avg %3.0lf " \ GPRINT:signal:MIN:"Min %3.0lf \l" \ COMMENT:"\s" \ # Создание графика (неделя) rrdtool graph $WWWPREFIX/signal_week.png \ --width 500 \ --height 200 \ --imgformat PNG \ --start -168h \ --end now \ --slope-mode \ --font-render-mode light \ --x-grid HOUR:6:HOUR:12:HOUR:12:0:"%R%n%d/%m" \ --units-exponent 0 \ --upper-limit 80 \ --lower-limit -115 \ --alt-autoscale-max \ --units-length 7 \ --vertical-label "Уровень сигнала GSM модема" \ --title "Уровень сигнала за неделю. Обновление $LASTUPDATE" \ DEF:signal=$BASE:signal:LAST \ DEF:signalDbm=$BASE:signalDbm:LAST \ COMMENT:"\s" \ COMMENT:"\s" \ HRULE:0#000000:"" \ AREA:-113#A1A1A1:"(-113 dBm) Нет сигнала" \ COMMENT:"\s" \ COMMENT:"\s" \ AREA:-105#FF5857:"(-105 dBm) Очень низкий уровень сигнала" \ COMMENT:"\s" \ COMMENT:"\s" \ AREA:-95#FDAB6D:"(-95 dBm) Низкий уровень сигнала" \ COMMENT:"\s" \ COMMENT:"\s" \ AREA:-85#E5FF94:"(-85 dBm) Средний уровень сигнала" \ COMMENT:"\s" \ COMMENT:"\s" \ AREA:-75#8FFF8F:"(-75 dBm) Высокий уровень сигнала" \ COMMENT:"\s" \ COMMENT:"\s" \ COMMENT:"\s" \ LINE3:signalDbm#021BAC:"Сигнал (dBm)" \ GPRINT:signalDbm:LAST:"Last %3.0lf " \ GPRINT:signalDbm:MAX:"Max %3.0lf " \ GPRINT:signalDbm:AVERAGE:"Avg %3.0lf " \ GPRINT:signalDbm:MIN:"Min %3.0lf \l" \ AREA:signal#FF9EFE: \ LINE1:signal#DB00DA:"Сигнал (%) " \ GPRINT:signal:LAST:"Last %3.0lf " \ GPRINT:signal:MAX:"Max %3.0lf " \ GPRINT:signal:AVERAGE:"Avg %3.0lf " \ GPRINT:signal:MIN:"Min %3.0lf \l" \ COMMENT:"\s" \ ############################################################# # END Уровень сиганал сети ############################################################# ############################################################# # START Температура ############################################################# # Укажем к какой базе данных мы будем обращаться. BASE="/srv/www/your.site/public_html/rrd_base/temperature.rrd" # Зададим папку, куда будем сохранять картинки с графиками. WWWPREFIX="/srv/www/your.site/public_html/ccu/temperature" # Получаем значения из ранее созданных файлов скриптом ccujson.php TEMP=$(cat /tmp/ccujson_temp.txt) echo $TEMP # Обновление БД #LC_ALL=C LANG=C /usr/bin/rrdtool update $BASE N:$TEMP # Создание графика (сутки) rrdtool graph $WWWPREFIX/temperature.png \ --width 500 \ --height 200 \ --imgformat PNG \ --start -24h \ --end now \ --slope-mode \ --font-render-mode light \ --font DEFAULT:7:Tahoma \ --x-grid HOUR:1:HOUR:3:HOUR:3:0:"%R%n%d/%m" \ --units-exponent 0 \ --alt-autoscale-max \ --base 1000 \ --units-length 7 \ --vertical-label "Температура, C" \ --title "Температура за 24 часа. Обновление $LASTUPDATE" \ LINE1:0#FFFFFF \ DEF:temp_inside=$BASE:temp_inside:LAST \ DEF:temp_outside=$BASE:temp_outside:LAST \ DEF:temp_ccu=$BASE:temp_ccu:LAST \ COMMENT:"\s" \ COMMENT:"\s" \ LINE1:temp_inside#f61:"Дом " \ AREA:temp_inside#f915: \ GPRINT:temp_inside:LAST:"Last %3.3lf C " \ GPRINT:temp_inside:MAX:"Max %3.3lf C " \ GPRINT:temp_inside:AVERAGE:"Avg %3.3lf C " \ GPRINT:temp_inside:MIN:"Min %3.3lf C \l" \ COMMENT:"\s" \ LINE1:temp_outside#0d8:"Улица " \ AREA:temp_outside#0f85: \ GPRINT:temp_outside:LAST:"Last %3.3lf C " \ GPRINT:temp_outside:MAX:"Max %3.3lf C " \ GPRINT:temp_outside:AVERAGE:"Avg %3.3lf C " \ GPRINT:temp_outside:MIN:"Min %3.3lf C \l" \ COMMENT:"\s" \ LINE1:temp_ccu#2F16F3:"Контроллер " \ GPRINT:temp_ccu:LAST:"Last %3.3lf C " \ GPRINT:temp_ccu:MAX:"Max %3.3lf C " \ GPRINT:temp_ccu:AVERAGE:"Avg %3.3lf C " \ GPRINT:temp_ccu:MIN:"Min %3.3lf C \l" \ COMMENT:"\s" \ # Создание графика (неделя) rrdtool graph $WWWPREFIX/temperature_week.png \ --width 500 \ --height 200 \ --imgformat PNG \ --start -168h \ --end now \ --slope-mode \ --font-render-mode light \ --font DEFAULT:7:Tahoma \ --x-grid HOUR:6:HOUR:12:HOUR:12:0:"%R%n%d/%m" \ --units-exponent 0 \ --alt-autoscale-max \ --base 1000 \ --units-length 7 \ --vertical-label "Температура, C" \ --title "Температура за неделю. Обновление $LASTUPDATE" \ LINE1:0#FFFFFF \ DEF:temp_inside=$BASE:temp_inside:AVERAGE \ DEF:temp_outside=$BASE:temp_outside:AVERAGE \ DEF:temp_ccu=$BASE:temp_ccu:AVERAGE \ COMMENT:"\s" \ COMMENT:"\s" \ LINE1:temp_inside#f61:"Дом " \ AREA:temp_inside#f915: \ GPRINT:temp_inside:LAST:"Last %3.3lf C " \ GPRINT:temp_inside:MAX:"Max %3.3lf C " \ GPRINT:temp_inside:AVERAGE:"Avg %3.3lf C " \ GPRINT:temp_inside:MIN:"Min %3.3lf C \l" \ COMMENT:"\s" \ LINE1:temp_outside#0d8:"Улица " \ AREA:temp_outside#0f85: \ GPRINT:temp_outside:LAST:"Last %3.3lf C " \ GPRINT:temp_outside:MAX:"Max %3.3lf C " \ GPRINT:temp_outside:AVERAGE:"Avg %3.3lf C " \ GPRINT:temp_outside:MIN:"Min %3.3lf C \l" \ COMMENT:"\s" \ LINE1:temp_ccu#2F16F3:"Контроллер " \ GPRINT:temp_ccu:LAST:"Last %3.3lf C " \ GPRINT:temp_ccu:MAX:"Max %3.3lf C " \ GPRINT:temp_ccu:AVERAGE:"Avg %3.3lf C " \ GPRINT:temp_ccu:MIN:"Min %3.3lf C \l" \ COMMENT:"\s" \ ############################################################# # END Температура ############################################################# ############################################################# # START Напряжение ############################################################# # Укажем к какой базе данных мы будем обращаться. BASE="/srv/www/your.site/public_html/rrd_base/voltage.rrd" # Зададим папку, куда будем сохранять картинки с графиками. WWWPREFIX="/srv/www/your.site/public_html/ccu/voltage" # Получаем значения из ранее созданных файлов скриптом ccujson.php VOLT=$(cat /tmp/ccujson_volt.txt) echo $VOLT # Обновление БД #LC_ALL=C LANG=C /usr/bin/rrdtool update $BASE N:$VOLT # Создание графика (сутки) rrdtool graph $WWWPREFIX/voltage.png \ --width 500 \ --height 200 \ --imgformat PNG \ --start -24h \ --end now \ --slope-mode \ --font-render-mode light \ --font DEFAULT:7:Tahoma \ --x-grid HOUR:1:HOUR:3:HOUR:3:0:"%R%n%d/%m" \ --alt-autoscale-max \ --units-length 7 \ --vertical-label "Напряжение, В" \ --title "Напряжение за 24 часа. Обновление $LASTUPDATE" \ DEF:volt_220=$BASE:volt_220:LAST \ COMMENT:"\s" \ COMMENT:"\s" \ LINE2:volt_220#B77F2A:"220В (AC) " \ GPRINT:volt_220:LAST:"Last %3.3lf В " \ GPRINT:volt_220:MAX:"Max %3.3lf В " \ GPRINT:volt_220:AVERAGE:"Avg %3.3lf В " \ GPRINT:volt_220:MIN:"Min %3.3lf В \l" \ COMMENT:"\s" \ # Создание графика (неделя) rrdtool graph $WWWPREFIX/voltage_week.png \ --width 500 \ --height 200 \ --imgformat PNG \ --start -168h \ --end now \ --slope-mode \ --font-render-mode light \ --font DEFAULT:7:Tahoma \ --x-grid HOUR:6:HOUR:12:HOUR:12:0:"%R%n%d/%m" \ --alt-autoscale-max \ --base 1000 \ --units-length 7 \ --vertical-label "Напряжение, В" \ --title "Напряжение за неделю. Обновление $LASTUPDATE" \ DEF:volt_220=$BASE:volt_220:AVERAGE \ COMMENT:"\s" \ COMMENT:"\s" \ LINE2:volt_220#B77F2A:"220В (AC) " \ GPRINT:volt_220:LAST:"Last %3.3lf В " \ GPRINT:volt_220:MAX:"Max %3.3lf В " \ GPRINT:volt_220:AVERAGE:"Avg %3.3lf В " \ GPRINT:volt_220:MIN:"Min %3.3lf В \l" \ COMMENT:"\s" \ ############################################################# # END Напряжение ############################################################# ############################################################# # START баланс ############################################################# # Укажем к какой базе данных мы будем обращаться. BASE="/srv/www/your.site/public_html/rrd_base/balance.rrd" # Зададим папку, куда будем сохранять картинки с графиками. WWWPREFIX="/srv/www/your.site/public_html/ccu/balance" # Получаем значения из ранее созданных файлов скриптом ccujson.php BALANCE=$(cat /tmp/ccujson_balance.txt) echo $BALANCE # Обновление БД #LC_ALL=C LANG=C /usr/bin/rrdtool update $BASE N:$BALANCE # Создание графика (сутки) rrdtool graph $WWWPREFIX/balance.png \ --width 500 \ --height 200 \ --imgformat PNG \ --start -24h \ --alt-autoscale-max \ --font-render-mode light \ --font DEFAULT:7:Tahoma \ --x-grid HOUR:1:HOUR:3:HOUR:3:0:"%R%n%d/%m" \ --vertical-label "Баланс, Руб" \ --title "Баланс за 24 часа. Обновление $LASTUPDATE" \ DEF:balance=$BASE:balance:LAST \ COMMENT:"\s" \ COMMENT:"\s" \ LINE2:balance#CD3932:"Баланс (Руб) " \ GPRINT:balance:LAST:"Last %3.3lf Руб " \ GPRINT:balance:MAX:"Max %3.3lf Руб " \ GPRINT:balance:AVERAGE:"Avg %3.3lf Руб " \ GPRINT:balance:MIN:"Min %3.3lf Руб \l" \ COMMENT:"\s" \ # Создание графика (неделя) rrdtool graph $WWWPREFIX/balance_week.png \ --width 500 \ --height 200 \ --imgformat PNG \ --start -168h \ --end now \ --slope-mode \ --font-render-mode light \ --font DEFAULT:7:Tahoma \ --x-grid HOUR:6:HOUR:12:HOUR:12:0:"%R%n%d/%m" \ --base 1000 \ --units-length 7 \ --vertical-label "Баланс, Руб" \ --title "Баланс за неделю. Обновление $LASTUPDATE" \ DEF:balance=$BASE:balance:AVERAGE \ COMMENT:"\s" \ COMMENT:"\s" \ LINE2:balance#CD3932:"Баланс (Руб) " \ GPRINT:balance:LAST:"Last %3.3lf Руб " \ GPRINT:balance:MAX:"Max %3.3lf Руб " \ GPRINT:balance:AVERAGE:"Avg %3.3lf Руб " \ GPRINT:balance:MIN:"Min %3.3lf Руб \l" \ COMMENT:"\s" \ ############################################################# # END Напряжение ############################################################# ############################################################# # START Заряд аккумулятора ############################################################# # Укажем к какой базе данных мы будем обращаться. BASE="/srv/www/your.site/public_html/rrd_base/batterycharge.rrd" # Зададим папку, куда будем сохранять картинки с графиками. WWWPREFIX="/srv/www/your.site/public_html/ccu/batterycharge" # Получаем значения из ранее созданных файлов скриптом ccujson.php BATTERYCHARGE=$(cat /tmp/ccujson_batterycharge.txt) echo $BATTERYCHARGE # Обновление БД #LC_ALL=C LANG=C /usr/bin/rrdtool update $BASE N:$BATTERYCHARGE # Создание графика (сутки) rrdtool graph $WWWPREFIX/batterycharge.png \ --width 500 \ --height 200 \ --imgformat PNG \ --start -24h \ --end now \ --slope-mode \ --font-render-mode light \ --font DEFAULT:7:Tahoma \ --x-grid HOUR:1:HOUR:3:HOUR:3:0:"%R%n%d/%m" \ --base 1000 \ --units-length 7 \ --vertical-label "Заряд аккумулятора, %" \ --title "Заряд аккумулятора за 24 часа. Обновление $LASTUPDATE" \ DEF:batterycharge=$BASE:batterycharge:LAST \ COMMENT:"\s" \ COMMENT:"\s" \ LINE2:batterycharge#CD3932:"Заряд аккумулятора (%) " \ GPRINT:batterycharge:LAST:"Last %3.3lf " \ GPRINT:batterycharge:MAX:"Max %3.3lf " \ GPRINT:batterycharge:AVERAGE:"Avg %3.3lf " \ GPRINT:batterycharge:MIN:"Min %3.3lf \l" \ COMMENT:"\s" \ # Создание графика (неделя) rrdtool graph $WWWPREFIX/batterycharge_week.png \ --width 500 \ --height 200 \ --imgformat PNG \ --start -168h \ --end now \ --slope-mode \ --font-render-mode light \ --font DEFAULT:7:Tahoma \ --x-grid HOUR:6:HOUR:12:HOUR:12:0:"%R%n%d/%m" \ --alt-autoscale-max \ --base 1000 \ --units-length 7 \ --lower-limit 0 \ --upper-limit 100 \ --vertical-label "Заряд аккумулятора, %" \ --title "Заряд аккумулятора за неделю. Обновление $LASTUPDATE" \ DEF:batterycharge=$BASE:batterycharge:AVERAGE \ COMMENT:"\s" \ COMMENT:"\s" \ LINE2:batterycharge#CD3932:"Заряд аккумулятора (%) " \ GPRINT:batterycharge:LAST:"Last %3.3lf " \ GPRINT:batterycharge:MAX:"Max %3.3lf " \ GPRINT:batterycharge:AVERAGE:"Avg %3.3lf " \ GPRINT:batterycharge:MIN:"Min %3.3lf \l" \ COMMENT:"\s" \ ############################################################# # END Заряд аккумулятора #############################################################
Задание в планировщике
Скрипт rrd_update.sh необходимо запускать каждые 5 минут.
Добавляем в планировщик (cron) следующее правило:
*/5 * * * * /home/ccujson/rrd_update.sh > /dev/null 2>&1
И перезапускам cron.
База данных и графики будут обновляться каждые 5 минут. Теперь нам нужно сделать возможность просматривать графики через web браузер.
HTML файл для отображения графиков
Создаём файл index.php в какой либо директории вашего HTTP сервера.
Содержимое файла index.php
Не забываем менять пути на свои!
<html> <head> <meta http-equiv="refresh" content="300; url=http://your.site/ccu/"> </head> <body> <?php include 'ccujson_gprs_status.txt'; ?> <table> <th>Уровень сигнала сотовой сети</th> <tr> <td><img src="http://your.site/ccu/signal/signal.png"></td> <td><img src="http://your.site/ccu/signal/signal_week.png"></td> </tr> <th>Температура</th> <tr> <td><img src="http://your.site/ccu/temperature/temperature.png"></td> <td><img src="http://your.site/ccu/temperature/temperature_week.png"></td> </tr> <th>Напряжение</th> <tr> <td><img src="http://your.site/ccu/voltage/voltage.png"></td> <td><img src="http://your.site/ccu/voltage/voltage_week.png"></td> </tr> <th>Баланс SIM карты</th> <tr> <td><img src="http://your.site/ccu/balance/balance.png"></td> <td><img src="http://your.site/ccu/balance/balance_week.png"></td> </tr> <th>Заряд аккумулятора</th> <tr> <td><img src="http://your.site/ccu/batterycharge/batterycharge.png"></td> <td><img src="http://your.site/ccu/batterycharge/batterycharge_week.png"></td> </tr> </table> </body> </html>
Результат будет примерно следующим
Благодаря постоянному замеру параметров электросети, были сделаны интересные наблюдения. Обратите внимание на ниже приведенный график напряжения. Да… вот такое у нас в деревне напряжение… падает <120 В (добавлено 21/06/2017).
Интеграция с сервисом «Народный мониторинг»
Что такое сервис «Народный мониторинг»:
Народный мониторинг (narodmon.ru) — геоинформационный сервис по отображению на карте мира и контролю (по e-mail, sms) показаний датчиков своих участников (температуры, влажности, атм.давления, скорости и направления ветра, радиации, энергопотребления и других), а также частных веб-камер для приватного(частного) и публичного доступа.
http://narodmon.ru
Я не буду останавливаться на описании данного сервиса, кому интересно заходите на сайт http://narodmon.ru и изучайте. Тут я приведу только пример скрипта работы с сервисом «Народный мониторинг», который будет использовать данные полученные с GSM контроллера CCU825 через JSON.
<?php # Получаем из временного файла ccujson_temp.txt, # созданного скриптом ccujson.php, данные о температуре. $tempFile = "/tmp/ccujson_temp.txt"; $tempFd = fopen($tempFile, 'r') or die("не удалось открыть файл"); $tempAll = fread($tempFd, filesize($tempFile)); fclose($tempFd); # Получаем из временного файла ccujson_volt.txt, # созданного скриптом ccujson.php, данные о напряжении в сети 220Ве. $voltFile = "/tmp/ccujson_volt.txt"; $voltFd = fopen($voltFile, 'r') or die("не удалось открыть файл"); $voltAll = fread($voltFd, filesize($voltFile)); fclose($voltFd); # Преобразуем полученные данные в массив. $tempArray = explode(":", $tempAll); $voltArray = explode(":", $voltAll); # Получаем значение температуры из массива $tempArray с индексом 1 # В нашем случае это температура на улице. $tempUlitsa = $tempArray[1]; # Получаем значение о напряжении 220В из массива $voltArray с индексом 0 # В нашем случае это напряжение в сети 220В. $volt220 = $voltArray[0]; # Отправляем данные на сайт narodmon.ru # #00-00-00-00-00-00 - MAC адрес вашего сервера # #Ulitsa - название датчика температуры # #220volt название датчика напряжения в сети 220В $fp = @fsockopen("tcp://narodmon.ru", 8283, $errno, $errstr); if(!$fp) exit("ERROR(".$errno."): ".$errstr); fwrite($fp, "#00-00-00-00-00-00\n#Ulitsa#$tempUlitsa\n#220volt#$volt220\n##"); fclose($fp); ?>
Цитата с сайта narodmon.ru про интервал обновления:
«Данные обрабатываются и загружаются в базу пакетно 1 раз в минуту (команды MQTT немедленно), соответственно и показания датчиков также обновляются ежеминутно. При отправке показаний чаще чем 1 раз в минуту прибор попадает в бан до устранения проблемы его владельцем.»
Добавляем в cron запуск скрипта каждые 5 минут
*/5 * * * * /usr/bin/php /home/ccujson/narodmon.php > /dev/null 2>&1
Пример отображения графиков в «Народном мониторинге»
Ссылки
- Встроенный CCU JSON API: Описание протокола: https://radsel.ru/files/docs/ccu-api/ccu-api.html
- Статья: GSM контроллер CCU825 версия 2. Начало работы
- GSM контроллер CCU825 на сайте производителя
- Документация на GSM контроллер CCU825
- Описание использования GSM контроллера CCU825
- Прошивка версии 2.x (веб-версия)
- Вопросы и ответы по работе с контроллерами через веб-интерфейс
- Сервис «Народный мониторинг»
Привет, а откуда ты узнал о команде DataType ControlPoll :)?
В документации такую не нашёл.
Есть ещё какие-нибудь незадокументированные?
Приветствую!
Зашел через FF на ccu.sh, включил в FF «Веб-разработка» и смотрел какой обмен идёт между браузером и сайтом.
Так и нашёл.
Скриншот примера прикрепил.
Прикрепленный файл:
А вы с SIMP Light случайно CCU825 не дружили?
Нет.
Но вот что есть: https://support.simplight.ru/knowledge-bases/2/articles/299-integratsiya-simp-light-i-oborudovaniya-radsel-ccu825
а вы сами пробовали?, а использовал проект с этой статьи https://simplight.ru/manual/radsel/cherez-internet-ccu-sh. у меня проблема с gsm сигналом, как я понял там для более старой версии . вот что летит {«Active»:0,»Voltage»:2081}],»Outputs»:[0,0,0,0,0,0,0],»Partitions»:[«Arm»],»Battery»:{«State»:»NotUsed»},»Case»:1,»Power»:15.1,»Temp»:8,»Balance»:55.00}
09.03.2019 21:21:49.441 {«ControlPoll»:{«ModemStatus»:8,»Signal»:{«dBm»:-57,»Percent»:100,»Strength»:3},»Balance»:55.00,»Mode»:[2],»In»:[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],»Out»:[0,0,0,0,0,0,0]}}
не программист )), не знаю что подправить
// GSM Level
jsonres := jsonobj.Field[‘ControlPoll’];
b := TlkJSONobject(jsonres).getInt(‘SignalLevel’);
WriteValue(Format(GSM_FORMAT, [Pribor[j, 3]]), b);
у вас я вижу все есть значения, как их подставить не знаю
Уровень сигнала модема
Прикрепленный файл:
может у вас есть проект с нормальным gsm ?
С нормальным GSM это что? Контроллером? Я пользуюсь CCU, меня устраивает.
проект для SIMP Light с новым форматом gsm
Думаю стоит обратится к производителю SIMP. Формат уровня сигнала менялся в новой версии.
Спасибо, написал обращение. У вас замечательные статьи, настроил на народный мониторинг))
Пожалуйста! Рад что пригодились статьи!
Здравствуйте, что то поменялось с доступом на контроллер, у вас все нормально? с поддержки RADSEL написали «Обновите OpenSSL. Теперь поддерживается только протокол TLS 1.2.» не подскажите что нужно конкретно сделать?
Здравствуйте!
Нужно сделать то, что сказал ТП — обновить OpenSSL.
TLS ниже 1.2 давно толком не поддерживается. Старый и уязвимый протокол.
На каком сервере (какая ОС, какая версия PHP?) у вас крутится скрипт взаимодействия с ccu.sh ?
Посмотрите версию модуля OpenSSL для PHP.
Спасибо, поменял версию XAMPP и все заработало . Был php версии 5.х.х сейчас 7.х.х, windows 7
появление интеграции в прошивки с народным мониторингом конечно хорошо — но во-первых это деньги за ключ для 825го, а еще если у вас несколько устройств то сам народмон тоже захочет пожертвование — ежегодное.
А вот если пользоваться вашим способом то можно собирать данные со всех 825 и отправлять их в народный мониторинг как одно устройство с кучей датчиков.
Для тех, кто не хочет разбираться, свой сервер настраивать, встроенная интеграция это удобно… а так да, согласен.