Pyqt5 5.10.1制作MQTT 实时监控噪音大小程序
刚下飞机,人在洛杉矶,复迟见谅,谢邀. 还是一样的逼格,还是熟悉的味道, 远在北京大四的学妹适逢毕业设计, 要做一个噪音监测软件,于是我略施绵薄之力,仅供参考.
技术方案:
1. 硬件方面,购买一个音量传感器连接ESP32开发板, 将音量分贝数传至开发板, 开发板连接Mqtt服务器, 每两秒推送一次音量数据
2.软件方面, 使用pyqt5构建一个桌面程序, 接收来自mqtt的数据, 然后将数据通过echarts展现出来,同时可以设置报警阈值, 超过即调用语音服务报警.
具体实现:
1. pyqt5 使用lable显示报警图片
lbl = self.label_10 pixmap = QtGui.QPixmap('./alarm.png') # 按指定路径找到图片 lbl.setPixmap(pixmap) # 在label上显示图片 lbl.setScaledContents(True) # 让图片自适应label大小 lbl.showNormal()
2. pyqt5使用frame显示pychart生成的静态音量html图, 我们通过pyqt5带的QWebEngineView打开本地html文件(注意打开本地文件需使用绝对路径, 传统的相对路径./...并不适用), 然后调用文件里的重汇函数传入最新的音量,让Pychart 刷新图表, 即可实现动态展示,注意这里pyqt5的版本需在5.11以下才有QWebEngineView:
url1 = self.lineEdit2_2.text() frame1 = self.frame # 创建一个QWebEngineView实例 w = frame1.width() h = frame1.height() self.webView1 = QWebEngineView(frame1) # 加载网页 self.webView1.load(QUrl(url1)) self.webView1.setGeometry(1, 3, w, h) self.webView1.setZoomFactor(0.6) # 显示QFrame self.webView1.show()
刷新本地html方法:
# update pyechart self.webView1.page().runJavaScript(f'reRender({str(nr_voice)})')
降低pyqt5版本:
D:\mqtt_project> pip install PyQt5==5.10.1
3. 超过预设的最大音量时, 系统播放语音警报:
# say sth. to warn engine = pyttsx3.init() engine.setProperty('rate', 180) engine.setProperty('volume', 100) # engine.setProperty('voice', 100) engine.say('Be quiet, or Boss will kill you!') engine.runAndWait() engine.stop()
4. mqtt python版
def mqtt_connect(self): def on_connect(client, userdata, flags, rc): # print("Connected with result code: " + str(rc)) if rc == 0: # rc连接标志,成功会返回0 self.isMQTTConnect = True self.label_status.setText('connect success') else: self.isMQTTConnect = False self.label_status.setText('connect error:' + str(rc)) connect_as = self.lineEdit1_1.text() cli_id = self.lineEdit1_2.text() protocol = self.lineEdit1_3_3.text() host = self.lineEdit1_3.text() port = self.lineEdit1_3_1.text() path = self.lineEdit1_3_2.text() username = self.lineEdit1_4.text() pwd = self.lineEdit1_5.text() topic = self.lineEdit2.text() url1 = self.lineEdit2_2.text() url2 = self.lineEdit2_3.text() print(connect_as, cli_id, protocol, host, port, username, pwd, topic, url1, url2) # save user's last set try: config = configparser.ConfigParser() config.read(self.config_file) config.set(connect_as, 'client_id', str(cli_id)) config.set(connect_as, 'protocol', protocol) config.set(connect_as, 'address', host) config.set(connect_as, 'port', port) config.set(connect_as, 'path', path) config.set(connect_as, 'username', username) config.set(connect_as, 'pwd', pwd) config.set(connect_as, 'topic', topic) config.set(connect_as, 'url', url1) config.set(connect_as, 'url2', url2) config.write(open(self.config_file, "w")) # with open(self.config_file, 'w') as file: # config.write(file) except Exception as e: print(e) self.client = mqtt.Client(client_id=cli_id, transport=protocol) try: self.client.username_pw_set(username, pwd) self.client.connect(host, int(port), 60) self.client.on_connect = on_connect self.client.loop_start() except Exception as e: print(e) def book_info(self): if not self.isMQTTConnect: print('subscribing') self.label_status_2.setText('Please connect host first.') return if self.isSubscribe: self.un_book() return def on_message(client, userdata, message): mstr = message.payload.decode("ascii") self.textEdit2_2.append(mstr) nr_voice = None if mstr.isnumeric() or mstr.replace('.', '').isnumeric(): nr_voice = mstr self.lcdNumber.display(nr_voice) else: strs = json.loads(mstr) nr_voice = strs['voice'] self.lcdNumber.display(nr_voice) # alarm if exceed maximum maximum = self.lineEdit2_4.text() if maximum and int(nr_voice) >= int(maximum): # self.play_video() self.show_img() else: self.label_10.clear() # update pyechart self.webView1.page().runJavaScript(f'reRender({str(nr_voice)})') self.topic = self.lineEdit2.text() self.client.subscribe(self.topic) # self.client.on_connect = self.on_connect self.client.on_message = on_message self.label_status_2.setText('subscribe success.') self.isSubscribe = True def publish(self): wd = self.textEdit2_1.toPlainText() result = self.client.publish(self.topic, wd) status = result[0] if status == 0: print('第{}条消息发送成功') else: print('第{}条消息发送失败') def un_connect(self): if self.client: self.client.disconnect() self.label_status.setText('Connect canceled') def un_book(self): if self.client: self.client.unsubscribe(self.topic) self.label_status_2.setText('subscribe canceled.') self.isSubscribe = False
以上其实还有另一解决方案, 构建一个web版的mqtt连接, 使用js的模块, 同样可以实现功能. 而且可以直接重新渲染echart图表, 免去了python和js的通信难题.
有
浙公网安备 33010602011771号