Sıcaklık Alarm Uygulaması (Python XML Parsing)

Merhabalar bu makalemde Ethernet Termometrelerden sıcaklık değerlerini okuyarak limit aşımı durumumda sesli alarm oluşturan ufak bir uygulamayı ele aldım. 

Murat Python1

 

Piyasada satılan bir çok ip tabanlı sıcaklık ölçer ürün SNMP destekli olup limit aşımlarında gerek SNMP ile gerek e-posta veya SMS ile uyarı göndermektedir. Ancak gördüğüm kadarı ile ağ üzerinden uzak bir yerde sesli alarm oluşturmak için kullanılan ürün sayısı son derece az. Olanlarda ise izleme ve alarm yazılımını ayrıca satın almak gerekiyor. 

Seçtiğim termometre HWG-STE cihazıdır. Fikir edinmek için Online DEMO‘suna bakabilirsiniz. Bu cihaz DEMO’sunda gördüğünüz üzere sıcaklığı ölçüp kullanıcıya bir web arayüzü ile anlık olarak sunuyor. Aynı zamanda SNMP/E-mail ile haberde gönderebiliyor. Biz bu cihazın web arayüzü üzerinden güncel sıcaklık değerini okuyup 22 derecenin üzerinde sıcaklık okuduğumuzda alarmı çaldıracağız. 

Termometre arayüzü aşağıdaki gibi : 

term

Bu ufak uygulamayı bir kaç saat içinde tasarladım bu kısa sürede olmasının en büyük sebebi kullanılan yazılım dilinin pratikliğe olanak sağlamasıdır. Bir yandan tv’de dizimi izlerken bir yandan da Phyton Shell’e girdileri yaptım. Burada ifade etmek istediğim Python’un yaratıcı bir düşünce ile kısa sürelerde ve zahmetsiz olarak neler yapabildiğini vurgulamaktır. 

Tüm süreci aşağıdaki akışa göre ilerleyeceğiz: (Resme tıklayarak büyütebilirsiniz) 

  • Programın çalışabilmesi için gereksinimlerin kontrolü,
  • Kullanıcıdan veri girişi istenmesi,
  • Verilerin doğruluğu için onay alınması,
  • Verinin okunması ve süzülmesi
  • Verinin kullanıcıya sunulması
  • Limitler ve alarm oluşturulması.

Sürec

Başlangıç aşamasında gerekli modülleri import edip sonrasında versiyon kontrolü yapmamız gerekiyor.  Kullanacağımız modüller: 

import urllib, urllib.request, findall, BeautifulSoup ——>WEB arayüzün okunması ve derlenmesi için. (XML Parsing işlemi için)

import sys import os  from io import StringIO, BytesIO —-> Versiyon Kontrolü vs. için.

import winsound, import time—-> İstediğimiz frekans ve periyotta ses çalabilmek için.

Modüllerin import edilmesinden sonra gerekli pyhton sürümünü kontrol edeceğiz. Biz uygulamamız Pyhton 3 ile yazdık bu sebeple 3 ve üzeri Python sürümleri ile çalıştırabiliriz. 

versiyon = (sys.version_info.major) 

Burada ben 3  üzeri olsun da ne olursa olsun şeklinde düşündüm ve versiyon numarasını bir değişkene atadım . Ancak birebir istenen versiyon için minor’de kullanabilirsiniz. Örn:3.1.2 vb.

Sonrasında basit bir döngü ile versiyon kontrolü yapıyoruz: 

while True:
     if versiyon < 3:
           print ("Bu program Phython 3 altındaki sürümlerde kullanılamaz")
           quit()
     else:
           print("Programı kullanmak için uygun sürüme sahipsiniz.")
           break

Versiyon uyumluluğunu kontrol ettiğimize göre kullanıcıdan sıcaklık sensor web arayüzünün ip adresini isteyeceğiz. 

Önce doğrulama sürecinde kullanacağımız evet (e) ve EVET(e) string parametlerini oluşturuyoruz. 

sorgu_dogru1 = ("E")
sorgu_dogru2 = ("e")

Sonra basit bir döngü ile bilgi alıp doğruluyoruz.: 

while True:
      sensor_ip = input("HTTP:// kullanmadan IP Giriniz : ")
      sensor_values_xml = str("http://"+sensor_ip+"/values.xml")
      print ("Adres\" "+ sensor_values_xml + " \" olacaktır")
      sorgu = input("Doğruluğunu onaylıyor musunuz ? E/H-----:")
      if sorgu == sorgu_dogru1 or sorgu==sorgu_dogru2:
            print("Sensor'e erişim sağlanacak")
            break
      else:
            print("Adresi doğru şekilde tekrar giriniz")

Kullanıcıdan gerekli bilgiyi aldık ve doğru olduğunu teyit ettirdik. Şimdi WEB arayüze erişip gerekli sıcaklık değerini. Bu makalede kullandığım termometrenin arayüzünü XML olarak görebileceğimiz bir URL’si var. (http://ste.hwg.cz/values.xml) Ve yukarıda dikkat ettiyseniz kullanıcıdan aldığımız adresin sonuna bir ekleme yaptım.

Şimdi arayüze erişiyorum, değerleri alıyorum ve kullanıcıya sunalbilmek için text isimli bir decoder oluşturuyorum.

sensor_arayuz = urllib.request.urlopen(sensor_values_xml)
html = sensor_arayuz.read() 
text = html.decode() #Decode işlemi

Şimdi html’in nasıl göründüğüne bir bakalım : 

print (html) 
b'<?xml version=”1.0″ encoding=”utf-8″?>\n<val:Root xmlns:val=”http://www.hw-group.com/XMLSchema/ste/values.xsd”>\n<Agent>\n\t<Version>2.0.7</Version>\n\t<XmlVer>1.01</XmlVer>\n\t<DeviceName>HWg-STE</DeviceName>\n\t<Model>33</Model>\n\t<vendor_id>0</vendor_id>\n\t<MAC>00:0A:59:00:D1:17</MAC>\n\t<IP>193.179.198.222</IP>\n\t<MASK>255.255.255.240</MASK>\n\t<sys_name>HWg-STE</sys_name>\n\t<sys_location></sys_location>\n\t<sys_contact>HWg-STE:For more information try http://www.hw-group.com</sys_contact>\n</Agent>\n<SenSet>\n\t<Entry>\n\t\t<ID>215</ID>\n\t\t<Name>Sensor 215</Name>\n\t\t<Units>C</Units>\n\t\t<Value>25.2</Value>\n\t\t<Min>10.0</Min>\n\t\t<Max>60.0</Max>\n\t\t<Hyst>0.0</Hyst>\n\t\t<EmailSMS>0</EmailSMS>\n\t\t<State>1</State>\n\t</Entry>

Şimdi beutifulsoup obje oluşturup birde öyle bakalım. : 

a = BeautifulSoup (html)

>>> print (a)
<?xml version=”1.0″ encoding=”utf-8“?>
<val:root xmlns:val=”http://www.hw-gro….xsd”>
<agent>
<version>2.0.7</version>
<xmlver>1.01</xmlver>
<devicename>HWg-STE</devicename>
<model>33</model>
<vendor_id>0</vendor_id>
<mac>00:0A:59:00:D1:17</mac>
<ip>193.179.198.222</ip>
<mask>255.255.255.240</mask>
<sys_name>HWg-STE</sys_name>
<sys_location></sys_location>
<sys_contact>HWg-STE:For mor…s_contact>
</agent>
<senset>
<entry>
<id>215</id>
<name>Sensor 215</name>
<units>C</units>
<value>25.2</value>
<min>10.0</min>
<max>60.0</max>
<hyst>0.0</hyst>
<emailsms>0</emailsms>
<state>1</state>
</entry>

BeatifulSoup’un ne iş yaptığını buraya  bakarak anlamak yeterli olur. (Tree şeklinde açıyor.)

Şimdi daha spesifik olarak istediğimiz değere yönelik bakalım. Sıcaklık değerimiz Value tag’leri içinde duruyor : 

print (a.value)
<value>25.2</value>

Sıcaklık değerini bize hala XML olarak veriyor. Burada yukarıda oluşturduğumuz “text” isimli decoder bize yardımcı olacak  : 

print (a.value.text)

25.2

Artık string olarak sıcaklık değerini alabiliyoruz. Alarm’ı tetiklemek için bir döngü daha oluşturacağız. Ama sayısal bir döngü olacağı için aldığımız değeri sayısal bir değer olacak şekilde dönüştürebiliriz. 

SICAKLIK = float(a.value.text)

25.2

Burada isterseniz yakın olduğu tam sayıya yuvarlama işlemi yapabilirsiniz. Math modünü import edip ceil fonksiyonunu kullanabilirsiniz.

Şimdi döngü oluşturalım : 

if SICAKLIK > 22:
     import winsound
     import time

     winsound.Beep(5000,1000)
     winsound.Beep(5000,1000)
     winsound.Beep(5000,1000)
     winsound.Beep(5000,1000)
     time.sleep(0.1)
     winsound.Beep(5000,1000)
     winsound.Beep(5000,1000)
     winsound.Beep(5000,1000)
     winsound.Beep(5000,1000)
     time.sleep(0.1)
     winsound.Beep(5000,1000)
     winsound.Beep(5000,1000)
     winsound.Beep(5000,1000)
     winsound.Beep(5000,1000)
     time.sleep(0.9)
     winsound.Beep(5000,1000)
     winsound.Beep(5000,1000)
     winsound.Beep(5000,1000)
     winsound.Beep(5000,1000)
     time.sleep(0.9)
     winsound.Beep(5000,1000)
     winsound.Beep(5000,1000)
     winsound.Beep(5000,1000)
     winsound.Beep(5000,1000)

          for i in range(100):
          winsound.Beep(1000, 2000)
          time.sleep(0.1)

          for i in range(200):
          winsound.Beep(10000, 1000)
          time.sleep(0.1)

Bu ses son derece rahatsız edici , sistemde herhangi bir problem olması durumumda müdahale etmek için bekleyen birisinin hemen dikkatini çekeceğinden emin olabilirsiniz. Eğer çok rahatsız ediyorsa sevdiğimiz bir alarm sesi oluşturabiliriz : 

winsound.PlaySound (“C:/Python34/feder-goodbye_remix.wav“, winsound.SND_FILENAME)

Bu sadece bir kere kontrol etmek için oluşturuldu real-time kontrol işlemi için olan her şeyi burada paylaşmıyorum. 

Herkese sorunsuz günler diliyorum.

Murat KAYAPINAR
Elect. Eng. & Comm. Eng.

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir