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ş olamsı 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 komutu vardır. mysql -u root -p mysql komutuyla 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.

Komutları girebileceğiniz mysql > imlecini elde edeceksiniz. İlk olarak veritabanında yer alan tabloları öğrenelim. Bunun için show tables; komutu 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 komutuyla digidb adındaki veritabanımızı yaratmış oluruz. Diğer komutlar başka bir yoldan girileceği için, exit komutuyla MySQL'in istemci ortamından çıkabiliriz.

Not:

MySQL'in genelde root adında bir sistem yönetici 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 komutuyla 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 komutu kullanılabilir. 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 komutlar girmek biraz karışık olabilir. Bu yüzden MySQL, komutların çalıştırılabileceği başka bir yötem sunmaktadır.

Bunu yapmak için SQL komutları bir dosyaya yazılmakta ve mysql komutuna "<" dan sonra dosya adı verilerek çalıştırılabilir.

Bunu göstermek için 0. alıcı için olan tabloyu yaratmaya yarayan komutu 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 komutla çalıştırıyoruz:
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 komutların bir dosyaya yazıp çalıştırılmaının yararını farketmiş olmalısınız.

Denetleme :

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

Herşeyi düzgün yaptıysak, komutun çıktısı 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;

Kısaca 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, denenmiş olan cron işi aracılığı ile yapılmaktadı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 bakalım.

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 ö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.

Fazlası, 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ısının (sensor0) verileri
  3. İkinci algılayıcısı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