【第8章 典型应用开发】8.2 构建IoT控制面板(MQTT协议)

基于统信UOS的Kivy编程构建IoT控制面板(MQTT协议)

下面是一个完整的IoT控制面板开发方案,使用Kivy框架和MQTT协议,专为统信UOS优化设计。

一、系统架构设计

UOS-IoT-Dashboard/
├── main.py                # 主程序入口
├── iot_dashboard.kv       # 界面布局文件
├── core/
│   ├── mqtt_client.py     # MQTT客户端实现
│   ├── uos_integration.py # 统信UOS专用功能
│   ├── device_manager.py  # 设备管理逻辑
│   └── security.py        # 安全模块
└── assets/
    ├── icons/             # 设备图标
    └── themes/            # 统信风格主题

二、MQTT客户端实现(core/mqtt_client.py)

import paho.mqtt.client as mqtt
from kivy.clock import Clock
from threading import Thread
import ssl

class UOSMQTTClient:
    def __init__(self, app):
        self.app = app
        self.client = mqtt.Client(client_id=f"uos_iot_{uuid.uuid4()}")
        self._setup_callbacks()
        self._connected = False
        
    def _setup_callbacks(self):
        self.client.on_connect = self._on_connect
        self.client.on_message = self._on_message
        self.client.on_disconnect = self._on_disconnect
        
    def connect(self, host, port, username=None, password=None, use_tls=True):
        if username and password:
            self.client.username_pw_set(username, password)
            
        if use_tls:
            self.client.tls_set(
                ca_certs="/etc/ssl/certs/uos-ca-bundle.crt",
                cert_reqs=ssl.CERT_REQUIRED
            )
            
        Thread(target=self._async_connect, args=(host, port)).start()
        
    def _async_connect(self, host, port):
        self.client.connect_async(host, port, keepalive=60)
        self.client.loop_start()
        
    def _on_connect(self, client, userdata, flags, rc):
        if rc == 0:
            self._connected = True
            Clock.schedule_once(lambda dt: self.app.on_mqtt_connect())
            # 订阅统信UOS系统主题
            client.subscribe("$SYS/broker/uptime")
            client.subscribe("$SYS/broker/load/#")
        else:
            print(f"Connection failed with code {rc}")
            
    def _on_message(self, client, userdata, msg):
        # 在主线程处理消息
        Clock.schedule_once(
            lambda dt: self.app.process_mqtt_message(msg.topic, msg.payload)
        )
        
    def _on_disconnect(self, client, userdata, rc):
        self._connected = False
        Clock.schedule_once(lambda dt: self.app.on_mqtt_disconnect())
        
    def publish(self, topic, payload, qos=1, retain=False):
        if self._connected:
            self.client.publish(topic, payload, qos=qos, retain=retain)
            
    def subscribe(self, topic, qos=1):
        if self._connected:
            self.client.subscribe(topic, qos=qos)

三、设备管理界面(iot_dashboard.kv)

#:import UosTheme core.uos_integration.UosTheme
#:import DeviceCard widgets.device_card.DeviceCard

<DashboardScreen>:
    BoxLayout:
        orientation: 'vertical'
        
        BoxLayout:
            size_hint_y: None
            height: 50
            canvas.before:
                Color:
                    rgba: UosTheme.get('primary_color')
                Rectangle:
                    pos: self.pos
                    size: self.size
                    
            Label:
                text: '统信UOS IoT控制面板'
                color: UosTheme.get('text_on_primary')
                font_size: 20
                bold: True
                
        ScrollView:
            GridLayout:
                id: device_grid
                cols: 2
                spacing: 20
                padding: 20
                size_hint_y: None
                height: max(self.minimum_height, root.height - 50)
                
        BoxLayout:
            size_hint_y: None
            height: 60
            spacing: 10
            padding: 10
            
            Button:
                text: '添加设备'
                background_normal: ''
                background_color: UosTheme.get('accent_color')
                on_press: root.show_add_device_dialog()
                
            Button:
                text: '系统设置'
                background_normal: ''
                background_color: UosTheme.get('secondary_color')
                on_press: root.show_settings()

四、设备控制卡片组件

from kivy.uix.boxlayout import BoxLayout
from kivy.properties import StringProperty, BooleanProperty

class DeviceCard(BoxLayout):
    device_name = StringProperty("")
    device_type = StringProperty("switch")
    device_status = BooleanProperty(False)
    mqtt_topic = StringProperty("")
    
    def __init__(self, mqtt_client, **kwargs):
        super().__init__(**kwargs)
        self.mqtt = mqtt_client
        self.bind(device_status=self._update_status)
        
    def _update_status(self, instance, value):
        payload = "ON" if value else "OFF"
        self.mqtt.publish(
            f"{self.mqtt_topic}/set",
            payload,
            qos=1
        )
        
    def toggle_device(self):
        self.device_status = not self.device_status

五、统信UOS集成功能(core/uos_integration.py)

import dbus
import subprocess
from kivy.utils import platform

class UOSIntegration:
    @staticmethod
    def show_system_notification(title, message):
        """使用统信通知中心显示通知"""
        try:
            bus = dbus.SessionBus()
            notify = bus.get_object(
                'org.freedesktop.Notifications',
                '/org/freedesktop/Notifications'
            )
            notify.Notify(
                'UOS-IoT', 0, 'iot-panel',
                title, message,
                [], {}, 5000,
                dbus_interface='org.freedesktop.Notifications'
            )
        except Exception as e:
            print(f"Notification failed: {e}")

    @staticmethod
    def get_network_info():
        """获取统信UOS网络信息"""
        try:
            import netifaces
            return {
                iface: netifaces.ifaddresses(iface)
                for iface in netifaces.interfaces()
                if iface != 'lo'
            }
        except:
            return {}

    @staticmethod
    def set_power_mode(mode):
        """设置统信电源模式"""
        valid_modes = ['powersave', 'balanced', 'performance']
        if mode not in valid_modes:
            raise ValueError(f"Invalid mode. Use one of: {valid_modes}")
        
        subprocess.run(
            ['uos-powercfg', 'set', mode],
            check=True
        )

六、安全模块实现(core/security.py)

import hashlib
from cryptography.fernet import Fernet
import base64
from kivy.storage.jsonstore import JsonStore

class IoTSecurity:
    def __init__(self):
        self._store = JsonStore('iot_secrets.json')
        self._load_or_create_key()
        
    def _load_or_create_key(self):
        if 'encryption' not in self._store:
            key = Fernet.generate_key()
            self._store.put('encryption', key=key.decode())
        self._cipher = Fernet(
            self._store.get('encryption')['key'].encode()
        )
        
    def encrypt_credentials(self, username, password):
        creds = f"{username}:{password}".encode()
        return self._cipher.encrypt(creds).decode()
        
    def decrypt_credentials(self, encrypted):
        creds = self._cipher.decrypt(encrypted.encode()).decode()
        return creds.split(':')
        
    def hash_device_id(self, device_id):
        return hashlib.sha256(
            f"{device_id}_uos_salt".encode()
        ).hexdigest()

七、主应用程序实现(main.py)

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.core.window import Window
from core.mqtt_client import UOSMQTTClient
from core.uos_integration import UOSIntegration
from widgets.device_card import DeviceCard
import json

class DashboardScreen(Screen):
    def __init__(self, mqtt_client, **kwargs):
        super().__init__(**kwargs)
        self.mqtt = mqtt_client
        self._devices = {}
        
    def add_device(self, device_info):
        """添加新设备到面板"""
        card = DeviceCard(
            mqtt_client=self.mqtt,
            device_name=device_info['name'],
            device_type=device_info['type'],
            mqtt_topic=device_info['topic']
        )
        self.ids.device_grid.add_widget(card)
        self._devices[device_info['id']] = card
        
    def process_device_message(self, device_id, payload):
        """处理设备状态更新"""
        if device_id in self._devices:
            status = payload.lower() == 'on'
            self._devices[device_id].device_status = status

class UOSIoTApp(App):
    def build(self):
        self.title = '统信UOS IoT控制面板'
        self.icon = 'assets/icon.png'
        
        # 初始化MQTT客户端
        self.mqtt = UOSMQTTClient(self)
        
        # 创建界面
        sm = ScreenManager()
        self.dashboard = DashboardScreen(self.mqtt, name='dashboard')
        sm.add_widget(self.dashboard)
        
        return sm
        
    def on_start(self):
        # 加载保存的设备配置
        self._load_devices()
        
        # 连接到MQTT服务器
        self._connect_to_broker()
        
    def _connect_to_broker(self):
        from core.security import IoTSecurity
        security = IoTSecurity()
        
        # 从安全存储获取凭证
        if 'mqtt' in security._store:
            creds = security._store.get('mqtt')
            username, password = security.decrypt_credentials(creds['credentials'])
            self.mqtt.connect(
                host=creds['host'],
                port=creds['port'],
                username=username,
                password=password
            )
            
    def _load_devices(self):
        try:
            with open('devices.json') as f:
                devices = json.load(f)
                for device in devices:
                    self.dashboard.add_device(device)
        except FileNotFoundError:
            pass
            
    def process_mqtt_message(self, topic, payload):
        """处理所有MQTT消息"""
        # 示例:home/living-room/light1 → light1
        device_id = topic.split('/')[-1]  
        self.dashboard.process_device_message(device_id, payload)
        
    def on_mqtt_connect(self):
        UOSIntegration.show_system_notification(
            "IoT面板", "已连接到MQTT服务器"
        )
        
    def on_mqtt_disconnect(self):
        UOSIntegration.show_system_notification(
            "IoT面板", "与MQTT服务器断开连接"
        )

if __name__ == '__main__':
    from kivy.config import Config
    Config.set('graphics', 'width', '800')
    Config.set('graphics', 'height', '600')
    UOSIoTApp().run()

八、MQTT主题命名规范

建议采用以下主题结构:

{场所}/{区域}/{设备类型}/{设备ID}
示例:
home/living-room/light/1
office/meeting-room/thermostat/1

九、统信UOS打包部署

1. 创建DEB包

# 安装打包工具
sudo apt install dh-make debhelper

# 创建包结构
mkdir -p uos-iot-dashboard/DEBIAN
mkdir -p uos-iot-dashboard/opt/uos-iot-dashboard
mkdir -p uos-iot-dashboard/usr/share/applications

# 复制文件
cp -r UOS-IoT-Dashboard/* uos-iot-dashboard/opt/uos-iot-dashboard/

# 创建控制文件
cat > uos-iot-dashboard/DEBIAN/control <<EOF
Package: uos-iot-dashboard
Version: 1.0.0
Section: utils
Priority: optional
Architecture: all
Maintainer: Your Name <your.email@example.com>
Description: 统信UOS IoT控制面板
 基于Kivy和MQTT协议的物联网设备控制面板
EOF

# 创建桌面文件
cat > uos-iot-dashboard/usr/share/applications/uos-iot-dashboard.desktop <<EOF
[Desktop Entry]
Name=UOS IoT控制面板
Comment=物联网设备管理工具
Exec=python3 /opt/uos-iot-dashboard/main.py
Icon=/opt/uos-iot-dashboard/assets/icon.png
Terminal=false
Type=Application
Categories=Utility;Network;
EOF

# 构建包
dpkg-deb --build uos-iot-dashboard

十、系统集成建议

  1. 系统服务集成:将MQTT客户端作为系统服务运行
  2. 权限管理:使用统信UOS的权限控制系统限制设备访问
  3. 自动启动:添加到统信UOS的启动应用程序列表
  4. 日志集成:将日志写入系统日志(/var/log/syslog)

这个IoT控制面板方案充分利用了统信UOS的特性:

  • 原生风格UI设计
  • 系统通知集成
  • 安全凭证存储
  • 系统打包部署
  • 网络和电源管理集成

面板支持通过MQTT协议与各种IoT设备通信,并提供直观的控制界面,适合在统信UOS上部署和管理智能家居或工业物联网设备。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Botiway

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值