基于C++ Socket和SQLite的智能家居状态监控系统
基于C++ Socket和SQLite的智能家居状态监控系统
本文将介绍如何使用Linux C语言和QT C++编写一个简单的智能家居状态监控系统,该系统包含服务器端和客户端,并使用SQLite数据库进行数据存储。
系统架构
本系统采用C/S架构,服务器端使用Linux C语言编写,客户端使用QT C++编写,并通过TCP协议进行通信。服务器端负责接收客户端发送的用户ID,查询数据库获取该用户对应的智能家居设备状态信息,并根据预设规则生成建议信息发送给客户端。客户端负责发送用户ID给服务器,并接收服务器返回的建议信息。
数据库设计
数据库名为database.db,包含两张表:
users表:存储用户信息,包括用户ID和用户名、密码。*Status表:存储智能家居设备状态信息,包括状态ID、用户ID、设备名称、设备状态、数值和模式。
**SQL语句:**sql-- 创建用户表CREATE TABLE IF NOT EXISTS users ( uid INTEGER PRIMARY KEY AUTOINCREMENT, username varchar(10), passwd varchar(10));
-- 创建智能家居状态表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(10), FOREIGN KEY (uid) REFERENCES users (uid));
服务器端代码
服务器端代码分为四个文件:server.h、server.cpp、database.h和database.cpp。
**server.h:**c++#ifndef SERVER_H#define SERVER_H
#include
class Server : public QObject{ Q_OBJECTpublic: explicit Server(QObject *parent = nullptr);
signals:
public slots: void newConnection(); void readyRead(); void disconnected();
private: QTcpServer *tcpServer; QTcpSocket *clientSocket; QSqlDatabase db;
void sendSuggestion(int uid);};
#endif // SERVER_H
**server.cpp:**c++#include 'server.h'#include
Server::Server(QObject *parent) : QObject(parent){ tcpServer = new QTcpServer(this); connect(tcpServer, SIGNAL(newConnection()), this, SLOT(newConnection()));
if (!tcpServer->listen(QHostAddress::Any, 1234)) { qDebug() << 'Server could not start!'; } else { qDebug() << 'Server started!'; }
db = QSqlDatabase::addDatabase('QSQLITE'); db.setDatabaseName('database.db'); if (!db.open()) { qDebug() << 'Database could not be opened!'; }}
void Server::newConnection(){ clientSocket = tcpServer->nextPendingConnection(); connect(clientSocket, SIGNAL(readyRead()), this, SLOT(readyRead())); connect(clientSocket, SIGNAL(disconnected()), this, SLOT(disconnected()));}
void Server::readyRead(){ QByteArray data = clientSocket->readAll(); int uid = data.toInt(); sendSuggestion(uid);}
void Server::disconnected(){ clientSocket->deleteLater();}
void Server::sendSuggestion(int uid){ QSqlQuery query; QString deviceName; QString deviceState; QString value;
query.prepare('SELECT device_name, device_state, value FROM Status WHERE uid = :uid'); query.bindValue(':uid', uid); if (!query.exec()) { qDebug() << 'Query failed: ' << query.lastError().text(); return; }
while (query.next()) { deviceName = query.value(0).toString(); deviceState = query.value(1).toString(); value = query.value(2).toString(); }
QString suggestion; if (deviceName == '空调') { if (deviceState == '开启' && value.toInt() < 24) { suggestion = '空调温度过低,建议提高温度至26℃'; } } else if (deviceName == '加湿器') { int humidity = value.toInt(); if (deviceState == '开启' && (humidity < 40 || humidity > 70)) { suggestion = '加湿器湿度过高或过低,建议调整加湿器湿度'; } }
QByteArray suggestionData = suggestion.toUtf8(); clientSocket->write(suggestionData);}
**database.h:**c++#ifndef DATABASE_H#define DATABASE_H
#include
class Database : public QObject{ Q_OBJECTpublic: explicit Database(QObject *parent = nullptr);
void updateStatus(int uid, QString deviceName, QString deviceState, QString value);
signals:
public slots:
private: QSqlDatabase db;};
#endif // DATABASE_H
**database.cpp:**c++#include 'database.h'#include
Database::Database(QObject *parent) : QObject(parent){ db = QSqlDatabase::addDatabase('QSQLITE'); db.setDatabaseName('database.db'); if (!db.open()) { qDebug() << 'Database could not be opened!'; }}
void Database::updateStatus(int uid, QString deviceName, QString deviceState, QString value){ QSqlQuery query; query.prepare('INSERT INTO Status (uid, device_name, device_state, value) VALUES (:uid, :deviceName, :deviceState, :value)'); query.bindValue(':uid', uid); query.bindValue(':deviceName', deviceName); query.bindValue(':deviceState', deviceState); query.bindValue(':value', value);
if (!query.exec()) { qDebug() << 'Query failed: ' << query.lastError().text(); }}
客户端代码
客户端代码分为两个文件:client.h和client.cpp。
**client.h:**cpp#ifndef CLIENT_H#define CLIENT_H
#include
class Client : public QObject{ Q_OBJECTpublic: explicit Client(QObject *parent = nullptr);
signals:
public slots: void connectToServer(); void readyRead();
private: QTcpSocket *socket; QTextEdit *textEdit; QPushButton *button;};
#endif // CLIENT_H
**client.cpp:**cpp#include 'client.h'#include
Client::Client(QObject *parent) : QObject(parent){ socket = new QTcpSocket(this); connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()));
textEdit = new QTextEdit(); button = new QPushButton('Connect'); connect(button, SIGNAL(clicked()), this, SLOT(connectToServer()));}
void Client::connectToServer(){ socket->connectToHost(QHostAddress::LocalHost, 1234); if (!socket->waitForConnected()) { textEdit->append('Connection failed!'); }}
void Client::readyRead(){ QByteArray data = socket->readAll(); QString suggestion = QString::fromUtf8(data); textEdit->append(suggestion);}
总结
本文介绍了如何使用C++ Socket编程和SQLite数据库实现一个简单的智能家居状态监控系统。通过学习本例,您可以了解C/S架构、TCP协议、SQLite数据库以及QT编程等知识。当然,这只是一个简单的示例,您可以根据自己的需求进行扩展和改进,例如添加更多类型的智能家居设备、实现更复杂的控制逻辑等。
原文地址: http://www.cveoy.top/t/topic/fB6T 著作权归作者所有。请勿转载和采集!