Linux ile sıcaklık izleme (2. Bölüm)

ArticleCategory: [Choose a category, translators: do not translate this, see list below for available categories]

Software Development

AuthorImage:[Here we need a little image from you]

Stefan Blechschmidt

TranslationInfo:[Author + translation history. mailto: or http://homepage]

original in de Stefan Blechschmidt

de to en Jürgen Pohl

en to tr:Erdal Mutlu

AboutTheAuthor:[A small biography about the author]

Eğitimli bir elektrik teknisyeni olarak 1990 yılında kendimi bir bilgisayar destekli tasarım ve derleyici programın karşısında bir switch ve bir kontrol merkezi geliştirirken buldum. Açıkçası, o zamanlar bilinmeyen bir virüs tarafından etkilenmiştim ve bunda bir sorun yoktu.

Abstract:[Here you write a little summary]

Kasım 2003'teki Linux ile sıcaklık izleme yazısında, sıcaklık verilerini Linux'ta toplamaya yarayan bir elektronik devre tanıtmıştım. Verileri değerlendirebilmek için bir veritabanına yerleştirmemiz gereklidir.

Bu yazının tam olarak yararlı olabilmesi için, verileri sanaldoku ortamında grafiksel olarak gösterilmesini anlatacağız.

ArticleIllustration:[One image that will end up at the top of the article]

Başlık resmi

ArticleBody:[The main part of the article]

Ön şartlar

Bilgisayarınızda bazı uygulamalarının önceden yüklenmiş olması gerekmektedir.

Sizin de farkına vardığınız gibi, bu yazı Linux'ta ileri seviye bilgiye sahip olan kullanıcılar içindir. Henüz bu seviyeye ulaşmamış olanlar, bu yazıyı okuyunca ulaşacaklardır ;-)

Veritabanının yüklenmesi

MySQL veritabanı için, veritabanına ulaşmayı sağlayan mysql buruğu vardır. mysql -u root -p mysql buyruğu ile MySQL veritabanına bağlanabilirsiniz.

-u seçeneği ile veritabanı kullanıcısı belirtilmektedir. Son olarak da bağlanılmak istenilen veritabanı ismi belirtilir. Bizim durumumuzda bu, MySQL'in ana veritabanıdır.

Buyrukları verebileceğiniz mysql > imlecini elde edeceksiniz. İlk olarak veritabanında yer alan tabloları öğrenelim. Bunun için show tables; buyruğu kullanılmaktadır.

mysql> show tables;
+-----------------+
| Tables_in_mysql |
+-----------------+
| columns_priv    |
| db              |
| func            |
| host            |
| tables_priv     |
| user            |
+-----------------+
6 rows in set (0.00 sec)

Sıcaklık verilerimiz için bir veritabanı oluşturmamız gerekiyor. create database digidb buyruğu ile digidb adındaki veritabanımızı yaratmış oluruz. Diğer buyruklar başka bir yoldan verileceği için, exit buyruğu ile MySQL'in istemci ortamından çıkabiliriz.

Not:

MySQL'in genelde root adında bir sistem yöneticisi kullanıcısı vardır. Benimsenmiş değer olarak bu kullanıcı için geçişsözcüğü istenmemektedir. mysqladmin -u root -p password gizli buyruğu ile root kullanıcısının geçişsözcüğünü gizli olarak değiştirmiş oluruz.

Bu değişikliğin hayata geçirilebilmesi için ilgili sistem tablosunun MySQL suncusu tarafından tekrar okunması gerekiyor. Bunu geçekleştirmek için mysqladmin -u root -p flush-privileges buyruğu verilebilir. Bundan böyle, veritabanına erişmek için root kullanıcısı geçişsözcüğünü yazmak zorundadır.

MySQL'in istemci programının (mysql) yorumlayıcı ortamından buyruklar vermek biraz karışık olabilir. Bu yüzden MySQL, buyruklarınızı verebileceğiniz başka bir yötem sunmaktadır.

Bunu yapmak için SQL buyruklar bir dosyaya yazılmakta ve mysql buyruğuna "<" den sonra dosya adı verililmektedir.

Bunu göstermek için 0. alıcı için olan tabloyu yaratmaya yarayan buyruğu bir sensor0.sql dosyasına yazıyoruz:

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;

Ve aşağıdaki buyruğu veriyoruz:
mysql -u digitemp -p digitemp < sensor0.sql

İki adet algılayıcı kullandığımız için yapmamız gereken tek şey, dosyanın bir kopyasını alıp, CREATE TABLE sensor0 ifadesini CREATE TABLE sensor1 ile değiştirmektir.

SQL buyruklarını bir dosyaya yazıp vermenin yararını farketmiş olmalısınız.

Denetleme :

Yeni yaratılmış tabloları görebilmek için echo 'show tables' | mysql -u root -p digidb buyruğunu verebiliriz.

Herşeyi düzgün yaptıysak, buyruğun sonucu aşağıdaki gibi olmalıdır:

  Enter password:
  Tables_in_digidb
  sensor0
  sensor1

Veritabanımıza veri girşi yapmak

Verilerin veritabanına aktarılmasını küçük bir Perl programı aracılığı ile yapacağız. Veritabanı erişimi için Perl'ün DBI modülü kullanılacaktır.

Not:

Hertürlü uygulama için olan Perl modüllerini 'Comprehensive Perl Archive Network (Gelişmiş Perl arşiv ağı) (CPAN, http://www.cpan.org/)' dan elde edebilirsiniz. Bunların yüklenmesini anlatmayarak size
http://www.pro-linux.de/news/2002/0070.html
ve
http://www.linux-magazin.de/Artikel/ausgabe/1997/10/CPAN/cpan.html
adreslerini öneriyorum.
#!/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;

Programın açıklanması:

Aslında programın yaptığı çok fazla bir şey yok. Yaptığı iş, veritanına bağlanmak, digitemp'den gelen verileri okumak, gerekmeyen verileri atlayarak sadece gerekli olanları veritabanındaki tabloya yazmaktır.

Verileri sürekli olarak toplamak için, bir cron işi tanımlanmaktadır:

  0-59/15 * * * * root /root/bin/digitemp -a | /root/bin/digipipe.pl

Veri toplama hakkında söyleyeceklerimiz bu kadar. Şimdi sanaldoku arayüzüne geçebiliriz.

Perl ve CGI

Bu iş için Perl uygun bir ortam sunmaktadır.

İlk önce Apache'nin CGI programlarınının olduğu dizini bulmak gerekir. Bunu Apache'nin yapılandırma dosyasına bakarak bulabiliriz. <Directory /usr/lib/cgi-bin> şeklinde bir satır görmeniz gerek.

Grafik çıktıya geçmeden önce, en çok ölçülen verileri elde etmemizi sağlayan programı oluşturalım.

Bu programları bir alt düzünde toplamak yararlı olabilir. Ayrıca, programı çalıştırılabilir duruma getirmek için erişim haklarını chmod 755 program_adı şeklinde değiştirmek gerekir.

Oluşturulacak çıktıyı son veriyi elde edecek şekilde sınırlamamız ve bunu bir Perl-CGI programına yazmamız gerekmektedir. Bunu aşağıdaki SQL sorgusuyla yapabiliriz:

#!/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;

Örneğimiz en şık olanı değildir. Bu sadece bu işin Perl ile ne kadar kolay yapılabileceğini göstermektedir.

Grafik çıktı

chart

Şimdi çıktı üzerinde duralım. Programın (Programı indirmek için yazının sonuna bakınız.) oluşturduğu grafik eğrilerden meydana gelmektedir. Daha farklı gösterilimler için GD modüllerine bakınız.

Dahası, program Perl ile HTML çıktısı oluşturmaya yarayan CGI modülü kullanmaktadır. Bununla ilgili İnternette birçok açıklama vardır.

Programa geri dönecek olursak, onun bir ana ve iki alt programdan oluştuğunu görürüz. Alt programlardan biri SQL sorgularından, diğeri de grafiklerden sorumludur.

Ana kısımda saedce üç adet sorgu yapılmakta ve elde ettiği veriler alt programlara aktarılmaktadır.

  1. X ekseninin ölçeklendirilmesi
  2. İlk algılayıcının (sensor0) verileri
  3. İkinci algılayıcının (sensor1) verileri

Farklı grafikler elde edebilmek için değiştirilmesi gereken sadece sorgulardır.

SQL Sorguları

Son olarak, örneğimizin bel kemiğini oluşturan bazı SQL sorguları göstermek istiyorum.

En son beş ölçüm

    select tag, monat, zeit,
     DATE_FORMAT(dbtime,'%Y-%c-%d %H:%i:%s') as dbtime, messung
       from sensor0
       order by id desc
         limit 5;

Yılın en soğuk günü

    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

Yılın en sıcak günü

    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

Gün için ortalama değer hesaplanması

   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)

Sonuç

Ben herzaman Perl ile yazılan programların ne kadar basit olduğuna şaşırmıştım. Aslında programalar sıfırdan yazılmamış, biryerlerden alınmış, kopyalanmış, yani bunlar bir şekilde bir yerlerden o veya bu şekilde vardır.

Umarım, Perl, CGI ve MySQL konularına az da olsa bir ışık tutabilmişimdir.

İndirebileceklereniz

Bağlantılar ve Referanslar