打造智能家居:用React、Node.js和WebSocket构建ESP32设备控制面板(代码说明)
一、项目概述
在物联网(IoT)时代,智能设备的远程控制变得越来越重要。本文介绍了一个构建智能设备控制面板的项目,允许用户通过 Web 应用来控制多个 ESP32 设备。用户可以通过该面板查看设备列表,实时了解设备状态,并对设备进行操作(例如开关、调节亮度等)。
二、系统架构
为了满足项目需求,我们设计了一套系统架构,包括前端、后端、数据库和通信协议,如下图所示:
1. 单片机和设备
-
单片机:ESP32
-
设备:智能灯光、智能插座等
2. 通信协议
-
WebSocket:用于实时通信,保证设备状态的实时更新
-
RESTful API:用于设备的管理操作
3. 技术栈
-
前端:React、Vue.js 或 Angular(本文选择 React)
-
后端:Node.js、Flask 或 Django(本文选择 Node.js)
-
数据库:MongoDB 或 Firebase(本文选择 MongoDB)
三、环境搭建
1. 前端环境
安装 React 开发环境:
npx create-react-app smart-device-control-panel
cd smart-device-control-panel
npm start
2. 后端环境
安装 Node.js 和 Express:
mkdir backend
cd backend
npm init -y
npm install express mongoose body-parser ws
3. 数据库环境
安装 MongoDB:
# 对于 macOS 用户
brew tap mongodb/brew
brew install mongodb-community@5.0# 启动 MongoDB
brew services start mongodb/brew/mongodb-community
四、代码实现
1. 前端代码
在 src
目录下创建组件和服务,主要包括设备列表管理、设备控制和实时状态更新。
设备列表组件
DeviceList
组件用于显示所有设备的列表。
// src/components/DeviceList.js
import React from 'react';function DeviceList({ devices }) {return (<div><h2>设备列表</h2><ul>{devices.map((device) => (<li key={device.id}>{device.name} - {device.status}</li>))}</ul></div>);
}export default DeviceList;
设备控制组件
DeviceControl
组件用于控制设备的状态。
// src/components/DeviceControl.js
import React, { useState } from 'react';function DeviceControl({ onControl }) {const [deviceId, setDeviceId] = useState('');const [command, setCommand] = useState('');const handleSubmit = (e) => {e.preventDefault();if (deviceId && command) {onControl(deviceId, command);}};return (<div><h2>设备控制</h2><form onSubmit={handleSubmit}><div><label htmlFor="deviceId">设备 ID:</label><inputtype="text"id="deviceId"value={deviceId}onChange={(e) => setDeviceId(e.target.value)}/></div><div><label htmlFor="command">指令:</label><inputtype="text"id="command"value={command}onChange={(e) => setCommand(e.target.value)}/></div><button type="submit">发送</button></form></div>);
}export default DeviceControl;
服务模块
deviceService
模块用于与后端进行通信。
// src/services/deviceService.js
const API_URL = 'http://localhost:3000';export async function getDevices() {const response = await fetch(`${API_URL}/devices`);return response.json();
}export async function controlDevice(id, command) {await fetch(`${API_URL}/control/${id}`, {method: 'POST',headers: {'Content-Type': 'application/json',},body: JSON.stringify({ command }),});
}export function subscribeToDeviceUpdates(callback) {const ws = new WebSocket('ws://localhost:8080');ws.onmessage = (event) => {const device = JSON.parse(event.data);callback(device);};
}
主应用组件
App
组件是主应用组件,负责管理设备列表和控制操作。
// src/App.js
import React, { useState, useEffect } from 'react';
import DeviceList from './components/DeviceList';
import DeviceControl from './components/DeviceControl';
import { getDevices, controlDevice, subscribeToDeviceUpdates } from './services/deviceService';function App() {const [devices, setDevices] = useState([]);useEffect(() => {getDevices().then(setDevices);subscribeToDeviceUpdates((updatedDevice) => {setDevices((prevDevices) =>prevDevices.map((device) => (device.id === updatedDevice.id ? updatedDevice : device)));});}, []);const handleControl = (id, command) => {controlDevice(id, command);};return (<div className="App"><DeviceList devices={devices} /><DeviceControl onControl={handleControl} /></div>);
}export default App;
2. 后端代码
在 backend
目录下创建服务器和路由,处理设备管理和控制请求。
设备模型
Device
模型定义设备的结构。
// backend/models/Device.js
const mongoose = require('mongoose');const deviceSchema = new mongoose.Schema({name: String,status: String,
});module.exports = mongoose.model('Device', deviceSchema);
服务器和路由
server.js
文件设置服务器,处理设备列表和控制请求,并通过 WebSocket 实现实时状态更新。
// backend/server.js
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const WebSocket = require('ws');
const Device = require('./models/Device');const app = express();
const wss = new WebSocket.Server({ port: 8080 });
app.use(bodyParser.json());// RESTful API
app.get('/devices', async (req, res) => {const devices = await Device.find();res.json(devices);
});app.post('/control/:id', async (req, res) => {const { id } = req.params;const { command } = req.body;// 发送控制命令给设备// 这里可以通过与 ESP32 设备通信的特定实现来发送命令const device = await Device.findById(id);if (device) {// 更新设备状态逻辑device.status = command.status; // 假设 command 包含 status 属性await device.save();// 通知所有 WebSocket 客户端wss.clients.forEach((client) => {if (client.readyState === WebSocket.OPEN) {client.send(JSON.stringify(device));}});res.sendStatus(200);} else {res.sendStatus(404);}
});// WebSocket
wss.on('connection', (ws) => {ws.on('message', (message) => {const { id, status } = JSON.parse(message);Device.findByIdAndUpdate(id, { status }, { new: true }, (err, device) => {if (err) return;wss.clients.forEach((client) => {if (client.readyState === WebSocket.OPEN) {client.send(JSON.stringify(device));}});});});
});app.listen(3000, () => {console.log('后端服务器在 http://localhost:3000 运行');
});
代码说明
前端代码说明
- DeviceList 组件 (
DeviceList.js
)
-
用于显示设备列表。
-
从
props
获取设备数据,并生成设备列表的 HTML 元素。
- DeviceControl 组件 (
DeviceControl.js
)
-
用于控制设备。
-
包含设备 ID 和控制指令的输入框,并在表单提交时调用
onControl
函数。
- deviceService 模块 (
deviceService.js
)
-
getDevices
函数:从后端获取设备列表。 -
controlDevice
函数:向后端发送控制设备的指令。 -
subscribeToDeviceUpdates
函数:通过 WebSocket 订阅设备状态更新。
- App 组件 (
App.js
)
-
主应用组件,管理设备列表和控制操作。
-
使用
useEffect
钩子在组件挂载时获取设备列表,并订阅设备状态更新。 -
handleControl
函数调用controlDevice
发送控制指令。
后端代码说明
- 设备模型 (
Device.js
)
- 定义设备的 Mongoose 模型,包含
name
和status
属性。
- 服务器和路由 (
server.js
)
-
监听客户端连接和消息,更新设备状态并通知所有客户端。
-
GET /devices
:获取所有设备。 -
POST /control/:id
:控制指定 ID 的设备,并通过 WebSocket 通知所有客户端。 -
使用 Express 创建服务器,并连接到 MongoDB 数据库。
五、项目总结
在本项目中,我们构建了一个智能设备控制面板,用户可以通过 Web 应用控制多个 ESP32 设备。项目使用 React 构建前端,用 Node.js 和 Express 搭建后端,使用 MongoDB 存储设备数据,并通过 WebSocket 实现设备状态的实时更新。项目架构清晰,功能完备,为用户提供了良好的体验。
相关文章:

打造智能家居:用React、Node.js和WebSocket构建ESP32设备控制面板(代码说明)
一、项目概述 在物联网(IoT)时代,智能设备的远程控制变得越来越重要。本文介绍了一个构建智能设备控制面板的项目,允许用户通过 Web 应用来控制多个 ESP32 设备。用户可以通过该面板查看设备列表,实时了解设备状态&am…...

计网:从输入URL到网页显示期间发生了什么
1、URL包含的信息 我们输入的url中包含着一些信息: http:表示的此次我们使用的什么协议/www.baidu.com:表示的是我们想要访问的服务器名称,也就是域名dir3/home.html:表示我们所要访问的资源 2、通过DNS解析URL获得I…...

龚宇引以为傲的“爆款制造营”,爱奇艺怕是要爽约了
文:互联网江湖 作者:刘致呈 人们经常用人红戏不红,来形容毯星,综艺上咋咋呼呼,一提都知道,可问及代表作,不好意思,这个真没有。 今年的爱奇艺,貌似也迎来了这一宿命。 …...

org.springframework.web.client.HttpClientErrorException$NotFound异常
springCloud报错信息:org.springframework.web.client.HttpClientErrorException$NotFound: 404 null第一点: 第二点:没有httpclient工具类 注入RestTmeplate类时,改类需要RestController或ResponseBody...

在开关电源转换器中充分利用碳化硅器件的性能优势
在过去的几十年中,半导体行业已经采取了许多措施来改善基于硅 MOSFET (parasitic parameters),以满足开关转换器(开关电源)设计人员的需求。行业效率標準以及市场对效率技术需求的双重作用,导致了对于可用于构建更高效…...

QObject::connect: Cannot queue arguments of type ‘QList<QString>‘
QObject::connect: Cannot queue arguments of type ‘QList’ QObject::connect: Cannot queue arguments of type QList<QString> (Make sure QList<QString> is registered using qRegisterMetaType().)使用信号和槽时,QList无法当做参数被传递&…...

基于K8S部署安装Jenkins
基于K8S部署安装Jenkins 1.Jenkins Kubernetes 清单文件2.Kubernetes Jenkins 部署1:为 Jenkins 创建 Namespace。 最好将所有DevOps工具分类为与其他应用程序分开的命名空间。2:创建“serviceAccount.yaml”文件并复制以下管理员服务帐户清单。1. kubec…...

24-8-4-读书笔记(十三)-《莎士比亚全集》(第一卷(续)) [英] 威廉·莎士比亚 [译]朱生豪
文章目录 《莎士比亚全集》(第一卷(续))目录阅读笔记记录总结《莎士比亚全集》(第一卷(续)) 《莎士比亚全集》朱生豪的经典译本,非常值得花时间去读一读,莎氏的巨作有其独特的韵味,与莫里哀、契诃夫、曹禺等其他国家的剧作家有其鲜明的特点,这既是源于其所处的时代…...

linux nicstat
nicstat 是一个用于监控和报告网络接口统计信息的工具。它可以提供关于网络接口的详细性能数据,包括传输速率、错误率、丢包率等。nicstat 对于诊断网络性能问题和优化网络配置非常有用。 安装 nicstat nicstat 可能不在所有Linux发行版的默认软件库中,…...

程序员如何积累人脉?光靠技术不行了~
从事技术的人,还没被社会“塑造”前,总会有一个“固有思维”,就是这个世界大概率是“由代码和逻辑主宰的世界”,人脉积累并不在考虑范围内,而我们也常被误解为只懂得与机器对话的technician。 事实上,游戏…...

初识增强现实(AR)
初识增强现实(AR) 笔记来源: 1.2023年中国增强现实(AR)行业研究报告 2.wiki/Augmented reality 3.In-Depth Review of Augmented Reality: Tracking Technologies, Development Tools, AR Displays, Collaborative AR…...

开关电源起振是什么看了就知道
接触开关电源的朋友都知道,含有电源管理芯片的开关电源有输入,没输出时常说是不是电路没起振,到底这句话是什么意思呢?什么是“起振”先不做 的解释,简单打个比方,大家就容易懂了,就好像抢救心…...

Modbus_Ascii协议
设备必须要有RTU协议!这是Modbus协议上规定的,且默认模式必须是RTU,ASCII作为选项。(也就是说,一般的设备只有RTU这个协议,ASCII一般很少)所以说,一般学习Modbus协议,只需…...

树莓派在功能和成本之间的 “惊人平衡 “支持了全球数字标牌的成功故事!
树莓派的“功能和成本之间的惊人平衡”支撑全球数字标牌成功故事 数字标牌已经成为一个数十亿美元的行业。Yodeck很快预测到了其中的潜力:他们需要硬件来支持他们可靠、具有成本效益和易于管理的服务,而不会影响性能。事实证明,树莓派 4 证明…...

C++ 学习记录
文章目录 继承重载和重写区别重载重写 参考文献 继承 继承顾名思义就是对长辈本有的东西进行获取与使用,即两个以及两个类以上的关系在获取与使用时会存在一些情况: public:长辈对外公开的自身所有物,最终都会是后代的protected&…...

C#中的TCP和UDP
TcpClient TCP客户端 UDP客户端 tcp和udp的区别 TCP(传输控制协议)和UDP(用户数据报协议)是两种在网络通信中常用的传输层协议,它们在C#或任何其他编程语言中都具有相似的特性。下面是TCP和UDP的主要区别:…...

Spring中使用嵌套事务及事务保存点
嵌套事务及事务保存点 Spring中的嵌套事务与事务保存点1. 什么是嵌套事务?2. 为什么使用嵌套事务?3. 如何在Spring中使用嵌套事务?4. 使用事务保存点5. 总结 Spring框架提供了强大的事务管理功能,包括对嵌套事务的支持。在Spring中…...

SFT、RLHF、DPO、IFT —— LLM 微调的进化之路
TL;DR • SFT、RLHF 和 DPO 都是先估计 LLMs 本身的偏好,再与人类的偏好进行对齐; • SFT 只通过 LLMs 生成的下一个单词进行估计,而 RLHF 和 DPO 通过 LLMs 生成的完整句子进行估计,显然后者的估计会更准确; • 虽然…...

【数据结构】LinkedList与链表
目录 链表 1、链表的概念及结构 2、LinkedList的使用 2、1什么是LinkedList 2、2LinkedList的使用 3、LinkedList的遍历 4、LinkedList的模拟实现 5、ArrayList和LinkedList的区别 上篇已经熟悉了ArrayList的使用,ArrayList底层使用数组来存储元素。由于其底层…...

《LeetCode热题100》---<5.①普通数组篇五道>
本篇博客讲解LeetCode热题100道普通数组篇中的五道题 第一道:最大子数组和(中等) 第二道:合并区间(中等) 第一道:最大子数组和(中等) 法一:贪心算法 class So…...

根据id查找树形结构中匹配数据与上级所有数据
背后 在用户管理业务开发过程中,通常需要查询出用户管理的菜单数据和当前菜单的所有上级数据。为了方便后续的cv工作,我打算把这种方法记录下来,以备不时之需. 代码实现细节 Data public class MenuDTO {Schema(description "菜单id&qu…...

探索亚马逊Amazon S3:无缝存储管理与极速数据传输的奥秘
亚马逊云科技中Amazon S3,因其设计简单与高度可靠,允许用户通过互联网存储和检索任意数量的数据,并能够自动扩展以满足各种规模的需求,使得Amazon S3成为了许多云计算应用和网站的核心存储基础设施之一,Amazon S3提供的…...

Linux_监测CPU和内存
通过TOP持续获取进程的CPU和内存消耗,并写入到表格 # 配置进程名 processvm-agent # 配置次数 number100 # 配置间隔时间 time5 # csv结果文件 filecm_$(date %s).csv echo "%CPU,%MEM">${file} pid$(ps -aux | grep ${process} | awk -F {OFS"…...

OpenCV经典案例:01 答题卡识别
目录 透视变换矫正 选项识别匹配 QT 界面设计 引言:随着信息化的发展,计算机阅卷已经成为一种常规操作。在大型考试中,客观题基本不再 需要人工阅卷。本项目旨在开发一个基于OpenCV的高效答题卡识别系统,通过先进的图像处理和模…...

进程的管理与控制详解:创建、终止、阻塞等待与非阻塞等待
目录 一、进程创建 1、实例 2、fork函数详解 (1)fork函数模板 (2). fork() 函数的工作原理 (3). fork() 返回值和错误处理 3、如何理解进程创建过程 二、进程终止 1、终止是在做什么? 2、进程终止,有三种情况 3、进程如何终止? 三…...

【从零开始一步步学习VSOA开发】开发环境搭建
开发环境搭建 开发 VSOA 首先需要搭建开发环境,这里讲解 Windows 下 C/C 开发环境搭建方法。 下载 IDE 并申请授权码 SylixOS 的开发和部署需要 RealEvo-IDE 的支持,因此您需要先获取 RealEvo-IDE 的安装包和注册码。 RealEvo-IDE 分为体验版和商业版…...

一篇文章让你用我的世界中的红石搞懂什么是ALU!
目录 1.一些在开始的约定 2.七大逻辑门电路 1、 与门 2、 或门 3、 非门 5、 或非门 6、 异或门 7、 同或门 3.半加器 4.全加器 5.ALU 1.一些在开始的约定 相同的概念:相同的概念:高电平低电平逻辑真逻辑假 开关的开 开关的关 灯的亮 灯…...

硬盘数据恢复:所需时长、全面指南及注意事项
在数字化时代,硬盘作为我们存储重要数据的核心设备,其重要性不言而喻。然而,由于各种原因,如误删除、格式化、硬盘故障等,我们时常面临数据丢失的困境。数据恢复不仅关乎个人隐私和信息安全,更可能影响到我…...

基于SpringBoot+Vue的科研管理系统(带1w+文档)
基于SpringBootVue的科研管理系统(带1w文档) 基于SpringBootVue的科研管理系统(带1w文档) 科研的管理系统设计过程中采用Java开发语言,B/S结构,采取springboot框架,并以MySql为数据库进行开发。结合以上技术,对本系统的整体、数据库、功能模块…...

计算机组成原理 —— 五段式指令流水线
计算机组成原理 —— 五段式指令流水线 五段式指令流水线运算类指令LOAD指令的执行过程STORE指令的执行过程条件转移指令执行过程无条件转移指令的执行过程 我们今天来看看五段式指令流水线: 五段式指令流水线 五段式指令流水线是一种常见的处理器架构设计中采用的…...