original in de Stefan Blechschmidt
de to en Jürgen Pohl
en to tr:Erdal Mutlu
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.
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.
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 ;-)
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.
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.
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
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.
#!/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;
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.
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.
Ş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.
Farklı grafikler elde edebilmek için değiştirilmesi gereken sadece sorgulardır.
Son olarak, örneğimizin bel kemiğini oluşturan bazı SQL sorguları göstermek istiyorum.
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)
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.