基于SQLite和TCP的智能家居建议系统

概述

本教程将指导您使用Linux C语言构建一个服务器,并使用QT C++在Windows上创建一个客户端,最终实现一个简单的智能家居建议系统。

功能

  • 客户端连接到服务器并发送用户ID (userid)。
  • 服务器从SQLite数据库中检索与该用户ID相关联的最新设备状态数据。
  • 服务器分析设备状态数据(例如,温度、湿度)并生成相应的建议。
  • 服务器将建议发送回客户端。
  • 客户端在GUI界面上显示建议。

数据库设计

我们将使用SQLite数据库来存储设备状态信息。以下是数据库'database.db'的设计:

users表

| 列名 | 数据类型 | 描述 | |---|---|---| | uid | INTEGER PRIMARY KEY AUTOINCREMENT | 用户ID | | username | varchar(10) | 用户名 | | passwd | varchar(10) | 密码 |

Status表

| 列名 | 数据类型 | 描述 | |---|---|---| | sid | INTEGER PRIMARY KEY AUTOINCREMENT | 状态ID | | uid | INTEGER | 用户ID (外键关联users表) | | device_name | varchar(10) | 设备名称 (例如:'空调', '加湿器') | | device_state | varchar(10) | 设备状态 (例如:'开启', '关闭')| | value | varchar(10) | 设备状态值 (例如:温度值,湿度值) | | mode | varchar(10) | 设备模式 (例如:'制冷', '制热', '自动') |

代码实现

服务器端代码 (server.c)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sqlite3.h>

#define PORT 8080

void generate_suggestion(int uid, char* suggestion) {
    // 连接数据库
    sqlite3* db;
    if (sqlite3_open('database.db', &db) != SQLITE_OK) {
        fprintf(stderr, '无法打开数据库\n');
        return;
    }

    // 查询最新的设备信息
    char query[100];
    snprintf(query, sizeof(query), 'SELECT device_name, value FROM Status WHERE uid=%d ORDER BY sid DESC LIMIT 1', uid);

    sqlite3_stmt* stmt;
    if (sqlite3_prepare_v2(db, query, -1, &stmt, NULL) != SQLITE_OK) {
        fprintf(stderr, '查询失败\n');
        sqlite3_close(db);
        return;
    }

    char device_name[10];
    char value[10];
    if (sqlite3_step(stmt) == SQLITE_ROW) {
        strcpy(device_name, sqlite3_column_text(stmt, 0));
        strcpy(value, sqlite3_column_text(stmt, 1));
    }

    sqlite3_finalize(stmt);
    sqlite3_close(db);

    // 根据设备信息生成建议
    if (strcmp(device_name, '空调') == 0) {
        int temperature = atoi(value);
        if (temperature < 24) {
            snprintf(suggestion, 100, '空调温度过低,建议提高温度至26℃');
        } else {
            snprintf(suggestion, 100, '空调温度正常');
        }
    } else if (strcmp(device_name, '加湿器') == 0) {
        int humidity = atoi(value);
        if (humidity < 40) {
            snprintf(suggestion, 100, '加湿器湿度过低,建议调整加湿器湿度');
        } else if (humidity > 70) {
            snprintf(suggestion, 100, '加湿器湿度过高,建议调整加湿器湿度');
        } else {
            snprintf(suggestion, 100, '加湿器湿度正常');
        }
    } else {
        snprintf(suggestion, 100, '设备信息不存在');
    }
}

int main() {
    int server_fd, new_socket;
    struct sockaddr_in address;
    int addrlen = sizeof(address);

    // 创建服务器套接字
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
        perror('套接字创建失败');
        exit(EXIT_FAILURE);
    }

    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(PORT);

    // 将套接字绑定到指定的IP和端口
    if (bind(server_fd, (struct sockaddr*)&address, sizeof(address)) < 0) {
        perror('绑定失败');
        exit(EXIT_FAILURE);
    }

    // 监听连接
    if (listen(server_fd, 3) < 0) {
        perror('监听失败');
        exit(EXIT_FAILURE);
    }

    // 接受新的连接
    if ((new_socket = accept(server_fd, (struct sockaddr*)&address, (socklen_t*)&addrlen)) < 0) {
        perror('接受连接失败');
        exit(EXIT_FAILURE);
    }

    // 接收userid
    int uid;
    if (recv(new_socket, &uid, sizeof(uid), 0) <= 0) {
        perror('接收userid失败');
        exit(EXIT_FAILURE);
    }

    // 生成建议
    char suggestion[100];
    generate_suggestion(uid, suggestion);

    // 发送建议
    send(new_socket, suggestion, strlen(suggestion), 0);

    close(new_socket);
    close(server_fd);

    return 0;
}

客户端代码 (client.h)

#ifndef CLIENT_H
#define CLIENT_H

#include <QtWidgets>
#include <QtNetwork>

class Client : public QWidget {
    Q_OBJECT

public:
    explicit Client(QWidget *parent = nullptr);

private slots:
    void connectToServer();

private:
    QTextEdit *textEdit;
    QTcpSocket *socket;
};

#endif // CLIENT_H

客户端代码 (client.cpp)

#include 'client.h'

Client::Client(QWidget *parent) : QWidget(parent) {
    QPushButton *connectButton = new QPushButton('连接');
    textEdit = new QTextEdit;

    connect(connectButton, &QPushButton::clicked, this, &Client::connectToServer);

    QVBoxLayout *layout = new QVBoxLayout;
    layout->addWidget(connectButton);
    layout->addWidget(textEdit);

    setLayout(layout);
}

void Client::connectToServer() {
    // 创建套接字
    socket = new QTcpSocket(this);

    // 连接到服务器
    socket->connectToHost('127.0.0.1', 8080);

    if (socket->waitForConnected()) {
        // 连接成功,发送userid
        int uid = 1; // 示例userid
        socket->write(reinterpret_cast<const char*>(&uid), sizeof(uid));
        socket->waitForBytesWritten();

        // 接收建议
        QByteArray suggestion = socket->readAll();
        textEdit->setText(suggestion);
    } else {
        // 连接失败
        textEdit->setText('连接失败');
    }

    socket->close();
}

客户端主程序 (main.cpp)

#include 'client.h'
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Client w;
    w.show();
    return a.exec();
}

编译和运行

编译服务器端

gcc server.c -o server -lsqlite3

编译客户端

g++ client.cpp -o client -lQt5Widgets -lQt5Network

运行

  1. 确保 'database.db' 数据库文件存在,并包含示例数据。
  2. 首先启动服务器端程序。
  3. 然后运行客户端程序,点击“连接”按钮,即可连接服务器并接收建议。

总结

本教程提供了一个简单的智能家居建议系统的基本框架,您可以根据自己的需求进行扩展和修改。例如,您可以添加更多类型的设备、更复杂的建议算法以及更友好的用户界面。

基于SQLite和TCP的智能家居建议系统

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

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