Konuyu Oyla:
  • Derecelendirme: 5/5 - 2 oy
  • 1
  • 2
  • 3
  • 4
  • 5
Raspberry Pi, MQTT ve Delphi
#1
Karantina günlerini değerlendirmek için evdeki Raspberry Pi ile bir şeyler yapmaya karar verdim. 

Raspberry Pi'den veri alıp bunu PC'deki programda göstermek için çok basit bir örnek:

Raspberry Pi gibi IOT cihazlarla haberleşmek için en yaygın kullanılan protokol MQTT'dir. Daha önce bir çok konu içerisinde ismi geçti. Hatta burada @Fesih ARSLAN,  TMS'nin MQTT bileşeni ile yapılmış bir örnek paylaştı. Bu bileşen ücretli olduğu için ben ücretsiz çözüm yolu göstermeye çalışacağım.

MQTT:
MQTT protokolü; TCP/IP bağlantısı ile yayıncı(publisher)-abone(subscriber) yapısında çalışır. Fakat burada hem yayıncı hem de abone istemci(client) durumundadır. MQTT ile gönderilen mesajları yönetmek için bir sunucuya ihtiyaç vardır. Buna da broker denilir. Broker mesajların dağıtımından/adreslenmesinden sorumludur. Aşağıdaki şekilde anlaşılması daha kolay olur sanırım:


mqtt_subhub.jpg


Benim örneğimde raspberry publisher, Delphi'de yazacağım program subscriber olacak. Broker'ı da programla aynı PC'ye kuracağım. 
Broker yukarıda da bahsettiğim gibi MQTT'nin sunucusu. Bu işi yapan bir çok ücretsiz uygulama bulabilirsiniz. Ben çok yaygın olan mosquitto'yu kullandım. Şu adresten indirebilirsiniz:
https://mosquitto.org/download/

Genelde MQTT kullanımı, IOT'ye bağlı olan sensör(ler)den alınan veriyi yayınlamak(publish) şeklindedir. Ben örneğin basit olması için sensörden veri almak yerine raspberry'nin CPU sıcaklığını mesaj olarak gönderdim. 
Raspberry'de kolaylık olsun diye Python kullandım Smile  İşin Python kısmında detaya girmeyip kodları paylaşıyorum:
import paho.mqtt.publish as publish
from time import sleep
from json import dumps
from utils import getSerial, getTemperature

while True:
    message = {
        "serial": getSerial(),
        "temp": getTemperature()
    } 
    publish.single("temperature", dumps(message), hostname="192.168.1.17")
    sleep(1)

Yukarıdaki Python kodları; her saniye, cihazın seri numarasını ve CPU sıcaklığını JSON formatında MQTT mesajı olarak belirlediğimiz IP adresine (broker'a) gönderiyor.


Gelelim işin Delphi kısmına Smile
Delphi'de MQTT kullanmak için Github'da bir çok seçenek mevcut. Ben şurayı kullanıyorum:
https://github.com/jamiei/Delphi-TMQTT2

Bunu bilgisayarımıza indirip TMQTT klasörünü Delphi'de Library Path'e eklemeliyiz. Ayrıca bu kütüphane, benim yıllardır kullandığım Synapse adlı bir socket kütüphanesine ihtiyaç duyuyor. Synapse'yi kendi web sayfasından indirebilirsiniz. Ama ben güncel olması bakımından şuradan indirmenizi tavsiye ederim:
https://sourceforge.net/p/synalist/code/...ree/trunk/
İndirdikten sonra klasörü Library Path'e eklemeyi unutmayın.

Gelelim kodlara:
procedure TForm1.FormShow(Sender: TObject);
begin
 MQTT := TMQTT.Create('127.0.0.1', 1883);
 MQTT.OnPublish := MessageReceived;
 if MQTT.Connect then
   MQTT.Subscribe('temperature', 0);
end;

procedure TForm1.MessageReceived(Sender: TObject; topic, payload: Ansistring);
var
 jsonObj: TJSONObject;
begin
 try
   jsonObj := TJSONObject.ParseJSONValue(payload) as TJSONObject;
   lblSerial.Caption := jsonObj.GetValue<string>('serial');
   lblTemp.Caption := jsonObj.GetValue<string>('temp');
 finally
   jsonObj.Free;
 end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 MQTT.Disconnect;
 MQTT.Free;
end;

Anlaşılabilir olması için kodları mümkün olduğunca kısa tutmaya çalıştım ve hata kontrolü vs. ile uğraşmadım.
Kısaca açıklamak gerekirse; formumuz gösterilirken TMQTT sınıfından bir örnek oluşturuyoruz ve broker'ın bulundupu IP ve portu parametre olarak veriyoruz. Bir mesaj geldiğinde bileşenin OnPublish olayı tetiklenir. Bu durumda bizim MessageReceived prosedürümüz çalışacak. Hatırlarsanız gönderilen mesaj JSON formatında idi. Bunu parse edip ekranda ilgili yerlere yazıyoruz.
Ekran görüntüsünü aşağıda görebilirsiniz.


Ek Dosyalar Resimler
   
There's no place like 127.0.0.1
WWW
Cevapla
#2
Teşekkürler @SimaWB hocam.
İşin ana başlıklarını sade bir şekilde anlatan, gösteren çok güzel bir makale olmuş. Bu tip teknolojiler ile uğraşmaya başlayanların en çok zorlanacakları noktalara ışık tuttunuz.
İşin mantığını anlatma ve örneklendirme harika olmuş.
Cevapla
#3
Elinize saglık. Teşekkürler
Cevapla
#4
Elinize sağlık
Muharrem ARSLAN
WWW
Cevapla
#5
Elinize sağlık hocam.
Ne kadar sıcak bir işlemci o öyle  Smile
Cevapla
#6
Harika bir giris olmus tesekurler. Arduino ornekleri de isteriz.
Cevapla
#7
Sizler de sağolun arkadaşlar.

@Mr.Developer, standby'da böyle, sen bir de işlem yaparken gör Sad

@Hayati, Raspberry'ciyim ben Smile
There's no place like 127.0.0.1
WWW
Cevapla
#8
(04-05-2020, Saat: 09:26)SimaWB Adlı Kullanıcıdan Alıntı: Karantina günlerini değerlendirmek için evdeki Raspberry Pi ile bir şeyler yapmaya karar verdim. 

Raspberry Pi'den veri alıp bunu PC'deki programda göstermek için çok basit bir örnek:

Raspberry Pi gibi IOT cihazlarla haberleşmek için en yaygın kullanılan protokol MQTT'dir. Daha önce bir çok konu içerisinde ismi geçti. Hatta burada @Fesih ARSLAN,  TMS'nin MQTT bileşeni ile yapılmış bir örnek paylaştı. Bu bileşen ücretli olduğu için ben ücretsiz çözüm yolu göstermeye çalışacağım.

MQTT:
MQTT protokolü; TCP/IP bağlantısı ile yayıncı(publisher)-abone(subscriber) yapısında çalışır. Fakat burada hem yayıncı hem de abone istemci(client) durumundadır. MQTT ile gönderilen mesajları yönetmek için bir sunucuya ihtiyaç vardır. Buna da broker denilir. Broker mesajların dağıtımından/adreslenmesinden sorumludur. Aşağıdaki şekilde anlaşılması daha kolay olur sanırım:


subpub.234deeff.png


Benim örneğimde raspberry publisher, Delphi'de yazacağım program subscriber olacak. Broker'ı da programla aynı PC'ye kuracağım. 
Broker yukarıda da bahsettiğim gibi MQTT'nin sunucusu. Bu işi yapan bir çok ücretsiz uygulama bulabilirsiniz. Ben çok yaygın olan mosquitto'yu kullandım. Şu adresten indirebilirsiniz:
https://mosquitto.org/download/

Genelde MQTT kullanımı, IOT'ye bağlı olan sensör(ler)den alınan veriyi yayınlamak(publish) şeklindedir. Ben örneğin basit olması için sensörden veri almak yerine raspberry'nin CPU sıcaklığını mesaj olarak gönderdim. 
Raspberry'de kolaylık olsun diye Python kullandım Smile  İşin Python kısmında detaya girmeyip kodları paylaşıyorum:
import paho.mqtt.publish as publish
from time import sleep
from json import dumps
from utils import getSerial, getTemperature

while True:
    message = {
        "serial": getSerial(),
        "temp": getTemperature()
    } 
    publish.single("temperature", dumps(message), hostname="192.168.1.17")
    sleep(1)

Yukarıdaki Python kodları; her saniye, cihazın seri numarasını ve CPU sıcaklığını JSON formatında MQTT mesajı olarak belirlediğimiz IP adresine (broker'a) gönderiyor.


Gelelim işin Delphi kısmına Smile
Delphi'de MQTT kullanmak için Github'da bir çok seçenek mevcut. Ben şurayı kullanıyorum:
https://github.com/jamiei/Delphi-TMQTT2

Bunu bilgisayarımıza indirip TMQTT klasörünü Delphi'de Library Path'e eklemeliyiz. Ayrıca bu kütüphane, benim yıllardır kullandığım Synapse adlı bir socket kütüphanesine ihtiyaç duyuyor. Synapse'yi kendi web sayfasından indirebilirsiniz. Ama ben güncel olması bakımından şuradan indirmenizi tavsiye ederim:
https://sourceforge.net/p/synalist/code/...ree/trunk/
İndirdikten sonra klasörü Library Path'e eklemeyi unutmayın.

Gelelim kodlara:
procedure TForm1.FormShow(Sender: TObject);
begin
 MQTT := TMQTT.Create('127.0.0.1', 1883);
 MQTT.OnPublish := MessageReceived;
 if MQTT.Connect then
   MQTT.Subscribe('temperature', 0);
end;

procedure TForm1.MessageReceived(Sender: TObject; topic, payload: Ansistring);
var
 jsonObj: TJSONObject;
begin
 try
   jsonObj := TJSONObject.ParseJSONValue(payload) as TJSONObject;
   lblSerial.Caption := jsonObj.GetValue<string>('serial');
   lblTemp.Caption := jsonObj.GetValue<string>('temp');
 finally
   jsonObj.Free;
 end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 MQTT.Disconnect;
 MQTT.Free;
end;

Anlaşılabilir olması için kodları mümkün olduğunca kısa tutmaya çalıştım ve hata kontrolü vs. ile uğraşmadım.
Kısaca açıklamak gerekirse; formumuz gösterilirken TMQTT sınıfından bir örnek oluşturuyoruz ve broker'ın bulundupu IP ve portu parametre olarak veriyoruz. Bir mesaj geldiğinde bileşenin OnPublish olayı tetiklenir. Bu durumda bizim MessageReceived prosedürümüz çalışacak. Hatırlarsanız gönderilen mesaj JSON formatında idi. Bunu parse edip ekranda ilgili yerlere yazıyoruz.
Ekran görüntüsünü aşağıda görebilirsiniz.

Merhaba

Örnek uygulamayı localhost bilgisayarda çalıştırıp veri alıp gönderebiliyorum.
Fakat yerel ağdaki başka bir pcden connect olamıyorum. VPS e kurup denediğimde de aynı sonuç bağlantı yapılamıyor.

1883 portuna izin verdim yine uzak bağlantı sağlanmadı. Güvenlik duvarını her iki pc de kapattım yine de bağlanamadı.
Raspberry pi den dednedim yine connection hatası alıyorum. Bu örnek uygulamada eksik olan nedir? Kullanıcı adı ve şifre girmem gerekli mi?

İyi çalışmalar.
   
Cevapla
#9
Kullanıcı adı şifre gerekmiyor. Gerekli olsa yazardım. Ayrıca yine gerekli olsa siz kendi bilgisayarınızda mesaj alabildiğinizi belirtiyorsunuz.

Publisherınızı nasıl yazdınız, brokerınız nerede kurulu, Mosquitto mu kullandınız vs. yukarıda yazılanların bir sürü bileşeni var. O yüzden hatanın kaynağını bilemiyorum. Ama bildiğim şey; tüm paylaşımlarımı muhakkak önce deneyip sonra yazıyorum  Shy
There's no place like 127.0.0.1
WWW
Cevapla
#10
(27-01-2021, Saat: 21:36)SimaWB Adlı Kullanıcıdan Alıntı: Kullanıcı adı şifre gerekmiyor. Gerekli olsa yazardım. Ayrıca yine gerekli olsa siz kendi bilgisayarınızda mesaj alabildiğinizi belirtiyorsunuz.

Publisherınızı nasıl yazdınız, brokerınız nerede kurulu, Mosquitto mu kullandınız vs. yukarıda yazılanların bir sürü bileşeni var. O yüzden hatanın kaynağını bilemiyorum. Ama bildiğim şey; tüm paylaşımlarımı muhakkak önce deneyip sonra yazıyorum  Shy

Verdiğiniz Delphi uygulama örneğini hem kendi bilgisayarımda hem de VPS de aynı anda çalıştırıyorum. vps üzerinde çalışan localhost hostname ile çalışıyor.
Kendi bilg.daki vps ip adresine hiç bağlanamıyor.Connect dediğimide uygulama kilitleniyor. Broker VPS üzerinde kurulu.Mosquitto kullanıyorum.

procedure TfMain.btnConnectClick(Sender: TObject);
begin
 MQTT := TMQTT.Create(eIP.Text, StrToInt(ePort.Text));
 MQTT.WillTopic := '/clients/will';
 MQTT.WillMsg := 'Broker died!';
 // Events
 MQTT.OnConnAck := GotConnAck;
 MQTT.OnPublish := GotPub;
 MQTT.OnPingResp := GotPingResp;
 MQTT.OnSubAck := GotSubAck;
 MQTT.OnUnSubAck := GotUnSubAck;
 MQTT.OnPubAck := GotPubAck;

 if MQTT.Connect then
   mStatus.Lines.Add('Connected to ' + eIP.Text + ' on ' + ePort.Text)
 else
   mStatus.Lines.Add('Failed to connect');
end;
procedure TfMain.btnPublishClick(Sender: TObject);
begin
 if (Assigned(MQTT)) then
   begin
     MQTT.Publish(eTopic.Text, eMessage.Text);
     mStatus.Lines.Add('Published');
   end;
end;
Cevapla


Konu ile Alakalı Benzer Konular
Konular Yazar Yorumlar Okunma Son Yorum
  Delphi RabbitMq 3ddark 8 4.233 21-11-2022, Saat: 18:26
Son Yorum: 3ddark
  Nodemcu ile Delphi json haberleşme arsl01 10 9.893 24-12-2021, Saat: 09:25
Son Yorum: arsl01
  OpenAI GPT3 Nedir? Delphi ile Kullanımı Tan Ay 1 2.033 07-05-2021, Saat: 15:40
Son Yorum: mrmarman
  Delphi ve PLC Haberleşmesi hk. Abdullah ILGAZ 12 15.158 24-08-2020, Saat: 19:02
Son Yorum: Onur
Thumbs Up Delphi 10.3 ile mobil uygulamadan esp32 cihazına bluetooth le ile metin gönderme AlpDmr 8 11.343 19-04-2020, Saat: 13:26
Son Yorum: AlpDmr



Konuyu Okuyanlar: 1 Ziyaretçi