Строим графики на GSM контроллере CCU825 (JSON) и интеграция с narodmon.ru

Обновление от :


ccu825_json_gr

Статья также опубликована на сайте: 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 идеальным языком обмена данными.

http://www.json.org/json-ru.html

Используя JSON, можно легко организовать передачу данных между приложениям и серверами, а это как раз то, что нам и нужно.

Схема работы CCU825 с сервером ccu.sh

Схема взаимодействия CCU825 с сервером
Схема взаимодействия CCU825 с сервером ccu.sh
  • GSM контроллер CCU825 (1), через GSM GPRS (2) и далее Интернет, используя закрытый протокол (3), организует двухсторонний канал передачи данных до сервера ccu.sh (4).
  • На сервере ccu.sh (3) поднят HTTP(S) сервер, который обеспечивает следующие функции:
  • Для взаимодействия с сервером ccu.sh через JSON (5), запускаем на нашем сервере (6) скрипты, которые будут приведены ниже.
  • На основе полученных через JSON данных, строим графики (7).

Подробнее про роль сервера ccu.sh

Теперь, когда стала понятна общая схема работы, слегка опишу как работает сервер ccu.sh (это моё предположение основанное на опыте).

Сервер ccu.sh выполняет функцию прокси сервера (посредника) между нами, находящимися где-то в Интернете и GSM контроллером, который так же, не известно где подключен к Интернет через GSM GPRS и скорей всего, у него нет публичного IP адреса, что не даёт возможности получить к контроллеру прямой доступ.

Упрощенный принцип работы

Принцип работы сервера ccu.sh
Принцип работы сервера ccu.sh
  1. При включении CCU825 и доступности GPRS (и если указано в настройках), контроллер инициализирует исходящее соединение к серверу (1) для организации с сервером ccu.sh двухстороннего канала передачи данных (2).
    • Тут важно заметить, что именно контроллер начинает исходящее соединение в сторону сервера ccu.sh у которого заранее известен публичный адрес (в отличии от контроллера). Любой контроллер, через Интернет, не имея публичного адреса, может к нему подключиться пройдя процедуру аутентификации.
  2. После прохождения всех процедур установления двухстороннего канала передачи данных (2), у сервера ccu.sh появляется возможность управлять контроллером. В дальнейшем, для управления контроллером CCU, мы взаимодействием с сервером ccu.sh, а он, уже с контроллером (как говорил выше — функция прокси сервера).
  3. С нашего сервера, мы отправляем JSON запрос (3) к серверу ccu.sh.
  4. Сервер ccu.sh, преобразует JSON запрос в свой закрытый протокол и по ранее организованному двухстороннему каналу (2) отправляет запрос (4) на CCU контроллер.
  5. Контроллер CCU, обработав запрос (4), возвращает на сервер ccu.sh ответ (5) с запрошенными данными.
  6. Сервер ccu.sh преобразует полученный ответ в JSON формат и уже в JSON формате отдаёт (6) его нашему серверу.
  7. Наш сервер, используя скрипты, парсит (извлекает данные) полученный 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);

?>
Скрипт для CCU прошивки 2.16 и ниже
<?php

# Массив для преобразования RSSI Index в RSSI dBm
$modemDbm = array(  "0" => "-113",
                    "1" => "-111",
                    "2" => "-109",
                    "3" => "-107",
                    "4" => "-105",
                    "5" => "-103",
                    "6" => "-101",
                    "7" => "-99",
                    "8" => "-97",
                    "9" => "-95",
                    "10" => "-93",
                    "11" => "-91",
                    "12" => "-89",
                    "13" => "-87",
                    "14" => "-85",
                    "15" => "-83",
                    "16" => "-81",
                    "17" => "-79",
                    "18" => "-77",
                    "19" => "-75",
                    "20" => "-73",
                    "21" => "-71",
                    "22" => "-69",
                    "23" => "-67",
                    "24" => "-65",
                    "25" => "-63",
                    "26" => "-61",
                    "27" => "-59",
                    "28" => "-57",
                    "29" => "-55",
                    "30" => "-53",
                    "31" => "-51"
                 );

# Имя пользователя для доступа к серверу 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 для получения уровня сигнала сотовой сети
$json1 = http_auth_get('https://ccu.sh/data.cgx?cmd={"DataType":"ControlPoll"}',$jsonUser,$jsonPass);
$obj1 = json_decode($json1, 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($obj1) ) {
	echo "\nНет связи с контроллером!\n\n";
	echo "\nВторая попытка JSON запроса. Пауза 10 сек.\n\n";
	sleep(10);
	$json1 = http_auth_get('https://ccu.sh/data.cgx?cmd={"DataType":"ControlPoll"}',$jsonUser,$jsonPass);
	$obj1 = json_decode($json1, 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,1);

	# Вход 2. Датчик RTD-03, температура на улице.
	$input2 = $input['1'];
	# Преобразуем дискреты на входе контроллера в напряжение.
	$inputVoltage2 = $input2['Voltage']*10/4095;
	# Используя формулу из uGuard преобразуем напряжение в градусы и округляем до десятых.
	$inputVoltageRtd2 = round(($inputVoltage2/5-0.5)/0.01,1);

	# Вход 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($obj1) ) {
	$control = $obj1['ControlPoll'];
	# Переводим уровень сигнала из RSSI Index в проценты
	$signal = round($control['SignalLevel']*100/31);
	$signalDbm = $modemDbm[$control['SignalLevel']];
} else {
	# Если нет связи с контроллером (массив пустой), то все переменные обнуляем.
	$signal = 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 ответа контроллера.

Принцип расчета уровня сигнала на прошивке 2.16 и ниже

Уровень сигнала сети, мы получаем с GSM контроллера в форме RSSI Index, в скрипте мы его переводим в процентное значение и dBm.

Таблица по которой можно соотнести RSSI Index, RSSI в dBm и процентов:

RSSI Index RSSI dBm Процент, %
0 113 и хуже 0
1 111 3
2 109 6
3 107 10
4 105 13
5 103 16
6 101 19
7 99 23
8 97 26
9 95 29
10 93 32
11 91 35
12 89 39
13 87 42
14 85 45
15 83 48
16 81 52
17 79 55
18 77 58
19 75 61
20 73 65
21 71 68
22 69 71
23 67 74
24 65 77
25 63 81
26 61 84
27 59 87
28 57 90
29 55 94
30 53 97
31 51 и лучше 100

Создание графиков

Для построения графиков будем использовать 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).

Напряжение в деревне
Напряжение в деревне

Интеграция с сервисом «Народный мониторинг»

Поддержка "Народного мониторинга"
В версии прошивки 2.22 от 17/01/2020 появилась поддержка (нужно покупать лицензионный ключ) работы с сервисом «Народный мониторинг» . Прошивку ещё не тестировал, но, судя по всему, с новой версией уже не нужно будет делать всё, что описано ниже, и можно настроить интеграцию в самом CCU без использования внешних серверов. Документация: http://www.radsel.ru/products/narodmon.html (22 марта 2022 г. встроенная в CCU функция интеграции с narodmon.ru перестала работать (произошёл какой-то конфликт между narodmon.ru и RADS Electronics). Но интеграция с narodmon.ru, описанная в данной статье, продолжает работать.)

Что такое сервис «Народный мониторинг»:

Народный мониторинг (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

Пример отображения графиков в «Народном мониторинге»

График в «Народном мониторинге»
График в «Народном мониторинге»

Ссылки

Андрей Торженов

В профессиональной сфере занимаюсь всем, что связанно с IT. Основная специализация - VoIP и сети передачи данных. Стараюсь не заниматься Windows серверами (но иногда приходится) и 1С.

Строим графики на GSM контроллере CCU825 (JSON) и интеграция с narodmon.ru: 16 комментариев

      1. а вы сами пробовали?, а использовал проект с этой статьи 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);
        у вас я вижу все есть значения, как их подставить не знаю

        Уровень сигнала модема

        $control = $objSignal['ControlPoll'];
        $signalLevel = $control['Signal'];
        $signal = $signalLevel['Percent'];
        $signalDbm = $signalLevel['dBm']; :unsure:
        

        Прикрепленный файл:

  1. Здравствуйте, что то поменялось с доступом на контроллер, у вас все нормально? с поддержки RADSEL написали «Обновите OpenSSL. Теперь поддерживается только протокол TLS 1.2.» не подскажите что нужно конкретно сделать?

    1. Здравствуйте!

      Нужно сделать то, что сказал ТП — обновить OpenSSL.

      TLS ниже 1.2 давно толком не поддерживается. Старый и уязвимый протокол.

      На каком сервере (какая ОС, какая версия PHP?) у вас крутится скрипт взаимодействия с ccu.sh ?

      Посмотрите версию модуля OpenSSL для PHP.

      php -i | grep OpenSSL :scratch:
      
  2. появление интеграции в прошивки с народным мониторингом конечно хорошо — но во-первых это деньги за ключ для 825го, а еще если у вас несколько устройств то сам народмон тоже захочет пожертвование — ежегодное.
    А вот если пользоваться вашим способом то можно собирать данные со всех 825 и отправлять их в народный мониторинг как одно устройство с кучей датчиков.

Добавить комментарий