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ş 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 ;-)
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.
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.
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
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, 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.
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.
Ş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.
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.