2022年12月27日 星期二

MQTT and Python For Beginners -Subscribing To Topics (訂閱主題)

 MQTT and Python For Beginners -Tutorials

源自於 http://www.steves-internet-guide.com/into-mqtt-python-client/

Subscribing To Topics (訂閱主題)

To subscribe to a topic you use the subscribe method of the Paho MQTT Class object.

The subscribe method accepts 2 parameters – A topic or topics and a QOS (quality of Service) as shown below with their default values.

subscribe(topic, qos=0)


We will now subscribe to topics and in this example we will subscribe to the topic house/bulb1 which is also the same topic that I’m publishing on.

Doing this lets us see the messages we are publishing but we will need to subscribe before we publish.

So our script outline becomes.

  1. Create new client instance
  2. Connect to broker
  3. Subscribe to topic
  4. Publish message

Our new example script is shown below, and I have inserted some print statements to keep track of what is being done.


import paho.mqtt.client as mqtt #import the client1
broker_address="192.168.1.184" 
#broker_address="iot.eclipse.org"
print("creating new instance")
client = mqtt.Client("P1") #create new instance
print("connecting to broker")
client.connect(broker_address) #connect to broker
print("Subscribing to topic","house/bulbs/bulb1")
client.subscribe("house/bulbs/bulb1")
print("Publishing message to topic","house/bulbs/bulb1")
client.publish("house/bulbs/bulb1","OFF")

If we run the script this is what we see:




import paho.mqtt.client as mqtt #import the client1

broker_address="broker.hivemq.com" 

#broker_address="iot.eclipse.org"

print("creating new instance")

client = mqtt.Client("P1") #create new instance

print("connecting to broker")

client.connect(broker_address) #connect to broker

print("Subscribing to topic","house/bulbs/bulb1")

client.subscribe("house/bulbs/bulb1")

print("Publishing message to topic","house/bulbs/bulb1")

client.publish("house/bulbs/bulb1","OFF")


>>> %Run Beginners_2.py
creating new instance
connecting to broker
Subscribing to topic house/bulbs/bulb1
Publishing message to topic house/bulbs/bulb1

where is the message that I published?
看不到發行的訊息

所以要callback 

When a client subscribes to a topic it is basically telling the broker to send messages to it that are sent to the broker on that topic.

The broker is ,in effect, publishing messages on that topic.

When the client receives messages it generate the on_message callback.

To view those messages we need to activate and process the on_message callback.

However at this stage it may be better to just accept them and proceed with the script.

To process callbacks you need to:

  1. Create callback functions to Process any Messages
  2. Start a loop to check for callback messages.

The client docs describe the on_message callback and the parameters it excepts.

Here is my callback function, which basically just prints the received messages:

def on_message(client, userdata, message):
    print("message received " ,str(message.payload.decode("utf-8")))
    print("message topic=",message.topic)
    print("message qos=",message.qos)
    print("message retain flag=",message.retain)

Note the message parameter is a message class with members topic, qos, payload, retain.

I.e message.topic will give you the topic.

Now we need to attach our callback function to our client object as follows:

client.on_message=on_message        #attach function to callback

and finally we need to run a loop otherwise we won’t see the callbacks. The simplest method is to use loop_start() as follows.

client.loop_start()    #start the loop

We also need to stop the loop at the end of the script (loop_stop()), and in addition wait a little to give the script time to process the callback, which we accomplish using the time.sleep(4) function.

This what our completed example script now looks like:


import paho.mqtt.client as mqtt #import the client1
import time
############
def on_message(client, userdata, message):
    print("message received " ,str(message.payload.decode("utf-8")))
    print("message topic=",message.topic)
    print("message qos=",message.qos)
    print("message retain flag=",message.retain)
########################################
broker_address="192.168.1.184"
#broker_address="iot.eclipse.org"
print("creating new instance")
client = mqtt.Client("P1") #create new instance
client.on_message=on_message #attach function to callback
print("connecting to broker")
client.connect(broker_address) #connect to broker
client.loop_start() #start the loop
print("Subscribing to topic","house/bulbs/bulb1")
client.subscribe("house/bulbs/bulb1")
print("Publishing message to topic","house/bulbs/bulb1")
client.publish("house/bulbs/bulb1","OFF")
time.sleep(4) # wait
client.loop_stop() #stop the loop

If you run the script you should see the following


import paho.mqtt.client as mqtt #import the client1
import time
############
def on_message(client, userdata, message):
    print("message received " ,str(message.payload.decode("utf-8")))
    print("message topic=",message.topic)
    print("message qos=",message.qos)
    print("message retain flag=",message.retain)
########################################
broker_address="broker.hivemq.com"
#broker_address="iot.eclipse.org"
print("creating new instance")
client = mqtt.Client("P1") #create new instance
client.on_message=on_message #attach function to callback
print("connecting to broker")
client.connect(broker_address) #connect to broker
client.loop_start() #start the loop
print("Subscribing to topic","house/bulbs/bulb1")
client.subscribe("house/bulbs/bulb1")
print("Publishing message to topic","house/bulbs/bulb1")
client.publish("house/bulbs/bulb1","OFF")
time.sleep(4) # wait
client.loop_stop() #stop the loop

>>> %Run Beginners_4.py
creating new instance
connecting to broker
Subscribing to topic house/bulbs/bulb1
Publishing message to topic house/bulbs/bulb1
message received  OFF
message topic= house/bulbs/bulb1
message qos= 0
message retain flag= 0
>>> 



MQTT and Python For Beginners -Publishing Messages

MQTT and Python For Beginners -Tutorials

 源自於 http://www.steves-internet-guide.com/mqtt-python-beginners-course/

發行訊息至broker

Main Client Methods

The paho mqtt client class has several methods.The main ones are:

  • connect() and disconnect()
  • subscribe() and unsubscribe()
  • publish()

Each of these methods is associated with a callback. See Later.

Importing The Client Class

To use the client class you need to import it. Use the following:

Import paho.mqtt.client as mqtt

Creating a Client Instance

The client constructor takes 4 optional parameters, as shown below .but only the client_id is necessary, and should be unique.

Client(client_id=””, clean_session=True, userdata=None, protocol=MQTTv311, transport=”tcp”)

To create a instance use:

client =mqtt.Client(client_name)


Connecting To a Broker or Server

Before you can publish messages or subscribe to topics you need to establish a connection to a broker.

To do this use the connect method of the Python mqtt client.

The method can be called with 4 parameters. The connect method declaration is shown below with the default parameters.

connect(host, port=1883, keepalive=60, bind_address="")

Note: You only need to supply the broker name/IP address.

The general syntax is

client.connect(host_name)

公開 MQTT Borker

Publishing Messages

Once you have a connection you can start to publish messages.

To do this we use the publish method.

The publish method accepts 4 parameters. The parameters are shown below with their default values.

publish(topic, payload=None, qos=0, retain=False)

The only parameters you must supply are the topic, and the payload.

The payload is the message you want to publish.

The general syntax is:

client.publish("house/light","ON")

Example Python Script:

We are now in a position to create our first Python Script to Publish a message.

The script below publishes the message OFF to topic house/main-light


import paho.mqtt.client as mqtt #import the client1
broker_address="192.168.1.184" 
#broker_address="iot.eclipse.org" #use external broker
client = mqtt.Client("P1") #create new instance
client.connect(broker_address) #connect to broker
client.publish("house/main-light","OFF")#publish




import time
import paho.mqtt.client as mqtt #import the client1
broker_address="broker.hivemq.com" 
#broker_address="iot.eclipse.org" #use external broker
client = mqtt.Client("P1") #create new instance
client.connect(broker_address) #connect to broker
client.publish("alex9ufo/house/main-light","OFF")#publish
print ("publish (alex9ufo/house/main-light,OFF")

time.sleep(10)

client.publish("alex9ufo/house/main-light","ON")#publish
print ("publish (alex9ufo/house/main-light, ON")


2022年12月11日 星期日

wxPython Hello World

 wxPython Hello World


import wx 

app = wx.App() 

window = wx.Frame(None, title = "wxPython Frame", size = (300,200)) 

panel = wx.Panel(window) 

label = wx.StaticText(panel, label = "Hello World", pos = (100,10))

label = wx.StaticText(panel, label = "Hello World", pos = (100,30))

window.Show(True) 

app.MainLoop()



wxPython Hello

 wxPython  Hello 


import random

import wx

def main():

    app = wx.App()


    frame = wx.Frame(

        parent=None,

        id=wx.ID_ANY,

        title='Hello'

    )

    frame.Show()


    # 產生字型設定

    font = wx.Font(wx.FontInfo(10).FaceName('Consolas'))


    # 建立文字元件

    label = wx.StaticText(

        parent=frame,

        label='People',

        pos=wx.Point(10, 13),

        size=wx.Size(50, 20)

    )

    # 套用字型

    label.SetFont(font)


    # 產生按鈕元件

    button = wx.Button(

        parent=frame,

        id=wx.ID_ANY,

        label='Say',

        pos=wx.Point(70, 10),

        size=wx.Size(100, 22)

    )

    # 套用字型

    button.SetFont(font)

    button.SetBackgroundColour((255, 230, 200, 255))

    # 綁定按鈕點擊事件

    button.Bind(wx.EVT_BUTTON, lambda _: input.SetValue(f'Hello {random.randint(10,100)}'))


    # 產生輸入元件

    input = wx.TextCtrl(

        parent=frame,

        id=wx.ID_ANY,

        value='Hello',

        pos=wx.Point(180, 10),

        size=wx.Size(100, 22)

      

    )

    # 套用字型

    input.SetFont(font)

    # 綁定文字變動事件

    input.Bind(wx.EVT_TEXT, lambda e: textarea.AppendText(f'text changed: {input.GetValue()}\n'))


    # 產生輸入元件

    textarea = wx.TextCtrl(

        parent=frame,

        id=wx.ID_ANY,

        style=wx.TE_MULTILINE,

        pos=wx.Point(10, 40),

        size=wx.Size(270, 150)

    )

    # 套用字型

    textarea.SetFont(font)

    # 設為唯讀

    textarea.SetEditable(False)


    app.MainLoop()


if __name__ == '__main__':

    main()




2022年12月9日 星期五

TKinter + MQTT Pusbish Topic

 


import tkinter as tk

import paho.mqtt.client as mqtt


def on_subscribe(client, userdata, mid, granted_qos):

    nomTopic = zoneTopic.get()

    labelAbonnement.config(text = "" + nomTopic, fg = "blue")

    boutonMessage.config(state = "active")


def on_message(client, userdata, message):

    labelMessageRecu.config(text = "" + str(message.payload.decode("utf-8")), fg = "blue")


def fonctionIp():

    ip = zoneIP.get()

    client = mqtt.Client("alex9ufo")

    client.connect(ip)

    zoneIP.config(state = "disable")

    boutonIP.config(state = "disable")

    zoneTopic.config(state = "normal")

    boutonTopic.config(state = "active")


def souscrire():

    ip = zoneIP.get()

    client = mqtt.Client("alex9ufo")

    client.connect(ip)

    nomTopic = zoneTopic.get()

    client.on_message = on_message

    client.on_subscribe = on_subscribe

    client.loop_start()

    client.subscribe(nomTopic)

    zoneMessage.config(state = "normal")


def publier():

    ip = zoneIP.get()

    client = mqtt.Client("alex9ufo")

    client.connect(ip)

    nomTopic = zoneTopic.get()

    client.on_message = on_message

    client.on_subscribe = on_subscribe

    client.loop_start()

    client.subscribe(nomTopic)

    client.publish(nomTopic, zoneMessage.get())


win = tk.Tk()

win.geometry("800x450")

win.title("MQTT")

win.iconbitmap('icon.ico')

win.resizable(False, False)


label = tk.Label(win, text = "MQTT communication application", font = "size 14 underline", fg = "red")

label.grid(column = 0, row = 0, columnspan = 3, pady = 15)

label = tk.Label(win, text = "https://github.com/PouletEnSlip/MQTT", font = "size 8 underline", fg = "red")

label.grid(column = 0, row = 1, columnspan = 3, pady = 5)



label = tk.Label(win, text = "Broker IP:", font = "size 12", fg = "blue")

label.grid(column = 0, row = 2, sticky = 'w', padx =5)


zoneIP = tk.Entry(win, width = "30", font = "size 12")

zoneIP.insert(0, "broker.mqtt-dashboard.com")

zoneIP.grid(column = 0, row = 3, sticky = 'w', padx = 5, pady = 5)


boutonIP = tk.Button(win, text = "Validate IP", font = "size 12", command = fonctionIp)

boutonIP.grid(column = 2, row = 3, sticky = 'e', padx = 5, pady = 5)


label = tk.Label(win, text = "Topic name:", font = "size 12", fg = "blue")

label.grid(column = 0, row = 4, sticky = 'w', padx = 5)


zoneTopic = tk.Entry(win, width = "30", font = "size 12", state = "disable")

zoneTopic.grid(column = 0, row = 5, sticky = 'w', padx = 5, pady = 5)


boutonTopic = tk.Button(win, text = "Subscribe to topic", font = "size 12", command = souscrire, state = "disable")

boutonTopic.grid(column = 2, row = 5, sticky = 'e', padx = 5, pady = 5)


label = tk.Label(win, text = "")

label.grid(column = 0, row = 6)


label = tk.Label(win, text = "Subscription to topic:", font = "size 10")

label.grid(column = 0, row = 7, sticky = 'e', pady = 5)


labelAbonnement = tk.Label(win, text = "No topic...", font = "size 10", fg = "grey", width = "30")

labelAbonnement.grid(column = 1, row = 7)


label = tk.Label(win, text = "Message(s) received:", font = "size 10")

label.grid(column = 0, row = 8, sticky = 'e', pady = 5)


labelMessageRecu = tk.Label(win, text = "No message...", font = "size 10", fg = "grey", width = "30")

labelMessageRecu.grid(column = 1, row = 8)


label = tk.Label(win, text = "")

label.grid(column = 0, row = 9)


label = tk.Label(win, text = "Enter your message:", font = "size 12", fg = "blue")

label.grid(column = 0, row = 10, sticky = 'w', padx = 5)


zoneMessage = tk.Entry(win, width = "30", font = "size 12", state = "disable")

zoneMessage.grid(column = 0, row = 11, sticky = 'w', padx = 5, pady = 5)


boutonMessage = tk.Button(win, text = "Send message", font = "size 12", command = publier, state = "disable")

boutonMessage.grid(column = 2, row = 11, sticky = 'e', padx = 5, pady = 5)


boutonQuitter = tk.Button(text = "eXit", font = "size 12", bg = '#FF5020', width = 6, command = win.destroy)

boutonQuitter.grid(column = 2, row = 12, sticky = 'e', padx = 5)


label = tk.Label(text = "alex9ufo © 2022", font = "size 8")

label.grid(column = 0, row = 12, sticky = 'w')


win.mainloop()


Paho MQTT Python

 

 Paho MQTT Python

  1. Introduction to the Paho Python MQTT Client
  2. Introduction to the Client Class
  3. Connecting to a Broker
  4. Publishing Using The Paho Python MQTT Client
  5. Subscribing using The Paho Python Client
  6.  Receiving Messages with the Paho MQTT Python Client
  7. Understanding The Loop
  8. Understanding Callbacks
  9. Handling Multiple Client Connections

Paho MQTT Python_1 (Publish / Subscribe)



import paho.mqtt.client as mqtt

import random

import json  

import datetime 

import time


# 設置日期時間的格式

ISOTIMEFORMAT = '%m/%d %H:%M:%S'


# 連線設定

# 初始化地端程式

client = mqtt.Client()


# 設定登入帳號密碼

client.username_pw_set("alex9ufo","alex9981")


# 設定連線資訊(IP, Port, 連線時間)

client.connect("broker.mqtt-dashboard.com", 1883, 60)


while True:

    t0 = random.randint(0,30)

    t = datetime.datetime.now().strftime(ISOTIMEFORMAT)

    payload = {'Temperature' : t0 , 'Time' : t}

    print (json.dumps(payload))

    #要發布的主題和內容

    client.publish("alex9ufo/MQTT/Test", json.dumps(payload))

    time. Sleep(5)


 

>>> %Run test2.py

{"Temperature": 29, "Time": "12/09 19:51:10"}

{"Temperature": 26, "Time": "12/09 19:51:15"}

{"Temperature": 20, "Time": "12/09 19:51:20"}

{"Temperature": 17, "Time": "12/09 19:51:25"}

{"Temperature": 15, "Time": "12/09 19:51:30"}

{"Temperature": 23, "Time": "12/09 19:51:35"}

{"Temperature": 16, "Time": "12/09 19:51:40"}

{"Temperature": 7, "Time": "12/09 19:51:45"}

{"Temperature": 28, "Time": "12/09 19:51:50"}

{"Temperature": 6, "Time": "12/09 19:51:55"}

{"Temperature": 27, "Time": "12/09 19:52:00"}

{"Temperature": 8, "Time": "12/09 19:52:05"}

{"Temperature": 26, "Time": "12/09 19:52:10"}

{"Temperature": 23, "Time": "12/09 19:52:15"}

{"Temperature": 2, "Time": "12/09 19:52:20"}

{"Temperature": 11, "Time": "12/09 19:52:25"}

{"Temperature": 16, "Time": "12/09 19:52:30"}

{"Temperature": 22, "Time": "12/09 19:52:35"}

{"Temperature": 28, "Time": "12/09 19:52:40"}

{"Temperature": 23, "Time": "12/09 19:52:45"}

{"Temperature": 5, "Time": "12/09 19:52:50"}

{"Temperature": 22, "Time": "12/09 19:52:55"}

{"Temperature": 25, "Time": "12/09 19:53:00"}

{"Temperature": 26, "Time": "12/09 19:53:05"}





import paho.mqtt.client as mqtt
import random
import json  
import datetime 
import time

# 設置日期時間的格式
ISOTIMEFORMAT = '%m/%d %H:%M:%S'

# 連線設定
# 初始化地端程式
client = mqtt.Client()

# 設定登入帳號密碼
client.username_pw_set("alex9ufo","alex9981")

# 設定連線資訊(IP, Port, 連線時間)
client.connect("broker.mqtt-dashboard.com", 1883, 60)

while True:
    t0 = random.randint(0,30)
    t = datetime.datetime.now().strftime(ISOTIMEFORMAT)
    payload = {'Temperature' : t0 , 'Time' : t}
    print (json.dumps(payload))
    #要發布的主題和內容
    client.publish("alex9ufo/MQTT/Test", json.dumps(payload))
    time. Sleep(5)



>>> %Run test3.py
{"Temperature": 14, "Time": "12/09 19:55:19"}
{"Temperature": 12, "Time": "12/09 19:55:24"}
{"Temperature": 7, "Time": "12/09 19:55:29"}
{"Temperature": 12, "Time": "12/09 19:55:34"}
{"Temperature": 15, "Time": "12/09 19:55:39"}
{"Temperature": 26, "Time": "12/09 19:55:44"}
{"Temperature": 15, "Time": "12/09 19:55:49"}




import paho.mqtt.client as mqtt
import random
import json  
import datetime 
import time

# 設置日期時間的格式
ISOTIMEFORMAT = '%m/%d %H:%M:%S'

# 連線設定
# 初始化地端程式
client = mqtt.Client()

# 設定登入帳號密碼
client.username_pw_set("alex9ufo","alex9981")

# 設定連線資訊(IP, Port, 連線時間)
client.connect("broker.mqtt-dashboard.com", 1883, 60)

while True:
    t0 = random.randint(0,30)
    t = datetime.datetime.now().strftime(ISOTIMEFORMAT)
    payload = {'Temperature' : t0 , 'Time' : t}
    print (json.dumps(payload))
    #要發布的主題和內容
    client.publish("alex9ufo/MQTT/Test", json.dumps(payload))
    time. Sleep(5)



>>> %Run Publish_MQTT.py
{"Temperature": 3, "Time": "12/09 19:56:32"}
{"Temperature": 24, "Time": "12/09 19:56:37"}
{"Temperature": 22, "Time": "12/09 19:56:42"}
{"Temperature": 15, "Time": "12/09 19:56:47"}
{"Temperature": 24, "Time": "12/09 19:56:52"}
{"Temperature": 11, "Time": "12/09 19:56:57"}
{"Temperature": 4, "Time": "12/09 19:57:02"}
{"Temperature": 7, "Time": "12/09 19:57:07"}
{"Temperature": 0, "Time": "12/09 19:57:12"}
{"Temperature": 17, "Time": "12/09 19:57:17"}
{"Temperature": 16, "Time": "12/09 19:57:22"}
{"Temperature": 0, "Time": "12/09 19:57:27"}
{"Temperature": 7, "Time": "12/09 19:57:32"}
{"Temperature": 18, "Time": "12/09 19:57:37"}
{"Temperature": 2, "Time": "12/09 19:57:42"}
{"Temperature": 29, "Time": "12/09 19:57:47"}
{"Temperature": 17, "Time": "12/09 19:57:52"}


import paho.mqtt.client as mqtt

# 當地端程式連線伺服器得到回應時,要做的動作
def on_connect(client, userdata, flags, rc):
    print("Connected with result code "+str(rc))

    # 將訂閱主題寫在on_connet中
    # 如果我們失去連線或重新連線時 
    # 地端程式將會重新訂閱
    client.subscribe("alex9ufo/MQTT/Test")

# 當接收到從伺服器發送的訊息時要進行的動作
def on_message(client, userdata, msg):
    # 轉換編碼utf-8才看得懂中文
    print(msg.topic+" "+ msg.payload.decode('utf-8'))

# 連線設定
# 初始化地端程式
client = mqtt.Client()

# 設定連線的動作
client.on_connect = on_connect

# 設定接收訊息的動作
client.on_message = on_message

# 設定登入帳號密碼
client.username_pw_set("alex9ufo","alex9981")

# 設定連線資訊(IP, Port, 連線時間)
client.connect("broker.mqtt-dashboard.com", 1883, 60)

# 開始連線,執行設定的動作和處理重新連線問題
# 也可以手動使用其他loop函式來進行連接
client.loop_forever()



Python 3.10.1 (tags/v3.10.1:2cd268a, Dec  6 2021, 19:10:37) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license()" for more information.

================== RESTART: D:\TKinter\MQTT\Subscribe_MQTT.py ==================
Connected with result code 0
alex9ufo/MQTT/Test {"Temperature": 7, "Time": "12/09 19:57:32"}
alex9ufo/MQTT/Test {"Temperature": 18, "Time": "12/09 19:57:37"}




Node-Red --> MQTT --> Fuxa

Node-Red --> MQTT --> Fuxa      FUXA(一個開源的 Web HMI / SCADA 自動化監控軟體)的專案設定檔 。 這份設定檔完整定義了 HMI 監控畫面的 後端通訊(MQTT 連線、點位標籤) 與 前端網頁圖形介面(SVG 畫布...