基于SQLite和TCP的智能家居建议系统
基于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
运行
- 确保 'database.db' 数据库文件存在,并包含示例数据。
- 首先启动服务器端程序。
- 然后运行客户端程序,点击“连接”按钮,即可连接服务器并接收建议。
总结
本教程提供了一个简单的智能家居建议系统的基本框架,您可以根据自己的需求进行扩展和修改。例如,您可以添加更多类型的设备、更复杂的建议算法以及更友好的用户界面。
原文地址: http://www.cveoy.top/t/topic/fB7U 著作权归作者所有。请勿转载和采集!