跳转至

项目实战4-工控系统前端

点击这里,观看视频讲解

这是一个开发 工业控制系统 前端 的锻炼。

可以微信咨询 byhy44 ,参加实战班 或者 购买视频讲解和代码 。

您需要高效学习,找工作? 点击咨询 报名实战班

点击查看学员就业情况

项目实战简介

先需要对 矿石采掘场地 开发监控系统, 架构图如下

架构图


实战要求: 开发其中的 操作前台 子系统 ,该系统的功能界面如下


锻炼本项目实战,需要具备的基础知识点包括:

  • 比较扎实的 Python语言基础

  • 比较了解线程、Socket网络编程

  • 有一定的 Python Qt 图形界面编程能力


Graphics View 框架

这个程序开发的需要使用 Qt 的 Graphics View 框架

Graphics View 框架让我们可以开发自定义的各种 2D 图形item( QGraphicsItem )

并且可以对其进行各种展示和操作控制,比如,线条/大小/颜色/移动/缩放/拖拽/点击行为 等等


Graphics View 框架主要由3种类型对象组成:

QGraphicsView

QGraphicsScene

QGraphicsItem


Graphics View 框架是典型的 model-view 架构。

这里, QGraphicsScene 和里面包含的 QGraphicsItem 作为 model, QGraphicsView 作为 view

model 里面存储了 要展示的界面的数据定义, 而view根据 model里面的数据进行展示。

一个 model可以对应多个view。

来看一个代码示例

from PySide6 import QtWidgets, QtGui

app = QtWidgets.QApplication()

# 创建 QGraphicsScene  对象,参数设定 位置 和宽度高度
scene = QtWidgets.QGraphicsScene(0, 0, 400, 400)
scene.setBackgroundBrush(QtGui.QColor('#C1E9F5')) # 设定整体背景色

# 创建 QGraphicsView 对象,它是 QWidget的子类, 也是一个QWidget
view = QtWidgets.QGraphicsView(scene)

# 创建QGraphicsRectItem 矩形对象, 这是 QGraphicsItem的子类型
rect = QtWidgets.QGraphicsRectItem(10, 10, 200, 50)

scene.addItem(rect) # 添加到 QGraphicsScene 对象中

rect.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable, True) # 让其可以移动

view.show()
app.exec()

这里, QGraphicsScene 对象 和里面包含的 QGraphicsRectItem矩形对象 ,就定义了 要展示在view界面的 内容。


前面说过一个model可以对应多个view, 所以,这样可以这样

from PySide6 import QtWidgets, QtCore

app = QtWidgets.QApplication()

scene = QtWidgets.QGraphicsScene(0, 0, 400, 400)

# 创建 2个QGraphicsView 对象, 对应同一个 QGraphicsScene  对象
view1 = QtWidgets.QGraphicsView(scene)
view2 = QtWidgets.QGraphicsView(scene)

rect = QtWidgets.QGraphicsRectItem(10, 10, 200, 50)
scene.addItem(rect) 
rect.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable, True)

# 2个view放到 QSplitter里面
splitter = QtWidgets.QSplitter(QtCore.Qt.Horizontal)
splitter.addWidget(view1)
splitter.addWidget(view2)
splitter.show()

app.exec()

运行就可以发现,出现的2个 QGraphicsView 展示的 内容是一样的,包括在移动的时候,行为也是一样的。

因为这2个view对应的是同一个model。

内置的item

可以看出,这种界面的开发, 主要就是开发各种 图形item : QGraphicsItem。

有些 QGraphicsItem 需要自己开发 , 有些可以直接使用 Qt 提供的现成的 QGraphicsItem。

我们先来看 Qt 提供的一些 图形item , 他们都是 QGraphicsItem 的子类

矩形

官网链接 : QGraphicsRectItem

前面的示例中已经演示过,呈现出的是一个矩形。

# 前2个参数指定了该矩形显示在上级对象的x/y坐标位置, 
# 后2个参数指定了矩形的宽度和高度
rect = QtWidgets.QGraphicsRectItem(10, 10, 200, 50)


如果想在运行过程中,动态改变矩形的宽度,高度,可以使用 setRect 方法

比如

from PySide6 import QtWidgets

app = QtWidgets.QApplication()

scene = QtWidgets.QGraphicsScene(0, 0, 300, 300)

view = QtWidgets.QGraphicsView(scene)
rect = QtWidgets.QGraphicsRectItem(10, 10, 200, 50)
scene.addItem(rect) 

def changeWidthHeight():
    # 返回值为  `QRectF`   对象
    qrf = rect.rect()
    qrf.setWidth(100) 
    qrf.setHeight(30)

    rect.setRect(qrf) # 重新设定

btn = QtWidgets.QPushButton('改变宽高')
btn.clicked.connect(changeWidthHeight)

top = QtWidgets.QWidget()
top.resize(400,400)
layout = QtWidgets.QVBoxLayout(top)
layout.addWidget(view)
layout.addWidget(btn)

top.show()
app.exec()


添加内置item,还有一种快捷方法,使用 QGraphicsScene 的 addXXX 系列方法,比如

from PySide6 import QtWidgets

app = QtWidgets.QApplication()

scene = QtWidgets.QGraphicsScene(0, 0, 300, 300)

view = QtWidgets.QGraphicsView(scene)

# 快捷方法添加矩形item,返回值就是添加的 QGraphicsRectItem对象
rect = scene.addRect(10, 10, 200, 50) 

view.show()
app.exec()


可以通过 设置画笔和画刷来指定 item的边线样式 和 填充色,比如

from PySide6 import QtWidgets, QtGui

app = QtWidgets.QApplication()

scene = QtWidgets.QGraphicsScene(0, 0, 300, 300)
view = QtWidgets.QGraphicsView(scene)
rect = scene.addRect(10, 10, 200, 50) 

brush = QtGui.QBrush(QtGui.QColor('#C1E9F5')) # 设定填充色
rect.setBrush(brush)

pen = QtGui.QPen(QtGui.QColor('green')) # 设定线条颜色
pen.setWidth(3) # 设定线条宽度
rect.setPen(pen)

view.show()
app.exec()

椭圆

官网链接 : QGraphicsEllipseItem

示例代码

from PySide6 import QtWidgets, QtGui

app = QtWidgets.QApplication()

scene = QtWidgets.QGraphicsScene(0, 0, 300, 300)

view = QtWidgets.QGraphicsView(scene)

# 设定去锯齿,否则椭圆边线会有明显的锯齿
view.setRenderHint(QtGui.QPainter.Antialiasing)

# 参数为椭圆所在矩形的左上角坐标和 椭圆的宽度,高度
elp = QtWidgets.QGraphicsEllipseItem(10, 10, 200, 50)
scene.addItem(elp)
# 当然也可以使用 快捷方法 elp = scene.addEllipse(10, 10, 200, 50) 

rect = scene.addRect(10, 10, 200, 50) 

view.show()
app.exec()

线条

官网链接 : QGraphicsLineItem

示例代码

from PySide6 import QtWidgets, QtGui

app = QtWidgets.QApplication()

scene = QtWidgets.QGraphicsScene(0, 0, 300, 300)

view = QtWidgets.QGraphicsView(scene)

# 设定去锯齿,否则斜线会有明显的锯齿
view.setRenderHint(QtGui.QPainter.Antialiasing)

# 参数为线条的起点,终点坐标
line = QtWidgets.QGraphicsLineItem(10, 10, 200, 30)
scene.addItem(line)
# 当然也可以使用 快捷方法 line = scene.addLine(10, 10, 200, 30) 

pen = QtGui.QPen(QtGui.QColor('green')) # 设定线条颜色
pen.setWidth(1) # 设定线条宽度
line.setPen(pen)

view.show()
app.exec()

文本

官网链接 : QGraphicsTextItem

示例代码

from PySide6 import QtWidgets, QtGui

app = QtWidgets.QApplication()

scene = QtWidgets.QGraphicsScene(0, 0, 300, 300)

view = QtWidgets.QGraphicsView(scene)

# 参数为文字内容
text = QtWidgets.QGraphicsTextItem(
'''  白月黑羽项目实战4

开发一个矿工监控系统,使用各种item,实时显示监控画面
''')
scene.addItem(text)

# 设定颜色
text.setDefaultTextColor(QtGui.QColor(0x0074cc))
# 设定字体大小
font = QtGui.QFont()
font.setPointSize(12)
text.setFont(font)
font.setFamily('新宋体')
# 设定文本段宽度,像素为单位
text.setTextWidth(200)

# 可以使用下面setPlainText方法,动态改变显示内容
# text.setPlainText('新的显示内容')

view.show()
app.exec()

位图

官网链接 : QGraphicsPixmapItem

QGraphicsPixmapItem可以显示位图图片,比如 bmp/jpg/png 等

示例代码

from PySide6 import QtWidgets, QtGui, QtCore

app = QtWidgets.QApplication()

# 对于显示器使用了缩放的,PySide6需要加上这行,否则图片显示毛糙
# 而PySide2就不需要,应该是Qt6的bug,
# 我已经给Qt提交了bug : https://bugreports.qt.io/browse/PYSIDE-2426
app.setHighDpiScaleFactorRoundingPolicy(QtCore.Qt.HighDpiScaleFactorRoundingPolicy.Round)

scene = QtWidgets.QGraphicsScene(0, 0, 300, 300)

view = QtWidgets.QGraphicsView(scene)

# 创建QPixmap对象
pm = QtGui.QPixmap('images/camera.png')
# 设定图片缩放大小
pm = pm.scaledToWidth(50, QtCore.Qt.SmoothTransformation)

# 创建 QGraphicsPixmapItem对象
picture = QtWidgets.QGraphicsPixmapItem(pm)
scene.addItem(picture)

view.show()
app.exec()

一些设定

属性设定

比较常见的item属性设定有如下设置:

ItemIsMovable    # 设置item可以移动
ItemIsSelectable # 设置item可以选中
ItemIsFocusable  # 设置item可以聚焦,才会有键盘按键回调keyPressEvent

下面是示例代码

from PySide6 import QtWidgets, QtGui, QtCore

app = QtWidgets.QApplication()

app.setHighDpiScaleFactorRoundingPolicy(QtCore.Qt.HighDpiScaleFactorRoundingPolicy.Round)

scene = QtWidgets.QGraphicsScene(0, 0, 300, 300)
view = QtWidgets.QGraphicsView(scene)

pm = QtGui.QPixmap('images/camera.png')
pm = pm.scaledToWidth(50, QtCore.Qt.SmoothTransformation)
picture = QtWidgets.QGraphicsPixmapItem(pm)
scene.addItem(picture)

# 设置item可以移动
picture.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable, True)
# 设置item可以选中
picture.setFlag(QtWidgets.QGraphicsItem.ItemIsSelectable, True)
# 设置item可以聚焦,这样才会有键盘按键回调keyPressEvent
picture.setFlag(QtWidgets.QGraphicsItem.ItemIsFocusable, True) 

view.show()
app.exec()

改变item的位置

如果在程序运行过程中需要改变item(相对于上级)的位置, 可以使用 setPos 方法

rect.setPos(10,10)

组合item

官网链接 : QGraphicsItemGroup

有时,我们需要两种item组合为一个 item使用, 比如 带文字的图标 item(气体监测仪等)。

这时候,可以使用 组合item: QGraphicsItemGroup

示例如下:

from PySide6 import QtWidgets,QtGui
from PySide6.QtCore import Qt

app = QtWidgets.QApplication()
app.setHighDpiScaleFactorRoundingPolicy(Qt.HighDpiScaleFactorRoundingPolicy.Round)

# 组合item继承自 QGraphicsItemGroup
class PictureItem(QtWidgets.QGraphicsItemGroup):
    def __init__(self, pic, text):
        super().__init__()

        pm = QtGui.QPixmap(pic).scaledToWidth(40, Qt.SmoothTransformation)
        self.picItem = QtWidgets.QGraphicsPixmapItem(pm)
        self.picItem.setPos(0,0) # 设置其在parent的显示位置

        self.textItem = QtWidgets.QGraphicsTextItem()
        self.textItem.setTextWidth(70)
        self.textItem.setPlainText(text)
        self.textItem.setPos(40,10) # 设置其在parent的显示位置

        # 添加子item到组item中
        self.addToGroup(self.picItem) 
        self.addToGroup(self.textItem)

        self.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable, True)


scene = QtWidgets.QGraphicsScene(0, 0, 800, 600)
view = QtWidgets.QGraphicsView(scene)

item = PictureItem('./images/temp-meter.png', '分析仪')
item.setPos(100, 100)
scene.addItem(item)

view.show()
app.exec()

自定义item

有些复杂的图形,可以使用上面讲的 位图item, 寻找或自己绘制图片,比如项目实战里面的摄像头/空气监测仪 等等。

但是如果这些还需要item显示内容/效果 随着业务数据的变化而变化,比如项目实战里面的 风泵/水箱, 使用位图item就往往就力不从心了。

这时就需要我们 自己定义item。

本节内容仅供内部学员学习。

您需要高效学习,找工作? 点击咨询 报名实战班

点击查看学员就业情况

分阶段开发项目

本次练习需要的文件放在如下百度云盘目录中,根据后续练习说明下载需要的文件。

百度网盘链接

01 初始布局

界面初始布局,左边是item图标栏,右边是 操作区


在项目实战的云盘目录中有个 images.zip 文件,下载并且解压

里面有提供好的图标栏中需要的 图标图片文件,省去自己寻找图标图片的时间。


具体见视频说明


参考代码如下,对应实现讲解 见视频说明

from PySide6 import QtWidgets,QtGui,QtCore

PIC_LIST = [
    'gas-meter', 'temp-meter',
    'wind-meter', 'water-meter',
    'water-valve', 'water-tank',
    'air-pump', 'camera',
    'hydrant', 'pipeline'
]

class MWindow(QtWidgets.QMainWindow):

    def __init__(self):
        super().__init__()
        self.resize(1000, 800)

        # central Widget
        centralWidget = QtWidgets.QWidget(self)
        self.setCentralWidget(centralWidget)

        # central Widget 里面的 主 layout
        self.mainLayout = QtWidgets.QHBoxLayout(centralWidget)

        # 左边区
        self.setupLeftPane()

        # 中间绘制区
        self.setupCanvas()

    def setupLeftPane(self):
        leftLayout = QtWidgets.QVBoxLayout()
        self.mainLayout.addLayout(leftLayout)

        pixmapLayout = QtWidgets.QGridLayout()
        leftLayout.addLayout(pixmapLayout)
        leftLayout.addStretch()

        row, col = 0, 0
        for picName in PIC_LIST:

            # 初始参数就是图片路径名
            pixmap = QtGui.QPixmap(f'./images/{picName}.png')
            # 设定图片缩放大小,这里是50个像素的宽度,高度也会等比例缩放
            pixmap = pixmap.scaledToWidth(40, QtCore.Qt.SmoothTransformation)

            label = QtWidgets.QLabel()

            # 设置label显示的pixmap
            label.setPixmap(pixmap)

            pixmapLayout.addWidget(label, row, col)  # 添加到第1行,第1列

            if col == 1:
                row += 1
                col = 0
            else:
                col += 1


    def setupCanvas(self):
        self.scene = QtWidgets.QGraphicsScene(0, 0, 800, 600)
        self.view = QtWidgets.QGraphicsView(self.scene)
        self.mainLayout.addWidget(self.view)


app = QtWidgets.QApplication()
app.setHighDpiScaleFactorRoundingPolicy(QtCore.Qt.HighDpiScaleFactorRoundingPolicy.Round)

window = MWindow()
window.show()
app.exec()

02 拖放布局

实现 item图标拖放到 操作区 的功能,并且item在操作区能够用鼠标移动

具体见视频说明


参考代码如下,对应实现讲解 见视频说明

from PySide6 import QtWidgets,QtGui,QtCore
from PySide6.QtCore import Qt


PIC_LIST = [
    'gas-meter', 'temp-meter',
    'wind-meter', 'water-meter',
    'water-valve', 'water-tank',
    'air-pump', 'camera',
    'hydrant', 'pipeline'
]

class DragLabel(QtWidgets.QLabel):

    def mouseMoveEvent(self, e):

        if e.buttons() != Qt.LeftButton:
            return

        mimeData = QtCore.QMimeData()

        drag = QtGui.QDrag(self)
        drag.setMimeData(mimeData)

        drag.exec(Qt.DropActions.MoveAction)


class DnDGraphicView(QtWidgets.QGraphicsView):
    def dragMoveEvent(self, e):
        pass


    def dragEnterEvent(self, e):

        if True:
            e.accept()
        else:
            e.ignore()

    def dropEvent(self, e):

        picName = e.source().dndinfo['name']

        pixmap = QtGui.QPixmap(f'./images/{picName}.png')

        pixmap = pixmap.scaledToWidth(40, Qt.SmoothTransformation)

        item = QtWidgets.QGraphicsPixmapItem(pixmap)

        self.scene().addItem(item)

        item.setPos(e.position())

        # 设置item可以移动
        item.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable, True)
        # 设置item可以选中
        item.setFlag(QtWidgets.QGraphicsItem.ItemIsSelectable, True)
        # 设置item可以聚焦,这样才会有键盘按键回调keyPressEvent
        item.setFlag(QtWidgets.QGraphicsItem.ItemIsFocusable, True)


    # 该方法使得view 改变大小时(比如拖拽主窗口resize), scene大小跟着变化
    # 否则,view和secen大小不一致, 拖放item 时,位置就不对了。
    def resizeEvent(self, event):
        super().resizeEvent(event)
        size = event.size()
        self.setSceneRect(0, 0, size.width(), size.height())


class MWindow(QtWidgets.QMainWindow):

    def __init__(self):
        super().__init__()
        self.resize(1000, 800)

        # central Widget
        centralWidget = QtWidgets.QWidget(self)
        self.setCentralWidget(centralWidget)

        # central Widget 里面的 主 layout
        self.mainLayout = QtWidgets.QHBoxLayout(centralWidget)

        # 左边区
        self.setupLeftPane()

        # 中间绘制区
        self.setupCanvas()

    def setupLeftPane(self):
        leftLayout = QtWidgets.QVBoxLayout()
        self.mainLayout.addLayout(leftLayout)

        pixmapLayout = QtWidgets.QGridLayout()
        leftLayout.addLayout(pixmapLayout)
        leftLayout.addStretch()

        row, col = 0, 0
        for picName in PIC_LIST:

            # 初始参数就是图片路径名
            pixmap = QtGui.QPixmap(f'./images/{picName}.png')
            # 设定图片缩放大小,这里是50个像素的宽度,高度也会等比例缩放
            pixmap = pixmap.scaledToWidth(40, Qt.SmoothTransformation)

            label = DragLabel()
            label.dndinfo = {'name': picName}

            # 设置label显示的pixmap
            label.setPixmap(pixmap)

            pixmapLayout.addWidget(label, row, col) 

            if col == 1:
                row += 1
                col = 0
            else:
                col += 1

    def setupCanvas(self):
        self.scene = QtWidgets.QGraphicsScene(0, 0, 800, 600)
        self.view = DnDGraphicView(self.scene)
        self.mainLayout.addWidget(self.view)


app = QtWidgets.QApplication()
app.setHighDpiScaleFactorRoundingPolicy(Qt.HighDpiScaleFactorRoundingPolicy.Round)

window = MWindow()
window.show()
app.exec()

03 矩形/线条/椭圆/文字 item

实现 位图item 支持配套文字,并且支持 用键盘方向键 进行 像素级微小移动。

添加 矩形/线条/椭圆/文字 item

具体见视频说明

04 属性表格-上

然后界面添加属性表格,属性表格的样式风格和视频说明里面一致。

且有 调整 表格 和 操作区 之间的边界位置的功能。

实现 操作组 选中 下面各类型item,可以配置如下属性

  • 文字Item
{
    '内容' : '文字内容',
    '颜色' : 'black',
    '大小' : '18',
    '字体' : 'fangsong',
    '字粗' : '200',
    'zValue' : '0.0',
}


  • 线条Item
{
    '线宽' : '2',
    '颜色' : '255, 69, 0',
    '线长' : '100',
    '旋转角度' : '0',
    'zValue' : '0.0',
}


  • 矩形Item
{
    '矩形长度'     : '160',
    '矩形高度'     : '100',
    '填充颜色'     : '222, 241, 255, 0',
    '线条宽度'     : '1',
    '线条颜色'     : '0, 100, 0',
    'zValue'      : '0.0',
}


  • 椭圆Item
{

    '椭圆长度'     : '160',
    '椭圆高度'     : '100',
    '填充颜色'     : '222, 241, 255, 0',
    '线条宽度'     : '1',
    '线条颜色'     : '0, 100, 0',
    'zValue'      : '0.0',
}


  • 图片Item
{
    '图标位置' : '0,0',
    '图标宽度' : '40',
    '文字位置' : '10,50',
    '文字宽度' : '70',
    'zValue' : '0.0',
}


本次练习只要求做到,点击操作区的item,显示其要配置的内容即可。

具体配置功能,下次练习实现

具体见视频说明

05 属性表格-下

接着上次已经实现的 点击操作区的item,显示其要配置的内容

本次练习完成具体配置功能,就是修改配置项内容,对应操作区item相应改变

具体见视频说明

06 删除 和 存盘

  1. 实现图标工具栏,里面有 保存,加载,删除,清空 按钮。

  2. 保存,加载 功能

  3. 实现 删除Item,清空操作区的 Item 功能

  4. 实现 拖放一个Item 就设置为当前选中Item

具体见视频说明

07 连接后端,获取数据

点击这里 了解采掘工控系统前后端接口的 接口协议格式说明

实现前端连接后端, 能持续接收后端发送过来的数据,打印出接收的每个完整消息的字节串数据即可。

另外,要求能够做到,当服务端重启后,前端能自动重连。


这次练习需要运行后端系统,在本次项目实战的云盘目录中有个 mine-cc.zip 文件,下载并且解压。

苹果Mac电脑下载 苹果Mac电脑 目录里面的 mine-cc-mac.zip 文件,并且解压。


后端系统需要用激活码联网激活,请和老师联系获取激活码后,运行目录里面的 activate.bat 激活。


激活后,运行 run.bat 运行后端服务系统

后端服务等待前端 TCP 连接的 listen 地址端口是 127.0.0.1:47554

这个参数可以在 cfg.toml 里面配置


具体见视频说明

08 某些图片item有额外属性

下面这些图片item的属性,要比前面说的多出一个属性 设备编号

gas-meter 毒气监测仪

temp-meter 温度湿度计

wind-meter 空气流量仪

water-meter 水流量表

water-tank 饮用水箱

camera 摄像头 item 要多处2个属性:设备编号视频流地址

请修改代码支持这些额外属性的 显示/修改/保存/加载


具体见视频说明

09 显示设备通知消息

后端会发送设备通知消息,消息类型 为 notify-to-frontend

各种设备的通知消息,格式示例如下

# 毒气监测仪
BF01|notify-to-frontend|0|1695899578730990${
    "device-sn":"aaaa0001","CO":0.05,"HCl":0.01,"SO2":0.01}


# 温度湿度计
BF01|notify-to-frontend|0|1695691644857589${
    "device-sn":"aaaa0002","humidity":51.85,"temperature":25.56}


# 空气流量仪
BF01|notify-to-frontend|0|1695899575700207${
    "device-sn":"aaaa0003","flow-rate":0.94}


# 水流量表
BF01|notify-to-frontend|0|1695899573726278${
    "device-sn":"aaaa0004","flow-rate":95.93,"water-pressure":3120.17}


# 饮用水箱
BF01|notify-to-frontend|0|1695899575825435${
    "device-sn":"aaaa0005","water-amount":0.61}

消息体中 device-sn 字段决定了是哪个设备上的通知消息,

要求,先在操作区拖动创建上述5种设备设备, 根据上面 device-sn 填入对应的设备号,然后保存操作区。

继续开发我们的程序,能显示接收到的服务端通知消息内容 到操作区对应的设备图标上。


具体见视频说明

10 水缸动态显示水量

学习本章上面 自定义item 这一节内容,实现 水缸Item 动态显示水量 的功能

  • 正确显示水量百分比,一个水箱的设备编号是 : aaaa0005

  • 能够移动

  • 选中时显示边界

  • 属性里面包括: zValue设备编号

  • 存盘/加载 没有问题


具体见视频说明

11 直播摄像头

做到双击摄像头,就可以播放该摄像头对应的直播视频流。

具体要求见视频说明

12 模式切换

  • 查看模式/编辑模式

查看模式 不能 拖拽创建/移动/删除 Item, 但是可以选中,可以编辑属性

  • del按键删除元件

可以删除多选的多个元件

  • 创建并保存如下操作区设置

image


上图中2个施工地的设备编号如下

施工地1:

设备类型 毒气监测仪
设备编号 aaaa0001

设备类型 温度湿度计
设备编号 aaaa0002

设备类型 空气流量仪
设备编号 aaaa0003

设备类型 水流量表
设备编号 aaaa0004

设备类型 饮用水箱
设备编号 aaaa0005

设备类型 摄像头
设备编号 aaaa0006
视频流地址: rtmp://127.0.0.1/mytv/room01


施工地2:

设备类型 毒气监测仪
设备编号 aaaa0021

设备类型 温度湿度计
设备编号 aaaa0022

设备类型 空气流量仪
设备编号 aaaa0023

设备类型 水流量表
设备编号 aaaa0024

设备类型 饮用水箱
设备编号 aaaa0025

设备类型 摄像头
设备编号 aaaa0026
视频流地址: rtmp://127.0.0.1/mytv/room02

具体见视频说明

13 实时统计图

后端会不断上报 煤产量 和 水/电 消耗数据,格式如下

BF01|notify-to-frontend|0|1695691644857589${

    "device-sn": "stats",

    "coal-1": [37856, 37859, 37866, 37866, 37866, 37872, 37872, 37878, 37883, 37884], 

    "coal-2": [37645, 37652, 37652, 37652, 37653, 37659, 37663, 37665, 37665, 37668], 

    "w-used": [37647, 37649, 37651, 37658, 37660, 37666, 37666, 37673, 37678, 37680], 

    "e-used": [21599, 21602, 21605, 21606, 21607, 21607, 21608, 21610, 21612, 21616]
}


其中:

coal-1coal-2 分别是 煤品1煤品2 的 产量变化数据,单位是吨。

w-used 消耗数据,单位是吨。

e-used 消耗数据,单位是千瓦时。


要求在操作区底部呈现3张实时统计图,展示 煤品1煤品2 的 产量数据, 水/电 的消耗数据


具体见视频说明

14 风泵动画效果

要求完成自定义风泵的功能。

风泵可以根据下方3个风速按钮进行3种速度的旋转,并且点击按钮时发送 device_control 消息给后端 ,告知调整对应风泵的速度

发送消息格式如下

BF01|device_control|0|1695691644857589$
{
    "device-sn" :  "bbbb0003",
    "operation" : "set-wind-pump-speed",
    "fan-speed"     : 3
}

两个风泵的设备号分别是 bbbb0003bbbb0023 , 这两个风泵 分别对应 空气流量仪 aaaa0003aaaa0023

fan-speed 取值为 0/1/2/3 对应从低到高4种风速, 0 为 零风速


发送消息使用的tcp socket 也就是接收消息的 socket


具体见视频说明