当前位置: 首页 > news >正文

打造智能家居:用React、Node.js和WebSocket构建ESP32设备控制面板(代码说明)

一、项目概述

在物联网(IoT)时代,智能设备的远程控制变得越来越重要。本文介绍了一个构建智能设备控制面板的项目,允许用户通过 Web 应用来控制多个 ESP32 设备。用户可以通过该面板查看设备列表,实时了解设备状态,并对设备进行操作(例如开关、调节亮度等)。

二、系统架构

为了满足项目需求,我们设计了一套系统架构,包括前端、后端、数据库和通信协议,如下图所示:

用户
前端
后端
数据库
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 运行');
});

代码说明

前端代码说明
  1. DeviceList 组件 (DeviceList.js)
  • 用于显示设备列表。

  • props 获取设备数据,并生成设备列表的 HTML 元素。

  1. DeviceControl 组件 (DeviceControl.js)
  • 用于控制设备。

  • 包含设备 ID 和控制指令的输入框,并在表单提交时调用 onControl 函数。

  1. deviceService 模块 (deviceService.js)
  • getDevices 函数:从后端获取设备列表。

  • controlDevice 函数:向后端发送控制设备的指令。

  • subscribeToDeviceUpdates 函数:通过 WebSocket 订阅设备状态更新。

  1. App 组件 (App.js)
  • 主应用组件,管理设备列表和控制操作。

  • 使用 useEffect 钩子在组件挂载时获取设备列表,并订阅设备状态更新。

  • handleControl 函数调用 controlDevice 发送控制指令。

后端代码说明
  1. 设备模型 (Device.js)
  • 定义设备的 Mongoose 模型,包含 namestatus 属性。
  1. 服务器和路由 (server.js)
  • 监听客户端连接和消息,更新设备状态并通知所有客户端。

  • GET /devices:获取所有设备。

  • POST /control/:id:控制指定 ID 的设备,并通过 WebSocket 通知所有客户端。

  • 使用 Express 创建服务器,并连接到 MongoDB 数据库。

五、项目总结

在本项目中,我们构建了一个智能设备控制面板,用户可以通过 Web 应用控制多个 ESP32 设备。项目使用 React 构建前端,用 Node.js 和 Express 搭建后端,使用 MongoDB 存储设备数据,并通过 WebSocket 实现设备状态的实时更新。项目架构清晰,功能完备,为用户提供了良好的体验。

相关文章:

打造智能家居:用React、Node.js和WebSocket构建ESP32设备控制面板(代码说明)

一、项目概述 在物联网&#xff08;IoT&#xff09;时代&#xff0c;智能设备的远程控制变得越来越重要。本文介绍了一个构建智能设备控制面板的项目&#xff0c;允许用户通过 Web 应用来控制多个 ESP32 设备。用户可以通过该面板查看设备列表&#xff0c;实时了解设备状态&am…...

计网:从输入URL到网页显示期间发生了什么

1、URL包含的信息 我们输入的url中包含着一些信息&#xff1a; http&#xff1a;表示的此次我们使用的什么协议/www.baidu.com&#xff1a;表示的是我们想要访问的服务器名称&#xff0c;也就是域名dir3/home.html&#xff1a;表示我们所要访问的资源 2、通过DNS解析URL获得I…...

龚宇引以为傲的“爆款制造营”,爱奇艺怕是要爽约了

文&#xff1a;互联网江湖 作者&#xff1a;刘致呈 人们经常用人红戏不红&#xff0c;来形容毯星&#xff0c;综艺上咋咋呼呼&#xff0c;一提都知道&#xff0c;可问及代表作&#xff0c;不好意思&#xff0c;这个真没有。 今年的爱奇艺&#xff0c;貌似也迎来了这一宿命。 …...

org.springframework.web.client.HttpClientErrorException$NotFound异常

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

在开关电源转换器中充分利用碳化硅器件的性能优势

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

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().)使用信号和槽时&#xff0c;QList无法当做参数被传递&…...

基于K8S部署安装Jenkins

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

24-8-4-读书笔记(十三)-《莎士比亚全集》(第一卷(续)) [英] 威廉·莎士比亚 [译]朱生豪

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

linux nicstat

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

程序员如何积累人脉?光靠技术不行了~

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

初识增强现实(AR)

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

开关电源起振是什么看了就知道

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

Modbus_Ascii协议

设备必须要有RTU协议&#xff01;这是Modbus协议上规定的&#xff0c;且默认模式必须是RTU&#xff0c;ASCII作为选项。&#xff08;也就是说&#xff0c;一般的设备只有RTU这个协议&#xff0c;ASCII一般很少&#xff09;所以说&#xff0c;一般学习Modbus协议&#xff0c;只需…...

树莓派在功能和成本之间的 “惊人平衡 “支持了全球数字标牌的成功故事!

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

C++ 学习记录

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

C#中的TCP和UDP

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

Spring中使用嵌套事务及事务保存点

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

SFT、RLHF、DPO、IFT —— LLM 微调的进化之路

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

【数据结构】LinkedList与链表

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

《LeetCode热题100》---<5.①普通数组篇五道>

本篇博客讲解LeetCode热题100道普通数组篇中的五道题 第一道&#xff1a;最大子数组和&#xff08;中等&#xff09; 第二道&#xff1a;合并区间&#xff08;中等&#xff09; 第一道&#xff1a;最大子数组和&#xff08;中等&#xff09; 法一&#xff1a;贪心算法 class So…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

基于服务器使用 apt 安装、配置 Nginx

&#x1f9fe; 一、查看可安装的 Nginx 版本 首先&#xff0c;你可以运行以下命令查看可用版本&#xff1a; apt-cache madison nginx-core输出示例&#xff1a; nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

在四层代理中还原真实客户端ngx_stream_realip_module

一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡&#xff08;如 HAProxy、AWS NLB、阿里 SLB&#xff09;发起上游连接时&#xff0c;将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后&#xff0c;ngx_stream_realip_module 从中提取原始信息…...

听写流程自动化实践,轻量级教育辅助

随着智能教育工具的发展&#xff0c;越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式&#xff0c;也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建&#xff0c;…...

Vite中定义@软链接

在webpack中可以直接通过符号表示src路径&#xff0c;但是vite中默认不可以。 如何实现&#xff1a; vite中提供了resolve.alias&#xff1a;通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...

FFmpeg avformat_open_input函数分析

函数内部的总体流程如下&#xff1a; avformat_open_input 精简后的代码如下&#xff1a; int avformat_open_input(AVFormatContext **ps, const char *filename,ff_const59 AVInputFormat *fmt, AVDictionary **options) {AVFormatContext *s *ps;int i, ret 0;AVDictio…...

聚六亚甲基单胍盐酸盐市场深度解析:现状、挑战与机遇

根据 QYResearch 发布的市场报告显示&#xff0c;全球市场规模预计在 2031 年达到 9848 万美元&#xff0c;2025 - 2031 年期间年复合增长率&#xff08;CAGR&#xff09;为 3.7%。在竞争格局上&#xff0c;市场集中度较高&#xff0c;2024 年全球前十强厂商占据约 74.0% 的市场…...

数据分析六部曲?

引言 上一章我们说到了数据分析六部曲&#xff0c;何谓六部曲呢&#xff1f; 其实啊&#xff0c;数据分析没那么难&#xff0c;只要掌握了下面这六个步骤&#xff0c;也就是数据分析六部曲&#xff0c;就算你是个啥都不懂的小白&#xff0c;也能慢慢上手做数据分析啦。 第一…...

深入理解 React 样式方案

React 的样式方案较多,在应用开发初期,开发者需要根据项目业务具体情况选择对应样式方案。React 样式方案主要有: 1. 内联样式 2. module css 3. css in js 4. tailwind css 这些方案中,均有各自的优势和缺点。 1. 方案优劣势 1. 内联样式: 简单直观,适合动态样式和…...

VUE3 ref 和 useTemplateRef

使用ref来绑定和获取 页面 <headerNav ref"headerNavRef"></headerNav><div click"showRef" ref"buttonRef">refbutton</div>使用ref方法const后面的命名需要跟页面的ref值一样 const buttonRef ref(buttonRef) cons…...