基于PYQT5的简易温度和湿度的传感器数据采集系统设计与实现
·
题目:实现一个简易的传感器数据采集系统,完成以下功能:
- 数据采集客户端。能够随机产生等模拟数据(如:温度、湿度),并发送到服务器端。
- 数据采集服务器,接收多个客户端的数据并进行展示。
- 通讯协议设计,包括:心跳协议、数据上报、客户端上线、下线等。
要求:
- 必须有图形界面
- 通信协议必须完整实现
- GUI界面可以采用(PyQt、Electron、Java Swing等)
一. 采集端代码:
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QListWidget, QVBoxLayout, QLineEdit, QPushButton, QWidget
from PyQt5.QtCore import QTimer, QThread, pyqtSignal
import socket
import random
import time
# 定义一个客户端线程类,用于发送数据到服务器
class ClientThread(QThread):
update_signal = pyqtSignal(str) # 定义一个信号,用于更新UI
def __init__(self, username, host, port):
super().__init__()
self.username = username # 用户名
self.host = host # 服务器地址
self.port = port # 服务器端口
self.running = True # 线程运行状态
def run(self):
# 创建socket连接
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((self.host, self.port)) # 连接服务器
while self.running:
temperature = random.uniform(20, 30) # 生成随机温度
humidity = random.uniform(40, 60) # 生成随机湿度
data = f"{self.username}: Temperature={temperature}, Humidity={humidity}"
s.sendall(data.encode()) # 发送数据
self.update_signal.emit(data) # 发送信号更新UI
time.sleep(2) # 休眠2秒
def stop(self):
self.running = False # 停止线程
# 定义客户端主窗口类
class ClientWindow(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
self.client_threads = [] # 存储客户端线程列表
def initUI(self):
# 设置窗口标题和大小
self.setWindowTitle('Sensor Data Client')
self.setGeometry(100, 100, 400, 300)
# 创建列表控件、用户名输入框、连接按钮和下线按钮
self.list_widget = QListWidget()
self.username_line = QLineEdit(self)
self.username_line.setPlaceholderText('Enter your username')
self.connect_button = QPushButton('Connect', self)
self.connect_button.clicked.connect(self.connect_to_server) # 绑定按钮点击事件
self.disconnect_button = QPushButton('Disconnect All', self)
self.disconnect_button.clicked.connect(self.disconnect_all) # 绑定按钮点击事件
# 布局管理
layout = QVBoxLayout()
layout.addWidget(self.username_line)
layout.addWidget(self.connect_button)
layout.addWidget(self.disconnect_button) # 添加下线按钮
layout.addWidget(self.list_widget)
# 设置中心窗口
central_widget = QWidget()
central_widget.setLayout(layout)
self.setCentralWidget(central_widget)
def connect_to_server(self):
# 获取用户名并创建客户端线程
username = self.username_line.text()
if username:
client_thread = ClientThread(username, 'localhost', 12345)
client_thread.update_signal.connect(self.update_list) # 绑定信号更新列表
client_thread.start()
self.client_threads.append(client_thread)
self.username_line.clear() # 清空输入框
def disconnect_all(self):
# 停止所有客户端线程
for client_thread in self.client_threads:
client_thread.stop()
self.client_threads = [] # 清空线程列表
self.list_widget.clear() # 清空列表控件
def update_list(self, data):
# 更新列表控件
self.list_widget.addItem(data)
def closeEvent(self, event):
# 关闭窗口时停止所有客户端线程
for client_thread in self.client_threads:
client_thread.stop()
super().closeEvent(event)
# 程序入口
if __name__ == '__main__':
app = QApplication(sys.argv)
client = ClientWindow()
client.show()
sys.exit(app.exec_())
二.服务器端代码:
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QListWidget, QVBoxLayout, QLineEdit, QPushButton, QWidget
from PyQt5.QtCore import QTimer, QThread, pyqtSignal
import socket
import random
import time
# 定义一个客户端线程类,用于发送数据到服务器
class ClientThread(QThread):
update_signal = pyqtSignal(str) # 定义一个信号,用于更新UI
def __init__(self, username, host, port):
super().__init__()
self.username = username # 用户名
self.host = host # 服务器地址
self.port = port # 服务器端口
self.running = True # 线程运行状态
def run(self):
# 创建socket连接
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((self.host, self.port)) # 连接服务器
while self.running:
temperature = random.uniform(20, 30) # 生成随机温度
humidity = random.uniform(40, 60) # 生成随机湿度
data = f"{self.username}: Temperature={temperature}, Humidity={humidity}"
s.sendall(data.encode()) # 发送数据
self.update_signal.emit(data) # 发送信号更新UI
time.sleep(2) # 休眠2秒
def stop(self):
self.running = False # 停止线程
# 定义客户端主窗口类
class ClientWindow(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
self.client_threads = [] # 存储客户端线程列表
def initUI(self):
# 设置窗口标题和大小
self.setWindowTitle('Sensor Data Client')
self.setGeometry(100, 100, 400, 300)
# 创建列表控件、用户名输入框、连接按钮和下线按钮
self.list_widget = QListWidget()
self.username_line = QLineEdit(self)
self.username_line.setPlaceholderText('Enter your username')
self.connect_button = QPushButton('Connect', self)
self.connect_button.clicked.connect(self.connect_to_server) # 绑定按钮点击事件
self.disconnect_button = QPushButton('Disconnect All', self)
self.disconnect_button.clicked.connect(self.disconnect_all) # 绑定按钮点击事件
# 布局管理
layout = QVBoxLayout()
layout.addWidget(self.username_line)
layout.addWidget(self.connect_button)
layout.addWidget(self.disconnect_button) # 添加下线按钮
layout.addWidget(self.list_widget)
# 设置中心窗口
central_widget = QWidget()
central_widget.setLayout(layout)
self.setCentralWidget(central_widget)
def connect_to_server(self):
# 获取用户名并创建客户端线程
username = self.username_line.text()
if username:
client_thread = ClientThread(username, 'localhost', 12345)
client_thread.update_signal.connect(self.update_list) # 绑定信号更新列表
client_thread.start()
self.client_threads.append(client_thread)
self.username_line.clear() # 清空输入框
def disconnect_all(self):
# 停止所有客户端线程
for client_thread in self.client_threads:
client_thread.stop()
self.client_threads = [] # 清空线程列表
self.list_widget.clear() # 清空列表控件
def update_list(self, data):
# 更新列表控件
self.list_widget.addItem(data)
def closeEvent(self, event):
# 关闭窗口时停止所有客户端线程
for client_thread in self.client_threads:
client_thread.stop()
super().closeEvent(event)
# 程序入口
if __name__ == '__main__':
app = QApplication(sys.argv)
client = ClientWindow()
client.show()
sys.exit(app.exec_())
三. 运行效果:

更多推荐

所有评论(0)