当前位置: 首页 > 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…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…...

CMake 从 GitHub 下载第三方库并使用

有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

Linux离线(zip方式)安装docker

目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1&#xff1a;修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本&#xff1a;CentOS 7 64位 内核版本&#xff1a;3.10.0 相关命令&#xff1a; uname -rcat /etc/os-rele…...

接口自动化测试:HttpRunner基础

相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具&#xff0c;支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议&#xff0c;涵盖接口测试、性能测试、数字体验监测等测试类型…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)

题目 做法 启动靶机&#xff0c;点进去 点进去 查看URL&#xff0c;有 ?fileflag.php说明存在文件包含&#xff0c;原理是php://filter 协议 当它与包含函数结合时&#xff0c;php://filter流会被当作php文件执行。 用php://filter加编码&#xff0c;能让PHP把文件内容…...

高防服务器价格高原因分析

高防服务器的价格较高&#xff0c;主要是由于其特殊的防御机制、硬件配置、运营维护等多方面的综合成本。以下从技术、资源和服务三个维度详细解析高防服务器昂贵的原因&#xff1a; 一、硬件与技术投入 大带宽需求 DDoS攻击通过占用大量带宽资源瘫痪目标服务器&#xff0c;因此…...

Vue3中的computer和watch

computed的写法 在页面中 <div>{{ calcNumber }}</div>script中 写法1 常用 import { computed, ref } from vue; let price ref(100);const priceAdd () > { //函数方法 price 1price.value ; }//计算属性 let calcNumber computed(() > {return ${p…...