『瀚思彼岸』» 智能家居技术论坛

 找回密码
 立即注册
查看: 6160|回复: 10

[基础教程] 用python 模拟 mqtt客户端之二

[复制链接]

5

主题

122

帖子

494

积分

中级会员

Rank: 3Rank: 3

积分
494
金钱
372
HASS币
0
发表于 2019-6-14 18:33:52 | 显示全部楼层 |阅读模式
本帖最后由 lipzbob 于 2019-6-15 09:42 编辑

                原理见帖子用python 模拟 mqtt客户端,                                                                                                                                    今天没事就用PyQt5做了个简单的UI,更能直观的反映出MQTT客户端的工作方式。实现功能:HA中实时控制客户端中的台灯;客户端中手动开关台灯后的状态可以实时反映到HA中。

              效果见下图:
                未标题-1.gif
    1.UI代码switch.py:
from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.setEnabled(True)
        MainWindow.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.checkBox = QtWidgets.QCheckBox(self.centralwidget)
        self.checkBox.setGeometry(QtCore.QRect(550, 430, 51, 16))
        self.checkBox.setObjectName("checkBox")
        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.setGeometry(QtCore.QRect(180, 190, 113, 21))
        self.lineEdit.setObjectName("lineEdit")
        self.lineEdit_2 = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit_2.setGeometry(QtCore.QRect(180, 230, 113, 21))
        self.lineEdit_2.setObjectName("lineEdit_2")
        self.lineEdit_3 = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit_3.setGeometry(QtCore.QRect(180, 270, 113, 21))
        self.lineEdit_3.setObjectName("lineEdit_3")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(70, 190, 111, 16))
        self.label.setObjectName("label")
        self.label_2 = QtWidgets.QLabel(self.centralwidget)
        self.label_2.setGeometry(QtCore.QRect(60, 230, 121, 20))
        self.label_2.setObjectName("label_2")
        self.label_3 = QtWidgets.QLabel(self.centralwidget)
        self.label_3.setGeometry(QtCore.QRect(100, 270, 72, 15))
        self.label_3.setObjectName("label_3")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(180, 360, 93, 28))
        self.pushButton.setObjectName("pushButton")
        self.label_4 = QtWidgets.QLabel(self.centralwidget)
        self.label_4.setGeometry(QtCore.QRect(460, 160, 261, 201))
        self.label_4.setAutoFillBackground(False)
        self.label_4.setText("")
        self.label_4.setPixmap(QtGui.QPixmap("light1.png"))
        self.label_4.setScaledContents(True)
        self.label_4.setWordWrap(False)
        self.label_4.setObjectName("label_4")
        self.label_5 = QtWidgets.QLabel(self.centralwidget)
        self.label_5.setGeometry(QtCore.QRect(100, 310, 72, 15))
        self.label_5.setObjectName("label_5")
        self.lineEdit_4 = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit_4.setGeometry(QtCore.QRect(180, 310, 113, 21))
        self.lineEdit_4.setObjectName("lineEdit_4")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 26))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.checkBox.setText(_translate("MainWindow", "开关"))
        self.label.setText(_translate("MainWindow", "mqtt服务器IP:"))
        self.label_2.setText(_translate("MainWindow", "mqtt服务器端口:"))
        self.label_3.setText(_translate("MainWindow", "订阅主题:"))
        self.pushButton.setText(_translate("MainWindow", "连接"))
        self.label_5.setText(_translate("MainWindow", "发布主题:"))


       2.主体代码mqttswitch:
from PyQt5 import QtCore, QtWidgets, QtGui
from switch import Ui_MainWindow
import paho.mqtt.client as mqtt


class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)
        self.retranslateUi(self)
        self.setFixedSize(800, 600)
        global client
        client = ''
        self.checkBox.setEnabled(False)
        self.pushButton.clicked.connect(self.link)
        self.checkBox.clicked.connect(self.cont)


    def cont(self):

        self.label_4.setPixmap(QtGui.QPixmap("light2.png" * (self.checkBox.isChecked() == True) + "light1.png" * (
                    self.checkBox.isChecked() == False)))
        client.publish(self.lineEdit_4.text(), "ON" * (self.checkBox.isChecked() == True) + "OFF" * (
                    self.checkBox.isChecked() == False))

    def on_connect(self, client, userdata, flags, rc,):
        print("Connected with result code "+str(rc))
        if rc == 0:
            self.lineEdit.setEnabled(False)
            self.lineEdit_2.setEnabled(False)
            self.lineEdit_3.setEnabled(False)
            self.lineEdit_4.setEnabled(False)
            self.pushButton.setText('连接成功')
            self.pushButton.setEnabled(False)
            client.subscribe(self.lineEdit_3.text())
        # else:
        #     QtWidgets.QMessageBox.warning(self, '警告', '请检查MQTT设置!', QtWidgets.QMessageBox.Yes)

    def on_message(self, client, userdata, msg):
        #print(msg.topic+":"+str(msg.payload.decode()))
         print(msg.topic+":"+msg.payload.decode("utf-8"))
         self.checkBox.setChecked(msg.payload.decode("utf-8")=='ON')
         self.label_4.setPixmap(QtGui.QPixmap("light2.png"*(msg.payload.decode("utf-8")=='ON')+"light1.png"*(msg.payload.decode("utf-8")=='OFF')))
         client.publish(self.lineEdit_4.text(), "OFF"*bool(msg.payload.decode("utf-8")=='OFF')+"ON"*bool(msg.payload.decode("utf-8")=='ON'))

    def link(self):
        global client
        client = mqtt.Client()
        client.username_pw_set("admin", "password1")  # 必须设置,否则会返回「Connected with result code 4」
        client.on_connect = self.on_connect
        client.on_message = self.on_message
        try:
           client.connect(self.lineEdit.text(), 1883, 60)
           self.checkBox.setEnabled(True)
        except:
            QtWidgets.QMessageBox.warning(self, '警告', '请检查MQTT设置!', QtWidgets.QMessageBox.Yes)
        client.loop_start()


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = MainWindow()
    MainWindow.show()
    sys.exit(app.exec_())




回复

使用道具 举报

27

主题

2143

帖子

8930

积分

论坛元老

Rank: 8Rank: 8

积分
8930
金钱
6782
HASS币
30

论坛元老

发表于 2019-6-14 18:51:35 | 显示全部楼层
厉害厉害,但是我还是被浏览器上的广告深深吸引,我大chrome为什么不能统治世界
回复

使用道具 举报

1

主题

237

帖子

962

积分

论坛积极会员

积分
962
金钱
725
HASS币
0
发表于 2019-6-14 21:42:43 | 显示全部楼层
厉害厉害。分享一下呗
回复

使用道具 举报

5

主题

122

帖子

494

积分

中级会员

Rank: 3Rank: 3

积分
494
金钱
372
HASS币
0
 楼主| 发表于 2019-6-15 09:12:09 | 显示全部楼层
komoya 发表于 2019-6-14 21:42
厉害厉害。分享一下呗

请参见:用python 模拟 mqtt客户端
回复

使用道具 举报

1

主题

89

帖子

385

积分

论坛分享达人

积分
385
金钱
296
HASS币
0
发表于 2019-6-15 09:23:13 | 显示全部楼层
大神,你的截图里面的联动界面是怎么实现的呢?
回复

使用道具 举报

8

主题

2073

帖子

6053

积分

论坛元老

流水无味

Rank: 8Rank: 8

积分
6053
金钱
3980
HASS币
145

灌水之王

发表于 2019-6-15 09:37:33 | 显示全部楼层
情非殇 发表于 2019-6-14 18:51
厉害厉害,但是我还是被浏览器上的广告深深吸引,我大chrome为什么不能统治世界 ...

因为名义上少了中国!
回复

使用道具 举报

5

主题

122

帖子

494

积分

中级会员

Rank: 3Rank: 3

积分
494
金钱
372
HASS币
0
 楼主| 发表于 2019-6-15 09:44:04 | 显示全部楼层
komoya 发表于 2019-6-14 21:42
厉害厉害。分享一下呗

已经更新代码。
回复

使用道具 举报

5

主题

122

帖子

494

积分

中级会员

Rank: 3Rank: 3

积分
494
金钱
372
HASS币
0
 楼主| 发表于 2019-6-20 08:07:36 | 显示全部楼层
本帖最后由 lipzbob 于 2019-6-20 08:13 编辑
JACK潘 发表于 2019-6-15 09:23
大神,你的截图里面的联动界面是怎么实现的呢?

客户端-->mosquitto(mqtt代理)-->HA来实现的。
回复

使用道具 举报

1

主题

89

帖子

385

积分

论坛分享达人

积分
385
金钱
296
HASS币
0
发表于 2019-6-27 22:11:34 | 显示全部楼层
lipzbob 发表于 2019-6-20 08:07
客户端-->mosquitto(mqtt代理)-->HA来实现的。

谢谢大神!
回复

使用道具 举报

5

主题

122

帖子

494

积分

中级会员

Rank: 3Rank: 3

积分
494
金钱
372
HASS币
0
 楼主| 发表于 2019-6-28 11:10:58 | 显示全部楼层
JACK潘 发表于 2019-6-15 09:23
大神,你的截图里面的联动界面是怎么实现的呢?

具体是用python+pyqt5实现的。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Hassbian

GMT+8, 2024-11-25 03:24 , Processed in 0.129626 second(s), 35 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表