| 
 | 
|  | 
| 
 | 
| эта страница доступна на следующих языках: English Castellano Deutsch Francais Nederlands Russian Turkce | 
|   автор Stefan Blechschmidt <sb(at)sbsbavaria.de> Об авторе: Будучи опытным электротехником, я нашел себя в 1990 на фронте рабочей станции CAD для разработки переключающей и управляющей станции. Очевидно, я заразился тогда неизвестным "вирусом", и это просто отлично. Перевод на Русский: Peter Demidov <p_demidov(at)rambler.ru> Содержание: | 
| Температурный мониторинг в Linux (часть 2)  Резюме: 
 В редакции от ноября 2003 года Temperature Monitoring With Linux я объяснил схему, которая позволяет собирать данные о температуре через Linux. Чтобы оценить данные о температуре, мы должны сохранить их в базе данных. Чтобы получить полностью пользу от этой статьи мы будем графически отображать данные через web-интерфейс. | 
Некоторые работающие приложения уже должны быть установлены на вашем компьютере
Как мы отмечаем, эта статья для отчати продвинутого пользователя Linux. Для тех, кто пока не относится к таким, это будет хорошим вступлением ;-)
В MySQL программа mysql обеспечивает интерфейс базы
    данных. С командой 
    mysql -u root -p mysql мы присоединяемся к монитору MySQL.
С ключём -u
    будет введено имя пользователя. Ключ 
    -u запросит пароль, и, наконец, БД, в которую необходимо
    войти. В нашем случае мы выбираем БД MySQL Manager.
 Вы получите приглашение mysql
    > для ввода команд SQL. Сначала нам необходимо узнать,
    какого типа таблицы находятся в БД. Команда
    show tables;
    делает это.
mysql> show tables; +-----------------+ | Tables_in_mysql | +-----------------+ | columns_priv | | db | | func | | host | | tables_priv | | user | +-----------------+ 6 rows in set (0.00 sec)
Теперь нам надо создать БД для наших данных о температуре.
    С помощью команды create database
    digidb мы генерируем нашу БД с именем digidb и
    командой exit мы можем
    выйти из монитора или могут быть введены дополнительные команды
    в другом случае.
MySQL имеет администратора, который в общем называется
    root. Инсталяция по умолчанию не требует пароля. Командой
    
    mysqladmin -u root -p password geheim мы меняем пароль
    для пользователя  root на geheim.
Чтобы активизировать эту модификацию, таблица администратора
    должна быть прочитана снова, мы делаем это при помощи команды 
    mysqladmin -u root -p flush-privileges. Теперь для
    пользователя root обеспечена проверка пароля при каждом
    обращении к БД.
Ввод команд через монитор очень сложен, однако, MySQL предлагает другую возможность ввести команды.
Чтобы сделать это мы набираем текстовый файл с командами SQL, добавляя "<" к команде mysql.
Чтобы это продемострировать, мы пишем текстовый файл для создания первой таблицы для сенсора 0.
В этом файле sensor0.sql мы сейчас пишем команды создания таблицы, это может выглядеть так.
CREATE TABLE sensor0 ( id int(11) NOT NULL auto_increment, monat char(3) NOT NULL default '', tag char(2) NOT NULL default '', dbtime timestamp(14) NOT NULL, zeit time NOT NULL default '00:00:00', messung decimal(4,2) NOT NULL default '0.00', PRIMARY KEY (id) ) TYPE=MyISAM;
Это будет введено при помощи:
     mysql -u digitemp -p digitemp
    < sensor0.sql
Поскольку мы используем 2 сенсора, нам необходимо только скопировать
    файл и изменить строрку CREATE TABLE
    sensor0 на  CREATE TABLE
    sensor1.
Очевидно, что ввод SQL команд посредством файла имеет реальные преимущества.
Чтобы показать вновь созданные таблицы мы используем команду:
    echo 'show tables' | mysql -u
    root -p digidb, конечно это также работает и наоборот.
Если мы сделали все правильно мы получим вывод:
Enter password: Tables_in_digidb sensor0 sensor1
Маленькая Perl-программа будет передавать данные в базу данных. Для этого будет использован наш первый модуль Perl (DBI), он предоставит нам методы доступа к БД.
#!/usr/bin/perl -w
#
# Digitemp preparing of  log file and saving in database
# sbs 2003-08-09
#
use DBI;
use strict;
# Initialize database
my $datasource = "dbi:mysql:database=digidb";
my $user = "root";
my $pass = "geheim";
my $db = DBI->connect($datasource, $user, $pass)
   or  "Verbindung zur Datenbank nicht möglich: " . $DBI::errstr;
# Filtering of Digitemp
while(<STDIN>) {
  chomp;
  # Skip output program name
  next if (m/Digi.*/);
  # Skip output blank line
  next if (m/^$/);
  # Skip all to Fahrenheit
  m/(.*).F.*/;
  my $templine = $1;
  # Divide temp line and save in variables
  my ($monat, $tag, $zeit, $sensor_txt, $sensor_nr, $grad_txt, $grad_wert)
  = split(/ /,$tempzeile);
  # Fill database
  $db->do( "insert into sensor$sensor_nr (monat, tag, zeit, messung)
  values ('$monat', '$tag', '$zeit','$grad_wert')")
    or die "do nicht möglich:  " . $db->errstr();
}# END- Digitemp filter
# close database
$db->disconnect;
    Программа не делает очень многого, она открывает базу данных, читает вывод, полученный от digitemp, отфильтровывает все, что нам не надо и пишет важные данные в правильную таблицу БД.
Непрерывный сбор данных производится с помощью хорошо испытаной работы cron:
0-59/15 * * * * root /root/bin/digitemp -a | /root/bin/digipipe.pl
Это все насчет сбора данных, теперь к web-интерфейсу.
Perl предлагает нам соответствующее окружение для этой задачи.
Во-первых нам надо знать директорию, где Apache обрабатывает
    свои CGI программы. Их можно найти в конфигурационных файлах
    Apache. Ищите строку вроде этой
    <Directory
    /usr/lib/cgi-bin>.
Перед тем, как мы начнем с графическим выводом, мы сперва создадим программу, которая обеспечит нас последними измерительными данными.
Было бы выгодно сохранить их в разные директории;
    вам также придется сделать ваши программы исполнимыми: chmod 755 
    programmname.
Нам необходимо ограничить вывод последних данных и ввод их в Perl-CGI программу. Это будет выполнено при помощи SQL-запроса.
#!/usr/bin/perl
use DBI;
use strict;
# Initialize database
my $datasource = "dbi:mysql:database=digidb";
my $user = "root";
my $pass = "geheim";
my $db = DBI->connect($datasource, $user, $pass)
   or  "Verbindung zur Datenbank nicht möglich: " . $DBI::errstr;
# database work parameter
my $sql;
my $sth;
# Sensor work parameter
my $temp;
my $zeit;
#Prepare HTML output
print "Content-type: text/html\n\n";
# Output of individual sensors measurements
  $sql = "select messung, zeit from sensor$i order by id desc limit 1;";
  $sth = $db->prepare($sql)
    or die "prepare nicht möglich";
  $sth->execute()
    or die "execute nicht möglich";
  ($temp, $zeit) = $sth->fetchrow_array();
  $sth->finish();
  print "<p>Temperatur Sensor$i: <b>[$temp]</b> $zeit</p>";
}
# Close database
$db->disconnect;
    Этот пример не самый изящный, он должен только демонстрировать как просто может быть выполнена эта работа с Perl.
Теперь давайте возьмемся за графический вывод. Программа (ссылка в конце статьи) генерирует графики кривых, для других графиков ищите другие GD модули.
Более того, программа использует CGI модуль, который позволяет осуществляет HTML-вывод в Perl. Я ссылаюсь здесь на многочисленные описания этого в Internet.
Вернемся к программе. Она включает главную часть и две подпрограммы. Одна подпрограмма ответственна за SQL запрос, вторая - за графики.
Главной частью выполняются только три запроса и данные передаются подпрограммам.
Требуется изменить только запросы, чтобы генерировать другой графический вывод.
Наконец, я хочу показать вам несколько SQL запросов, посколльку они являются главным предметом этого примера.
    select tag, monat, zeit,
     DATE_FORMAT(dbtime,'%Y-%c-%d %H:%i:%s') as dbtime, messung
       from sensor0
       order by id desc
         limit 5;
     
    select tag, monat, zeit,
     DATE_FORMAT(dbtime,'%Y-%c-%d %H:%i:%s') as dbtime, messung
       from sensor1
       where YEAR(dbtime) = YEAR(NOW())
         order by messung asc
         limit 1
     
    select tag, monat, zeit,
     DATE_FORMAT(dbtime,'%Y-%c-%d %H:%i:%s') as dbtime, messung
       from sensor1
       where YEAR(dbtime) = YEAR(NOW())
         order by messung desc
         limit 1
     
   select day, month, YEAR(dbtime) as Jahr,
     sum(messung)/count(*) as Durchschnitt
        from sensor1
       where YEAR(dbtime) = YEAR(NOW())
       and DAYOFMONTH(dbtime)= DAYOFMONTH(NOW())
       and MONTHNAME(dbtime) = MONTHNAME(NOW())
         group by DAYOFMONTH(dbtime)
     
Меня всегда удивляет, как это просто - писать программы на Perl. Вообще-то, они не написаны, а скопированы, а их секции скомбинированы; так или иначе все они уже где-нибудь существуют в одной или другой форме.
Я надеюсь, у меня получилось обеспечить вам маленький проблеск в теме Perl, CGI и MySQL.
| 
 | 
| Webpages maintained by the LinuxFocus Editor team © Stefan Blechschmidt, FDL LinuxFocus.org | Translation information: 
 | 
2004-08-06, generated by lfparser version 2.43