智能家居系统数据库设计与实现

一、数据库表设计

1. 用户表

CREATE TABLE IF NOT EXISTS users (
    uid INTEGER PRIMARY KEY AUTOINCREMENT,
    username varchar(10),
    passwd varchar(10)
);

2. 智能家居状态表

CREATE TABLE IF NOT EXISTS Status (
    sid INTEGER PRIMARY KEY AUTOINCREMENT,
    uid INTEGER ,
    device_name varchar(10),
    device_state varchar(10),
    value varchar(10),
    mode varchar(20),
    FOREIGN KEY (uid) REFERENCES users (uid)
);

二、SQLite数据库操作代码示例

#include <QSqlDatabase>
#include <QSqlQuery>
#include <QMessageBox>
#include <QDebug>
#include <QSqlError>
#include "sqlite.h"

Sqlite::Sqlite()
{

}


void Sqlite::sqlite_init()
{
    // 先关闭重复的数据库连接
    if (QSqlDatabase::contains("qt_sql_default_connection")) {
        QSqlDatabase::removeDatabase("qt_sql_default_connection");
    }
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("../Smarthome_Client/database/database.db");
    if(!db.open())
    {
        qDebug() << "无法打开数据库!";
    }
    else{
        qDebug() << "数据库打开成功!";
    }
}


// 更新智能家居状态表中的数据
void updateSmartHomeStatus(int userId, QString deviceName, QString devicestate,QString newValue)
{
    Sqlite::sqlite_init();
    // 执行更新操作
    QSqlQuery query;
    query.prepare("SELECT * FROM Status WHERE uid = :userId");
     query.bindValue(":userId", userId);
     if (!query.exec()) {
         qDebug() << "查询id失败:" << query.lastError().text();
     }
         QString sql = QString("INSERT INTO Status (uid, device_name, device_state, value) VALUES (%1, \'%2\', \'%3\', \'%4\')")
                 .arg(userId).arg(deviceName).arg(devicestate).arg(newValue);
         query.prepare(sql);
         if (!query.exec()) {
             qDebug() << "插入数据失败:" << query.lastError().text();
             return;
     }
}

bool statusUid(int userId)
{
    Sqlite::sqlite_init();
    QSqlQuery query;
    // 查询智能家居状态表,获取用户对应的状态
    query.prepare("SELECT * FROM status WHERE user_id = :userId");
    query.bindValue(":userId", userId);
    qDebug() << query.exec();
    if (!query.next()) {
        qDebug() << "Failed to execute query!" << query.lastError().text();
        return false;
    }else{
        qDebug() << "Successed to execute query!";
        return true;
    }
}

#ifndef USERSWIDGET_H
#define USERSWIDGET_H

#include <QWidget>

namespace Ui {
class UsersWidget;
}

class UsersWidget : public QWidget
{
    Q_OBJECT

public:
    explicit UsersWidget(int userid,QWidget *parent = nullptr);
    ~UsersWidget();
    void displayUsersWidget();
    void loadLastStatus();//加载上一次的状态
    void saveLastStatus(); // 保存当前更改的状态
    QString getLastState(int userid);//得到上一次的状态信息
    void updateLastMode(int userid,QString mode);//更新模式信息

protected:
    void closeEvent(QCloseEvent *);

signals:
    void modeChanged(const QString &mode); // 添加信号

private slots:
    void on_mode_currentIndexChanged(int index);

private:
    Ui::UsersWidget *ui;
    int userid;
};

#endif // USERSWIDGET_H


#include "userswidget.h"
#include "ui_userswidget.h"
#include "sqlite.h"
#include "lights.h"
#include "aircondition.h"
#include "curtains.h"
#include "humidiffer.h"
#include "information.h"
#include "procession.h"
#include <QSqlQuery>
#include <QCloseEvent>
#include <QComboBox>
#include <QMessageBox>
#include <QSqlError>

UsersWidget::UsersWidget(int userid,QWidget *parent) :
    QWidget(parent),
    ui(new Ui::UsersWidget),
    userid(userid)
{
    ui->setupUi(this);
    displayUsersWidget();
    connect(ui->lights,&QToolButton::clicked,this,[=]{
        Lights *w = new Lights(userid);
        w->show();});
    connect(ui->air_condition,&QToolButton::clicked,this,[=]{
        AirCondition *w = new AirCondition(userid);
        w->show();});
    connect(ui->curtains,&QToolButton::clicked,this,[=]{
        Curtains *w = new Curtains(userid);
        w->show();});
    connect(ui->humidifiers,&QToolButton::clicked,this,[=]{
        Humidiffer *w = new Humidiffer(userid);
        w->show();});
    connect(ui->tables,&QToolButton::clicked,this,[=]{
        Information *w = new Information;
        w->show();});
    connect(ui->wifi,&QToolButton::clicked,this,[=]{
        Procession *w = new Procession(userid);
        w->show();});
    //模式信号和槽连接
    connect(ui->mode, QOverload<int>::of(&QComboBox::currentIndexChanged),
            this, &UsersWidget::on_mode_currentIndexChanged);
    loadLastStatus();




}

UsersWidget::~UsersWidget()
{
    delete ui;
}

void UsersWidget::displayUsersWidget()
{
    setWindowTitle("智能家居总览图");
    setFixedSize(900,600);

}

void UsersWidget::loadLastStatus()
{
    qDebug() << this->userid;
    QString state = getLastState(this->userid);
    qDebug() << state;
    if (state.compare("日常模式") == 0) {
        ui->mode->setCurrentIndex(1);
    } else if (state.compare("睡眠模式") == 0) {
        ui->mode->setCurrentIndex(2);
    } else if (state.compare("节能模式") == 0) {
        ui->mode->setCurrentIndex(3);
    } else {
        ui->mode->setCurrentIndex(0);
    }

}

void UsersWidget::saveLastStatus()
{
    qDebug() << this->userid;
    QString Mode = ui->mode->currentData().toString();
    updateLastMode(this->userid, Mode);

}

void UsersWidget::on_mode_currentIndexChanged(int mode)
{
    QString deviceName = "";
    switch (mode)
    {
        case 1:
        {
            deviceName = "智能灯";
            break;
        }
        case 2:
        {
            deviceName = "空调";
            break;
        }
        case 3:
        {
            deviceName = "窗帘";
            break;
        }
        case 4:
        {
            deviceName = "加湿器";
            break;
        }
        default:
            return;
    }

    Sqlite::sqlite_init();
    QSqlQuery query;
    query.prepare("UPDATE Status SET mode = :mode WHERE uid = :userId AND device_name = :deviceName " \
                  "AND sid = (SELECT MAX(sid) FROM Status WHERE uid = :userId AND device_name = :deviceName)");
    query.bindValue(":mode", ui->mode->currentText());
    query.bindValue(":userId", userid);
    query.bindValue(":deviceName", deviceName);
    if (!query.exec()) {
        qDebug() << "更新模式失败:" << query.lastError().text();
    }

    saveLastStatus();
}

QString UsersWidget::getLastState(int userid)
{
    Sqlite::sqlite_init();
    QString queryStr = QString("SELECT mode FROM Status WHERE uid = %1  ORDER BY sid DESC LIMIT 1").arg(userid);
    qDebug() << queryStr << userid;
    QSqlQuery query;
    qDebug () << query.exec(queryStr);
    if (query.exec(queryStr) && query.next())
    {
        return query.value(0).toString();
    }
    else
    {
        qDebug() << "得到上一次状态错误: " << query.lastError().text();
        return "";
    }
}

void UsersWidget::updateLastMode(int userid,QString mode)
{
    Sqlite::sqlite_init();
    QString queryStr = QString("UPDATE Status SET mode = %1  WHERE uid = %2 ").arg(mode).arg(userid);
    QSqlQuery query;
    if (!query.exec(queryStr))
    {
        qDebug() << "更新模式失败: " << query.lastError().text();
    }
}
void UsersWidget::closeEvent(QCloseEvent *e)
{
    if(e->spontaneous())
    {
    //窗口关闭时弹出的提示窗口
        QMessageBox::StandardButton reply;

        reply = QMessageBox::information(this,"提示","确认退出智能管家系统?",QMessageBox::Yes|QMessageBox::No);
        if(reply == QMessageBox::Yes){
            //若用户点击确认,则接收这个事件,当前窗口会关闭
            e->accept();
         }else{
            //若用户点击取消,则忽略这个事件,当前窗口不会关闭
            e->ignore();
        }
    }
}

三、使用说明

  1. 创建一个名为 database.db 的 SQLite 数据库文件。
  2. 将代码示例中的 SQL 语句复制到数据库中,创建 usersStatus 表。
  3. 编写应用程序代码,使用 SQLite 数据库 API 对数据库进行操作。
  4. 运行应用程序,测试数据库功能。

四、代码说明

  1. updateSmartHomeStatus 函数用于更新智能家居状态表中的数据。
  2. statusUid 函数用于查询智能家居状态表,获取用户对应的状态。
  3. UsersWidget 类用于显示智能家居总览图,并提供对设备状态的控制。
  4. on_mode_currentIndexChanged 函数用于处理模式选择事件,更新最新一次设备状态的 mode 信息。

五、总结

本文介绍了智能家居系统数据库的设计与实现,使用 SQLite 数据库作为数据存储,并提供了一些代码示例。通过本文的介绍,读者可以了解如何使用数据库来存储和管理智能家居系统中的数据。


原文地址: http://www.cveoy.top/t/topic/fCZ6 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录