27.06.2017 Сервер Статистики aka Автоматизация измерений Эпизод II

Материал из SRNS
Перейти к: навигация, поиск
(Что за Сервер Статистики?)
 
(не показаны 40 промежуточных версий 1 участника)
Строка 1: Строка 1:
 
<summary [ hidden ]>
 
<summary [ hidden ]>
 
<center>[[File:StatServer.PNG|400px]]</center>
 
<center>[[File:StatServer.PNG|400px]]</center>
'''''Сервера Статистики УИЦ СРТТ'''''
+
Встречайте нового работника - Сервер Статистики УИЦ СРТТ!
 
</summary>
 
</summary>
  
Строка 12: Строка 12:
  
 
== Что за Сервер Статистики? ==
 
== Что за Сервер Статистики? ==
'''Сервер Статистики''' - отдельно выделенный компьютер, работающий круглосуточно, к которому подключены различные приемники, в свою очередь, решающиеся по одной антенне. На данный момент подключены '''Javad Lexon GGD''', '''Swift Navigation Piksi''' и наш '''Oryx''' в <s>серой коробке</s> походном исполнении. Далее в статье Oryx фигурирует под мейнстримовым названием '''MCR'''. IP сервера [https://srns.ru/wiki/%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA_IP '''192.168.0.94'''], кодовое имя '''Evaluator''', пользователь '''srtt''', пароль известен.
+
'''Сервер Статистики''' - отдельно выделенный компьютер, работающий круглосуточно, к которому подключены различные приемники, в свою очередь, решающиеся по одной антенне. На данный момент подключены '''Javad Lexon GGD''', '''Swift Navigation Piksi''' и наш '''Oryx''' в <s>серой коробке</s> походном исполнении. Далее в статье Oryx фигурирует под мейнстримовым названием '''MCR'''. IP сервера [https://srns.ru/wiki/%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA_IP '''192.168.0.94'''], кодовое имя '''Evaluator''', пользователь '''nsl''', пароль известен.
  
 
== Чего он там делает? ==
 
== Чего он там делает? ==
На протяжении суток Сервер Статистики пишет логи себе в ''/tmp'', а в начале каждых суток (00:01) решается по ним, строит картинки, делает некоторые статистические (вот почему Сервер Статистики, а не логов) вычисления и шлет это на заданные почтовые адреса типа '''@gmail.com'''.  
+
На протяжении суток Сервер Статистики пишет логи себе в ''/tmp'', а в начале каждых суток (00:01) решается по ним, строит картинки, делает некоторые статистические (вот почему Сервер Статистики, а не логов) вычисления и шлет это на заданные почтовые адреса.  
  
После этого для Javad и Oryx '''логи''' копируются в папку ''/home/CommonFiles/logs'', затем стираются. Логи для Piksi, в настоящее время, слишком тяжелы, потому они просто стираются без копирования.
+
После этого для Javad и Oryx '''логи''' копируются в папку ''/home/CommonFiles/logs'', затем стираются. Для Piksi, в настоящее время, логи слишком тяжелы, потому копируется только один, уже обработанный, файл - '''piksi.obs'''.
  
 
Необходимые '''скрипты''' находятся в папке ''/home/CommonFiles/scripts''.
 
Необходимые '''скрипты''' находятся в папке ''/home/CommonFiles/scripts''.
Строка 94: Строка 94:
 
[[File:swift_console.png|600px]]
 
[[File:swift_console.png|600px]]
  
'''Ssvnc''' также запускается автоматически, но иногда умудряется просто прекращать свою работу, тогда необходимо запустить скрипт ''run_vnc:''
+
Транслирующий изображение '''x11vnc ''' также запускается автоматически, но иногда умудряется просто прекращать свою работу, тогда необходимо запустить скрипт ''run_vnc:''
 
<source lang="bash">
 
<source lang="bash">
 
#!/bin/bash
 
#!/bin/bash
Строка 130: Строка 130:
 
/home/CommonFiles/progs/piksi_tools/piksi_tools/sbp2rinex.py $PIKSI -o $PIKSI_OUT
 
/home/CommonFiles/progs/piksi_tools/piksi_tools/sbp2rinex.py $PIKSI -o $PIKSI_OUT
  
echo 'All convert!'
+
echo "All convert!"
 
</source>
 
</source>
 
Для Javad и MCR используется скомпилированная программа '''convbin''' из RTKLib, для Piksi используется '''sbp2rinex.py''', предоставляемая Swift Navigation.
 
Для Javad и MCR используется скомпилированная программа '''convbin''' из RTKLib, для Piksi используется '''sbp2rinex.py''', предоставляемая Swift Navigation.
Строка 161: Строка 161:
 
rnx2rtkp -r $REF -p 0 $PIKSI $NAV $GNAV -e > $OUT
 
rnx2rtkp -r $REF -p 0 $PIKSI $NAV $GNAV -e > $OUT
  
echo 'All solve!'
+
echo "All solve!"
 
</source>
 
</source>
 
Используется скомпилированная программа '''rnx2rtkp''' из RTKLib, '''-r REF''' - задается опорная точка, '''-p 0''' - задается режим работы (0 - single), '''-e''' - формат выдачи данных (e - X/Y/Z ECEF).
 
Используется скомпилированная программа '''rnx2rtkp''' из RTKLib, '''-r REF''' - задается опорная точка, '''-p 0''' - задается режим работы (0 - single), '''-e''' - формат выдачи данных (e - X/Y/Z ECEF).
Строка 195: Строка 195:
 
#pl $MCR_OUT_SKIP $PIKSI_OUT_SKIP $JAVAD_OUT_SKIP
 
#pl $MCR_OUT_SKIP $PIKSI_OUT_SKIP $JAVAD_OUT_SKIP
  
SKIP=5000
+
SKIP=1000
  
 
MCR_OUT_SKIP=`echo $MCR_OUT | sed 's/\.plane/\.plane_skip/g'`
 
MCR_OUT_SKIP=`echo $MCR_OUT | sed 's/\.plane/\.plane_skip/g'`
Строка 244: Строка 244:
 
toc ()"
 
toc ()"
  
echo 'All plot!'
+
echo "All plot!"
 
</source>
 
</source>
Скрипт может откинуть начальные измерения, например, чтобы исключить начальные искажения, в данном случае откидываются '''SKIP''' 5000 начальных измерений.
+
Скрипт может откинуть начальные измерения, например, чтобы исключить начальные искажения, в данном случае откидываются '''SKIP''' 1000 начальных измерений.
  
 
В построении графиков поможет '''Octave'''. В него парсятся данные из созданных выше файликов, строятся графики, подсчитывается количество измерений и рассчитывается стандартное отклонение измерений относительно опорной точки по каждому приемнику.
 
В построении графиков поможет '''Octave'''. В него парсятся данные из созданных выше файликов, строятся графики, подсчитывается количество измерений и рассчитывается стандартное отклонение измерений относительно опорной точки по каждому приемнику.
Строка 275: Строка 275:
 
ATTACHMENT=`find -name '*.png'`
 
ATTACHMENT=`find -name '*.png'`
 
echo $ATTACHMENT
 
echo $ATTACHMENT
(echo "Subject:Solutions statistics"; uuencode $ATTACHMENT $ATTACHMENT;) | sendmail -F "Daily solutions" *****@gmail.com
+
echo " " | mailx -r "srtt@evaluator (Daily solutions)" -s "Solutions statics" -a $ATTACHMENT ****@gmail.com
(echo "Subject:Solutions statistics"; uuencode $ATTACHMENT $ATTACHMENT;) | sendmail -F "Daily solutions" *********@gmail.com
+
echo " " | mailx -r "srtt@evaluator (Daily solutions)" -s "Solutions statics" -a $ATTACHMENT *******@srns.ru
 
cp $ATTACHMENT /home/CommonFiles/logs
 
cp $ATTACHMENT /home/CommonFiles/logs
 
rm -rf $ATTACHMENT
 
rm -rf $ATTACHMENT
echo 'Email successfully sent!'
+
echo "Email successfully sent!"
 
</source>
 
</source>
'''Uuencode''' необходим, чтобы конвертировать бинарный файл картинок в текст, чтобы ''sendmail'' мог её передать, является частью пакета '''sharutils'''. После отправки картинка копируется в папку ''logs'' и удаляется.
+
После отправки картинка копируется в папку ''logs'' и удаляется.
  
 
== Как очищаются логи? ==
 
== Как очищаются логи? ==
Инквизицией! Шутка. Скриптом ''refresh_logs'':
+
Инквизицией! Шутка. Пока идет запись логов, их файлы защищены на запись, следовательно, придется прервать запись, убив фоновые процессы, скрипт ''kill_logs_pid'':
 +
<source lang="bash">
 +
#!/bin/bash
 +
 
 +
pid_log=`ps aux | grep '\(start_\|swift\|curl\|broadcast_\)'| awk '{print $2}'`
 +
kill $pid_log
 +
echo "Pids killed!"
 +
</source>
 +
 
 +
Скрипт очищающий логи ''refresh_logs'':
 
<source lang="bash">
 
<source lang="bash">
 
#!/bin/bash
 
#!/bin/bash
Строка 293: Строка 302:
 
cp /tmp/javad.* /home/CommonFiles/logs/$Data"_"$Time
 
cp /tmp/javad.* /home/CommonFiles/logs/$Data"_"$Time
 
cp /tmp/mcr.* /home/CommonFiles/logs/$Data"_"$Time
 
cp /tmp/mcr.* /home/CommonFiles/logs/$Data"_"$Time
echo " ">/tmp/javad.log
+
cp /tmp/piksi.obs /home/CommonFiles/logs/$Data"_"$Time
echo " ">/tmp/mcr.log
+
cp /dev/null /tmp/javad.log
echo " ">/tmp/piksi.log
+
cp /dev/null /tmp/mcr.log
echo 'Logs refreshed!'
+
cp /dev/null /tmp/piksi.log
 +
echo "Logs refreshed!"
 
</source>
 
</source>
При вызове скрипта фиксируется дата и время, после чего логи для Javad и MCR копируются в соответствующую папку в ''/home/CommonFiles/logs/''. Затем логи для всех 3-х приемников начинают собираться заново.
+
При вызове скрипта фиксируется дата и время, после чего логи для Javad и MCR копируются в соответствующую папку в ''/home/CommonFiles/logs/''. Для Piksi копируются только уже обработанный файл - '''piksi.obs'''.
  
 
== Хочу один скрипт для вызова всего! ==
 
== Хочу один скрипт для вызова всего! ==
Строка 309: Строка 319:
 
plot_all
 
plot_all
 
send_mail
 
send_mail
 +
kill_logs_pid
 
refresh_logs
 
refresh_logs
echo 'All done!'
+
echo "All done!"
 
</source>
 
</source>
 +
 +
 +
'''UPD'''. Время показало, что пока Piksi пишет "тяжелые" логи, они долго обрабатываются. В данном случае пришлось разделить скрипты. Обработка логов ''conv_n_solv'':
 +
<source lang="bash">
 +
#!/bin/bash
 +
 +
convert_all_to_rinex
 +
solve_all_from_rinex
 +
</source>
 +
 +
От этого немного похудел ''process_all'':
 +
<source lang="bash">
 +
#!/bin/bash
 +
 +
plot_all
 +
send_mail
 +
kill_logs_pid
 +
refresh_logs
 +
echo "All done!"
 +
</source>
 +
 
== А где же автоматизация? ==
 
== А где же автоматизация? ==
 
Автоматизируется Сервер Статистики программированием его расписания с помощью планировщика '''crontab''', для этого необходимо указать ему расписание,
 
Автоматизируется Сервер Статистики программированием его расписания с помощью планировщика '''crontab''', для этого необходимо указать ему расписание,
Строка 322: Строка 354:
 
MAILTO=srtt
 
MAILTO=srtt
 
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/home/CommonFiles/scripts:/home/CommonFiles/progs/RTKlib:
 
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/home/CommonFiles/scripts:/home/CommonFiles/progs/RTKlib:
#15 17 * * * "bash -c `broadcast_javad`"
+
00 00 * * * "bash -c `conv_n_solv`"
#16 17 * * * "bash -c `start_javad_log`"
+
00 01 * * * "bash -c `process_all`"
#17 17 * * * "bash -c `start_mcr_log`"
+
15 01 * * * "bash -c `broadcast_javad`"
#18 17 * * * "bash -c `start_piksi_log`"
+
16 01 * * * "bash -c `start_javad_log`"
01 00 * * * "bash -c `process_all`"
+
17 01 * * * "bash -c `start_mcr_log`"
 +
18 01 * * * "bash -c `start_piksi_log`"
 
</source>
 
</source>
 
Обязательно указывается пользователь '''MAILTO''', от которого будут выполнены запланированные команды, и пути нахождения необходимых программ '''PATH'''.
 
Обязательно указывается пользователь '''MAILTO''', от которого будут выполнены запланированные команды, и пути нахождения необходимых программ '''PATH'''.
Закомментированные строки это строки, выполнение которых, по идеи, должно выполняться единожды, я это сделал. Возможно в будущем накопление логов выявит проблемы или новые задачи и будет необходимо запускать сбор логов также по расписанию, пока что так.  
+
Предполагается, что ранее сбор логов был запущен и 00:00 уже пойдет над ними работа.
  
 
Формат записи строчки расписания такой:
 
Формат записи строчки расписания такой:
Строка 337: Строка 370:
 
</source>
 
</source>
 
Первое число обозначает минуту, второе час, то есть запуск всех процессов произойдет в одни минуту первого ночи. Звездочку вместо числа следует трактовать как слово ''каждый'', то есть ''каждого дня месяца'', ''каждого месяца'', ''каждого дня недели''. Тонкости настройки ''crontab'' легко ищутся в интернете, например, [http://help.ubuntu.ru/wiki/cron вот] и [http://devacademy.ru/posts/15-otlichnykh-primierov-dlia-sozdaniia-cron-zadach-v-linux/ вот].
 
Первое число обозначает минуту, второе час, то есть запуск всех процессов произойдет в одни минуту первого ночи. Звездочку вместо числа следует трактовать как слово ''каждый'', то есть ''каждого дня месяца'', ''каждого месяца'', ''каждого дня недели''. Тонкости настройки ''crontab'' легко ищутся в интернете, например, [http://help.ubuntu.ru/wiki/cron вот] и [http://devacademy.ru/posts/15-otlichnykh-primierov-dlia-sozdaniia-cron-zadach-v-linux/ вот].
 +
 +
Соответственно, скрипты на запись логов запускаются в 01:00, потому что процессы обработки могут затягиваться, часа точно должно хватить.
  
 
Посмотреть текущее расписание можно командой:
 
Посмотреть текущее расписание можно командой:
Строка 348: Строка 383:
  
  
=== PS ===
+
Вот примерно так всё и работает!
+
'''P.S.'''
  
<s>Подписывайтесь, ставьте лайки!</s>
+
Вот примерно так всё и работает!
  
[[Категория:HOWTO]] [[Категория:Сервер Статистики]]
+
[[Категория:HOWTO]] [[Категория:Сервер Статистики]] [[Категория:Oryx]] [[Категория:испытания и эксперименты]]
 +
{{wl-publish: 2017-06-28 10:17:25 +0300 | Ustinov }}

Текущая версия на 16:18, 5 декабря 2019

StatServer.PNG

Данная страница продолжает дело создания Сервера Статистики и написана по мотивам нескольких статей: этой, этой и этой.

Написана она для того, чтобы подвести итог и чтобы потом не забыть, как это сделано и работает сейчас.

Пути улучшения, как всегда, есть, но это дело будущего.

Содержание

[править] Что за Сервер Статистики?

Сервер Статистики - отдельно выделенный компьютер, работающий круглосуточно, к которому подключены различные приемники, в свою очередь, решающиеся по одной антенне. На данный момент подключены Javad Lexon GGD, Swift Navigation Piksi и наш Oryx в серой коробке походном исполнении. Далее в статье Oryx фигурирует под мейнстримовым названием MCR. IP сервера 192.168.0.94, кодовое имя Evaluator, пользователь nsl, пароль известен.

[править] Чего он там делает?

На протяжении суток Сервер Статистики пишет логи себе в /tmp, а в начале каждых суток (00:01) решается по ним, строит картинки, делает некоторые статистические (вот почему Сервер Статистики, а не логов) вычисления и шлет это на заданные почтовые адреса.

После этого для Javad и Oryx логи копируются в папку /home/CommonFiles/logs, затем стираются. Для Piksi, в настоящее время, логи слишком тяжелы, потому копируется только один, уже обработанный, файл - piksi.obs.

Необходимые скрипты находятся в папке /home/CommonFiles/scripts.

Необходимые программы в папке /home/CommonFiles/progs.

[править] Как заставить приемники делиться логами?

Для этого существуют скрипты.

Javad не имеет ethernet возможностей, потому для него два скрипта.

Первый, настраивает приемник и запускает трансляцию данных в сеть - broadcast_javad:

#!/bin/bash

PORT=/dev/ttyUSB0

stty -F $PORT raw
stty -F $PORT 115200 cs8 -parenb -cstopb -ixon

echo "em,,def:{1,,}" > $PORT
echo "em,,jps/gd"    > $PORT
echo "em,,jps/qd"    > $PORT
echo "em,,jps/WD"    > $PORT

nc -l -p 3500 < $PORT

Второй скрипт пишет логи - start_javad_log:

#!/bin/bash

IP=127.0.0.1
TcpPort=3500

DIR=/tmp/
FILE=javad.log

curl $IP:$TcpPort > $DIR/$FILE


MCR транслирует по сети протокол BINR через порт 3491. Для записи логов - start_mcr_log:

#!/bin/bash

IP=192.168.0.163
TcpPort=3491

DIR=/tmp/
FILE=mcr.log

curl $IP:$TcpPort > $DIR/$FILE


Piksi пишет лог с помощью GUI программы swift_console в формате JSON, скрипт start_piksi_log:

#!/bin/bash

IP=192.168.0.222
TcpPort=55555
DIR=/tmp
FILE=piksi.log

echo /home/CommonFiles/progs/swift_console_v1.0.A_linux/console -t -p $IP:$TcpPort -l -o $DIR --logfilename $FILE
DISPLAY=:1 /home/CommonFiles/progs/swift_console_v1.0.A_linux/console -t -p $IP:$TcpPort -l -o $DIR --logfilename $FILE

Сервер Статистики не имеет экрана, но должен запускать GUI приложение, по крайней мере на данный момент так. При запуске GUI приложений выдаются ошибки об отсутствии дисплея и завершении программы, это несколько странно, ведь наш сервер живет и вроде бы здравствует без экрана, а здесь в качестве выхода из ситуации поднят виртуальный X-сервер, который называется Xvfb, он загружается автоматически при старте системы. Сделано это так. Соответственно, при запуске swift_console принудительно указывается этот виртуальный экран - DISPLAY=:1.

Посмотреть на виртуальный экран можно командой:

ssvncviewer 192.168.0.94:5900

Swift console.png

Транслирующий изображение x11vnc также запускается автоматически, но иногда умудряется просто прекращать свою работу, тогда необходимо запустить скрипт run_vnc:

#!/bin/bash

x11vnc -display :1 -bg -nopw -listen 192.168.0.94 -xkb

Доступные сетевые сервисы Сервера Статистики, в том числе проверить работу ssvnc, можно командой:

nmap -O 192.168.0.94

VNC StatServer.png

[править] И что теперь делать с этими логами?

Обработать.

Шаг 1. Конвертировать собранные логи в RINEX формат, поможет convert_all_to_rinex:

#!/bin/bash

DIR=/tmp

JAVAD=$DIR/javad.log
MCR=$DIR/mcr.log
PIKSI=$DIR/piksi.log

echo Javad: $JAVAD
convbin $JAVAD -r javad

echo MCR: $MCR
convbin $MCR -r nvs

echo Piksi: $PIKSI
export PIKSI_OUT=`echo $PIKSI | sed 's/\.log/\.obs/'`
/home/CommonFiles/progs/piksi_tools/piksi_tools/sbp2rinex.py $PIKSI -o $PIKSI_OUT

echo "All convert!"

Для Javad и MCR используется скомпилированная программа convbin из RTKLib, для Piksi используется sbp2rinex.py, предоставляемая Swift Navigation.

Шаг 2. Рассчитать решение, solve_all_from_rinex:

#!/bin/bash

DIR=/tmp

JAVAD=$DIR/javad.obs
MCR=$DIR/mcr.obs
PIKSI=$DIR/piksi.obs

NAV=`echo $MCR | sed 's/\.obs/\.nav/g'`
GNAV=`echo $MCR | sed 's/\.obs/\.gnav/g'`

REF="2846044.0 2200316.0 5249376.0"

OUT=`echo $JAVAD | sed 's/\.obs/\.pos/g'`
echo "Javad: $JAVAD  -> $OUT"
rnx2rtkp -r $REF -p 0 $JAVAD $NAV $GNAV -e > $OUT

OUT=`echo $MCR | sed 's/\.obs/\.pos/g'`
echo "MCR: $MCR  -> $OUT"
rnx2rtkp -r $REF -p 0 $MCR $NAV $GNAV -e > $OUT

OUT=`echo $PIKSI | sed 's/\.obs/\.pos/g'`
echo "Piksi: $PIKSI  -> $OUT"
rnx2rtkp -r $REF -p 0 $PIKSI $NAV $GNAV -e > $OUT

echo "All solve!"

Используется скомпилированная программа rnx2rtkp из RTKLib, -r REF - задается опорная точка, -p 0 - задается режим работы (0 - single), -e - формат выдачи данных (e - X/Y/Z ECEF).

[править] Когда уже статистика?

Вот теперь.

Визуализируем полученные данные, plot_all:

#!/bin/bash

DIR=/tmp

JAVAD=$DIR/javad.pos
MCR=$DIR/mcr.pos
PIKSI=$DIR/piksi.pos

JAVAD_OUT=`echo $JAVAD | sed 's/\.pos/\.plane/g'`
echo "$JAVAD  ->   $JAVAD_OUT"
cat $JAVAD | grep -v "^%" | awk '{print $3" "$4}' > $JAVAD_OUT
#cat $JAVAD | grep -v "^%" | awk '{print $3$4$5" "$6$7$8}' > $JAVAD_OUT

MCR_OUT=`echo $MCR | sed 's/\.pos/\.plane/g'`
echo "$MCR   ->  $MCR_OUT"
cat $MCR | grep -v "^%" | awk '{print $3" "$4}' > $MCR_OUT
#cat $MCR | grep -v "^%" | awk '{print $3$4$5" "$6$7$8}' > $MCR_OUT

PIKSI_OUT=`echo $PIKSI | sed 's/\.pos/\.plane/g'`
echo "$PIKSI   ->  $PIKSI_OUT"
cat $PIKSI | grep -v "^%" | awk '{print $3" "$4}' > $PIKSI_OUT
#cat $PIKSI | grep -v "^%" | awk '{print $3$4$5" "$6$7$8}' > $PIKSI_OUT

#pl $MCR_OUT_SKIP $PIKSI_OUT_SKIP $JAVAD_OUT_SKIP

SKIP=1000

MCR_OUT_SKIP=`echo $MCR_OUT | sed 's/\.plane/\.plane_skip/g'`
echo "$MCR_OUT   ->  $MCR_OUT_SKIP"
cat $MCR_OUT | tail -n +$SKIP > $MCR_OUT_SKIP

JAVAD_OUT_SKIP=`echo $JAVAD_OUT | sed 's/\.plane/\.plane_skip/g'`
echo "$JAVAD_OUT   ->  $JAVAD_OUT_SKIP"
cat $JAVAD_OUT | tail -n +$SKIP > $JAVAD_OUT_SKIP

PIKSI_OUT_SKIP=`echo $PIKSI_OUT | sed 's/\.plane/\.plane_skip/g'`
echo "$PIKSI_OUT   ->  $PIKSI_OUT_SKIP"
cat $PIKSI_OUT | tail -n +$SKIP > $PIKSI_OUT_SKIP

octave --eval "graphics_toolkit('gnuplot');
fid=fopen(\"$MCR_OUT_SKIP\", 'r');
mcr_plot=fscanf(fid, '%f %f\n', [2 Inf]);
fclose(fid);
fid=fopen(\"$JAVAD_OUT_SKIP\", 'r');
javad_plot=fscanf(fid, '%f %f\n', [2 Inf]);
fclose(fid);
fid=fopen(\"$PIKSI_OUT_SKIP\", 'r');
piksi_plot=fscanf(fid, '%f %f\n', [2 Inf]);
fclose(fid);
fig = figure();
set (fig, 'visible', 'off');
mcr_plot(1,:) = mcr_plot(1,:)-2846044; piksi_plot(1, :) = piksi_plot(1, :)-2846044; javad_plot(1, :) = javad_plot(1, :)-2846044;
mcr_plot(2,:) = mcr_plot(2,:)-2200316; piksi_plot(2, :) = piksi_plot(2, :)-2200316; javad_plot(2, :) = javad_plot(2, :)-2200316;
plot(mcr_plot(1, :), mcr_plot(2, :),'r-*', piksi_plot(1, :), piksi_plot(2, :),'g-+', javad_plot(1, :), javad_plot(2, :),'b-x');
grid on; set (gca, 'FontSize', 14);
MCR_smpl = length(mcr_plot); piksi_smpl = length(piksi_plot); javad_smpl = length(javad_plot);
samples_str = sprintf('Solutions statistics [MCR: %d, Piksi: %d, Javad: %d]', MCR_smpl, piksi_smpl, javad_smpl);
title (samples_str);
xlabel('X, m');
ylabel('Y, m');
box('off');
Std_MCR = sqrt((norm(mcr_plot,'fro')^2)/MCR_smpl);
Std_Piksi = sqrt((norm(piksi_plot,'fro')^2)/piksi_smpl);
Std_Javad = sqrt((norm(javad_plot,'fro')^2)/javad_smpl);
MCR_lgn = sprintf('MCR: %0.2f m', Std_MCR);
Piksi_lgn = sprintf('Piksi: %0.2f m', Std_Piksi);
Javad_lgn = sprintf('Javad: %0.2f m', Std_Javad);
lgn = legend(MCR_lgn,Piksi_lgn,Javad_lgn,'Location','southeast');
time = strftime ('%Y-%m-%d_%H_%M_%S', localtime (time ()));
mess = sprintf('%s.png', time);
tic ()
print (fig,mess,'-S1024,768','-dpngcairo');
toc ()"


echo "All plot!"

Скрипт может откинуть начальные измерения, например, чтобы исключить начальные искажения, в данном случае откидываются SKIP 1000 начальных измерений.

В построении графиков поможет Octave. В него парсятся данные из созданных выше файликов, строятся графики, подсчитывается количество измерений и рассчитывается стандартное отклонение измерений относительно опорной точки по каждому приемнику. Std StatServer.PNG

n - количество накопленных измерений.

Получается картинка примерного такого вида:

2017-06-27 00 08 30.png

Достаточно важным моментом здесь является выбор "рендера" и выдаваемого формата файла:

graphics_toolkit('gnuplot')
...
print (fig,mess,'-S1024,768','-dpngcairo');

Cairo - наиболее быстрый (проверено экспериментально) способ вывода. Работает только при graphics_toolkit('gnuplot'). Иначе, процесс сохранения картинки занимает баснословное количество времени.

[править] Где искать эти картинки?

Картинки сохраняются в папку к скопированным логам /home/CommonFiles/logs.

[править] И всё?

Нет, еще картинки отправляются по почте, следующим образом send_mail:

#!/bin/bash

ATTACHMENT=`find -name '*.png'`
echo $ATTACHMENT
echo " " | mailx -r "srtt@evaluator (Daily solutions)" -s "Solutions statics" -a $ATTACHMENT ****@gmail.com
echo " " | mailx -r "srtt@evaluator (Daily solutions)" -s "Solutions statics" -a $ATTACHMENT *******@srns.ru
cp $ATTACHMENT /home/CommonFiles/logs
rm -rf $ATTACHMENT
echo "Email successfully sent!"

После отправки картинка копируется в папку logs и удаляется.

[править] Как очищаются логи?

Инквизицией! Шутка. Пока идет запись логов, их файлы защищены на запись, следовательно, придется прервать запись, убив фоновые процессы, скрипт kill_logs_pid:

#!/bin/bash

pid_log=`ps aux | grep '\(start_\|swift\|curl\|broadcast_\)'| awk '{print $2}'`
kill $pid_log
echo "Pids killed!"

Скрипт очищающий логи refresh_logs:

#!/bin/bash

Data=$(date +%Y-%m-%d)
Time=$(date +%H_%M_%S)
mkdir /home/CommonFiles/logs/$Data"_"$Time
cp /tmp/javad.* /home/CommonFiles/logs/$Data"_"$Time
cp /tmp/mcr.* /home/CommonFiles/logs/$Data"_"$Time
cp /tmp/piksi.obs /home/CommonFiles/logs/$Data"_"$Time
cp /dev/null /tmp/javad.log
cp /dev/null /tmp/mcr.log
cp /dev/null /tmp/piksi.log
echo "Logs refreshed!"

При вызове скрипта фиксируется дата и время, после чего логи для Javad и MCR копируются в соответствующую папку в /home/CommonFiles/logs/. Для Piksi копируются только уже обработанный файл - piksi.obs.

[править] Хочу один скрипт для вызова всего!

И он есть у нас. Один скрипт, чтобы править всеми. Его название process_all:

#!/bin/bash

convert_all_to_rinex
solve_all_from_rinex
plot_all
send_mail
kill_logs_pid
refresh_logs
echo "All done!"


UPD. Время показало, что пока Piksi пишет "тяжелые" логи, они долго обрабатываются. В данном случае пришлось разделить скрипты. Обработка логов conv_n_solv:

#!/bin/bash

convert_all_to_rinex
solve_all_from_rinex

От этого немного похудел process_all:

#!/bin/bash

plot_all
send_mail
kill_logs_pid
refresh_logs
echo "All done!"

[править] А где же автоматизация?

Автоматизируется Сервер Статистики программированием его расписания с помощью планировщика crontab, для этого необходимо указать ему расписание,

crontab ./cron

заполненное специальным образом cron:

SHELL=/bin/bash
MAILTO=srtt
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/home/CommonFiles/scripts:/home/CommonFiles/progs/RTKlib:
00 00 * * * "bash -c `conv_n_solv`"
00 01 * * * "bash -c `process_all`"
15 01 * * * "bash -c `broadcast_javad`"
16 01 * * * "bash -c `start_javad_log`"
17 01 * * * "bash -c `start_mcr_log`"
18 01 * * * "bash -c `start_piksi_log`"

Обязательно указывается пользователь MAILTO, от которого будут выполнены запланированные команды, и пути нахождения необходимых программ PATH. Предполагается, что ранее сбор логов был запущен и 00:00 уже пойдет над ними работа.

Формат записи строчки расписания такой:

01       00    *             *       *             "bash -c `process_all`"
минута   час   день_месяца   месяц   день_недели   команда

Первое число обозначает минуту, второе час, то есть запуск всех процессов произойдет в одни минуту первого ночи. Звездочку вместо числа следует трактовать как слово каждый, то есть каждого дня месяца, каждого месяца, каждого дня недели. Тонкости настройки crontab легко ищутся в интернете, например, вот и вот.

Соответственно, скрипты на запись логов запускаются в 01:00, потому что процессы обработки могут затягиваться, часа точно должно хватить.

Посмотреть текущее расписание можно командой:

crontab -l

Удалить текущее расписание:

crontab -r


P.S.

Вот примерно так всё и работает!

[ Хронологический вид ]Комментарии

(нет элементов)

Войдите, чтобы комментировать.

Персональные инструменты
Пространства имён

Варианты
Действия
SRNS Wiki
Рабочие журналы
Приватный файлсервер
QNAP Сервер
Инструменты