【智能家居入门2】(MQTT协议、微信小程序、STM32、ONENET云平台)
此篇智能家居入门与前两篇类似,但是是使用MQTT协议接入ONENET云平台,实现微信小程序与下位机的通信,这里相较于使用http协议的那两篇博客,在主程序中添加了独立看门狗防止程序卡死和服务器掉线问题。后续还有使用MQTT协议连接MQTT服务器的智能家居项目。
- 前言
- 一、硬件模块
- 二、连接服务器测试
- 三、两个协议的对比分析
- 1、代码结构上:
- 2、获取服务器数据上:
- 3、架构上:
- 四、下位机主要代码
- 1、接收并解析云平台下发数据:
- 2、传感器数据上云:
- 五、微信小程序主要代码
- 1、index.js
- 2、index.wxml
- 六、源码获取
前言
这里给出前两篇使用http协议博客的网址:
①实现数据上云:https://blog.csdn.net/m0_71523511/article/details/135892908
②实现小程序控制下位机:https://blog.csdn.net/m0_71523511/article/details/135907645
在第二篇的博客结尾提出了服务器经常掉线的问题,使用别人编写好的心跳包也没用,因为程序一直卡死在重连中,所以也可以参照本篇的解决办法:加上独立看门狗,隔一段时间喂狗,如果超过时间没喂狗,说明程序多半卡死,此时看门狗处理逻辑中执行初始化esp8266和连接服务器的操作。
③独立看门狗:https://www.bilibili.com/video/BV1th411z7sn/?p=46&spm_id_from=pageDriver&vd_source=2a10d30b8351190ea06d85c5d0bfcb2a
④由于使用到了MQTT协议,想深入了解源码的话可以看看之前的的博客,对MQTT协议进行详解:https://blog.csdn.net/m0_71523511/article/details/135905690
一、硬件模块
1、0.96寸OLED液晶显示屏
2、DHT11温湿度传感器
3、继电器
4、小风扇、小水泵
5、MQ-4、MQ-9
6、esp8266-01s或者esp-12f
7、JLink下载器
8、STM32F103C8T6
大部分在上面说的第一篇博客中有介绍,这里介绍一下继电器、小风扇、小水泵:
①继电器:
由于单片机的io口无法直接驱动小风扇和水泵,这里用继电器充当开关,使用继电器驱动小风扇和小水泵运动。
输入端口:外接5V电源,黑色跳帽可以控制继电器是高电平触发还是低电平触发。
输出端口:从左往右看,分别是NO1/NO2,COM1/COM2,NC1/NC2,代表常开,公共端,常闭三种状态。
继电器的两种状态,开和关,当继电器触发时,为打开状态,NOn口就会被使能,当继电器为关闭状态时,NCn口就会被使能,中间作为公共端连接输出。
硬件连线:
继电器输出端:小风扇红黑两根线子,红线接入继电器的NO1/NO2口,继电器的COM1/COM2拿一根公母杜邦线引出来接入5V电源,小风扇的黑线接STM32的GND口。
继电器输入端:
原文链接:https://blog.csdn.net/qq_51868810/article/details/127792611
②小风扇、小水泵:
这两个小东西就只有电源线和底线,给5v输入即可转动起来:
二、连接服务器测试
如果想单独先使用esp8266测试是否能正常与服务器通信的话可以参考这篇博客,不会创建产品也可以看:
https://blog.csdn.net/m0_71523511/article/details/135887108
需要注意的点:
①创建产品时要选择MQTT协议那个目录下进行创建
②AT指令中的IP地址和端口号要换成:183.230.40.39 6002
③需要记住的有:产品ID、鉴权信息(创建产品时自己填写的)、Master-APIkey、设备ID
三、两个协议的对比分析
1、代码结构上:
相较于使用http协议连接onenet,使用mqtt协议需要多几个源文件:onenet.c、cJSON.c、MqttKit.c。
①onenet.c是与onenet平台的数据交互接口层,通过调用MqttKit.c和esp8266.c中的库函数实现与云平台的通信,
②MqttKit.c是MQTT协议库,是MQTT协议最底层,由onenet.c进行调用。前面两个都是大神张继瑞开源。
③cJSON.c是一个用于处理JSON数据格式的轻量级C语言库,JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,常用于在不同系统之间传输和存储数据。在对云平台下发数据进行解析时会用到(onenet.c)。
2、获取服务器数据上:
******使用http协议和MQTT协议连接onenet,最大的不同就是获取onenet云平台数据的方式:
http协议:直接构建HTTP请求报文并调用esp8266_send_data函数发送HTTP请求,并获取返回的字符串。
mqtt协议:不主动发送请求,使用ESP8266_WaitRecive函数等待,如果云平台有数据下发,那就存起来当作变量传入OneNet_RevPro函数,进行消息解析。
3、架构上:
"请求/响应"和"发布/订阅"是两种不同的通信模式,它们在系统架构和通信方式上有所不同。
①请求/响应:
特点: 在请求/响应模式中,通信的一方发送请求,而另一方回复响应。通信是单向的,有一个明确的请求者和一个响应者。
用途: 这种模式常见于客户端和服务器之间的通信。客户端发送请求,服务器处理请求并返回相应的响应。
②发布/订阅:
特点: 在发布/订阅模式中,消息的发布者将消息发送到一个主题(topic),而订阅者可以选择订阅特定主题以接收相关消息。通信是多对多的,发布者和订阅者之间是松耦合的。
用途: 这种模式常见于事件驱动系统、消息中间件和实时数据更新场景。发布者发布消息到主题,所有订阅该主题的订阅者都会收到消息。
由以上分析很容易得出一个结论:在做环境信息检测这种实时数据更新的项目上,使用MQTT协议更具优势。
四、下位机主要代码
1、接收并解析云平台下发数据:
主循环中使用以下代码接收并跳转:
dataPtr = ESP8266_GetIPD(10);if(dataPtr != NULL){timeCount = 0;OneNet_RevPro(dataPtr);}
接收到数据后跳转至onenet.c的OneNet_RevPro函数中进行mqtt数据包(报文)解包和数据解析:
void OneNet_RevPro(unsigned char *cmd)
{MQTT_PACKET_STRUCTURE mqttPacket = {NULL, 0, 0, 0}; //协议包char *req_payload = NULL;char *cmdid_topic = NULL;unsigned short req_len = 0;unsigned char type = 0;short result = 0;char *dataPtr = NULL;char numBuf[10];int num = 0;cJSON *json , *json_value;cJSON *json1, *json_value1;cJSON *json2, *json_value2;type = MQTT_UnPacketRecv(cmd);switch(type){case MQTT_PKT_CMD: //命令下发OLED_Refresh_Line("jinru111");result = MQTT_UnPacketCmd(cmd, &cmdid_topic, &req_payload, &req_len); //解出topic和消息体if(result == 0){//打印收到的信息printf( "cmdid: %s, req: %s, req_len: %d\r\n", cmdid_topic, req_payload, req_len);// 对数据包req_payload进行JSON格式解析json = cJSON_Parse(req_payload);if (!json)//如果json内容为空,则打印错误信息printf("Error before: [%s]\n",cJSON_GetErrorPtr());else{json_value = cJSON_GetObjectItem(json , "LED0");//提取对应属性的数值if((json_value->valueint)==1){GPIO_SetBits(GPIOB,GPIO_Pin_12); }else if((json_value->valueint)==0) GPIO_ResetBits(GPIOB,GPIO_Pin_12); }//开关风扇json1 = cJSON_Parse(req_payload);if (!json1)printf("Error before: [%s]\n",cJSON_GetErrorPtr());else{json_value1 = cJSON_GetObjectItem(json1 , "feng");if((json_value1->valueint)==1)GPIO_SetBits(GPIOB,GPIO_Pin_5); else if((json_value1->valueint)==0)GPIO_ResetBits(GPIOB,GPIO_Pin_5); }//开关水泵json2 = cJSON_Parse(req_payload);if (!json2)printf("Error before: [%s]\n",cJSON_GetErrorPtr());else{json_value2 = cJSON_GetObjectItem(json2 , "shui");if((json_value2->valueint)==1){GPIO_SetBits(GPIOB,GPIO_Pin_6); }else if((json_value2->valueint)==0)GPIO_ResetBits(GPIOB,GPIO_Pin_6); }if(MQTT_PacketCmdResp(cmdid_topic, req_payload, &mqttPacket) == 0) //命令回复组包{printf( "Tips: Send CmdResp\r\n");ESP8266_SendData(mqttPacket._data, mqttPacket._len); //回复命令MQTT_DeleteBuffer(&mqttPacket); //删包}cJSON_Delete(json);//释放位于堆中cJSON结构体内存cJSON_Delete(json1);}break;case MQTT_PKT_PUBACK: //发送Publish消息,平台回复的Ackif(MQTT_UnPacketPublishAck(cmd) == 0)//printf( "Tips: MQTT Publish Send OK\r\n");break;default:result = -1;break;}ESP8266_Clear(); //清空缓存if(result == -1)return;dataPtr = strchr(req_payload, ':'); //搜索'}'if(dataPtr != NULL && result != -1) //如果找到了{dataPtr++;while(*dataPtr >= '0' && *dataPtr <= '9') //判断是否是下发的命令控制数据{numBuf[num++] = *dataPtr++;}numBuf[num] = 0;num = atoi((const char *)numBuf); //转为数值形式}if(type == MQTT_PKT_CMD || type == MQTT_PKT_PUBLISH){MQTT_FreeBuffer(cmdid_topic);MQTT_FreeBuffer(req_payload);}
}
2、传感器数据上云:
主函数中读取传感器数值,每隔一段时间上传:
else if(timeCount >= 100) //发送间隔{DHT11_Read_Data(&tempValue,&humidity);gas = AD_GetValue(ADC_Channel_2);ranqi = AD_GetValue(ADC_Channel_3);delay_ms(10);OneNet_SendData();//发送数据给onenetESP8266_Clear(); timeCount = 0;}
调用OneNet_SendData发送数据,在OneNet_SendData函数中又调用OneNet_FillBuf函数将要发送的数据拼接起来。
unsigned char OneNet_FillBuf(char *buf)
{char text[32];//LED0_FLAG=GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_12);//读取LED的开关状态(即对应引脚的)//LED1_FLAG=GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_13);memset(text, 0, sizeof(text));strcpy(buf, ",;");memset(text, 0, sizeof(text));sprintf(text, "Tempreture,%d;",tempValue);strcat(buf, text);memset(text, 0, sizeof(text));sprintf(text, "Humidity,%d;", humidity);strcat(buf, text);memset(text, 0, sizeof(text));sprintf(text, "tianranqi,%d;", gas);strcat(buf, text);memset(text, 0, sizeof(text));sprintf(text, "keranqiti,%d;", ranqi);strcat(buf, text);printf("buf_mqtt=%s\r\n",buf);return strlen(buf);}//==========================================================
// 函数名称: OneNet_SendData
//
// 函数功能: 上传数据到平台
//
// 入口参数: type:发送数据的格式
//
// 返回参数: 无
//
// 说明:
//==========================================================
void OneNet_SendData(void)
{MQTT_PACKET_STRUCTURE mqttPacket = {NULL, 0, 0, 0}; //协议包char buf[128];short body_len = 0, i = 0;//printf( "Tips: OneNet_SendData-MQTT\r\n");memset(buf, 0, sizeof(buf));//清空数组内容body_len = OneNet_FillBuf(buf); //获取当前需要发送的数据流的总长度if(body_len){if(MQTT_PacketSaveData(DEVID, body_len, NULL, 5, &mqttPacket) == 0) 数据点上传组包,将数据封装成mqtt协议所要求的数据包格式{{for(; i < body_len; i++)mqttPacket._data[mqttPacket._len++] = buf[i];ESP8266_SendData(mqttPacket._data, mqttPacket._len); //上传数据到平台printf( "Send %d Bytes\r\n", mqttPacket._len);MQTT_DeleteBuffer(&mqttPacket); //删包}else{printf( "WARN: EDP_NewBuffer Failed\r\n");}}}
五、微信小程序主要代码
图中圈起来的地方需要根据自己的数据进行填写,在下面的调试信息栏可以看到有数据上传,查看数据流即可:
1、index.js
主要是增加了控制风扇和水泵的代码:
feng_kai:function(){//按钮发送命令控制硬件wx.request({url:'https://api.heclouds.com/cmds?device_id=1108129261',header: {'content-type': 'application/json','api-key':'nV4Cso3uQMZR2EGQQiY49MRCfx8='},method: 'POST',data:{"feng":1},success(res){console.log("成功",res.data)},fail(res){console.log("失败",res)}})
},feng_guan:function(){//按钮发送命令控制硬件wx.request({url:'https://api.heclouds.com/cmds?device_id=1108129261',header: {'content-type': 'application/json','api-key':'nV4Cso3uQMZR2EGQQiY49MRCfx8='},method: 'POST',data:{"feng":0},success(res){console.log("成功",res.data)},fail(res){console.log("失败",res)}})
},shui_kai:function(){//按钮发送命令控制硬件wx.request({url:'https://api.heclouds.com/cmds?device_id=1108129261',header: {'content-type': 'application/json','api-key':'nV4Cso3uQMZR2EGQQiY49MRCfx8='},method: 'POST',data:{"shui":1},success(res){console.log("成功",res.data)},fail(res){console.log("失败",res)}})
},shui_guan:function(){//按钮发送命令控制硬件wx.request({url:'https://api.heclouds.com/cmds?device_id=1108129261',header: {'content-type': 'application/json','api-key':'nV4Cso3uQMZR2EGQQiY49MRCfx8='},method: 'POST',data:{"shui":0},success(res){console.log("成功",res.data)},fail(res){console.log("失败",res)}})
},
需要注意的是这里的url需要更换成:‘https://api.heclouds.com/cmds?device_id=11081xxxxxx’,并且文件开头的apikey和设备号也要换成自己的。
2、index.wxml
最后加上:
<button type="primary" style="margin-top: 20px;" bindtap="feng_kai">开风扇</button>
<button type="warn" bindtap="feng_guan">关风扇</button><button type="primary" style="margin-top: 20px;" bindtap="shui_kai">开水泵</button>
<button type="warn" bindtap="shui_guan">关水泵</button>
六、源码获取
我用夸克网盘分享了「智能家居(MQTT+ONENET).rar」,点击链接即可保存。打开「夸克APP」,无需下载在线播放视频,畅享原画5倍速,支持电视投屏。
链接:https://pan.quark.cn/s/db251fd599bd
提取码:9sR9
相关文章:

【智能家居入门2】(MQTT协议、微信小程序、STM32、ONENET云平台)
此篇智能家居入门与前两篇类似,但是是使用MQTT协议接入ONENET云平台,实现微信小程序与下位机的通信,这里相较于使用http协议的那两篇博客,在主程序中添加了独立看门狗防止程序卡死和服务器掉线问题。后续还有使用MQTT协议连接MQTT…...
Java架构师之路九、设计模式:常见的设计模式,如单例模式、工厂模式、策略模式、桥接模式等
目录 常见的设计模式: 单例模式: 工厂模式: 策略模式: 桥接模式: 责任链模式: Java架构师之路八、安全技术:Web安全、网络安全、系统安全、数据安全等-CSDN博客Java架构师之路十、框架和工…...
【OpenAI官方课程】第三课:ChatGPT文本总结Summarizing
欢迎来到ChatGPT 开发人员提示工程课程(ChatGPT Prompt Engineering for Developers)!本课程将教您如何通过OpenAI API有效地利用大型语言模型(LLM)来创建强大的应用程序。 本课程由OpenAI 的Isa Fulford和 DeepLearn…...

跨越千年医学对话:用AI技术解锁中医古籍知识,构建能够精准问答的智能语言模型,成就专业级古籍解读助手(LLAMA)
介绍:首先在 Ziya-LLaMA-13B-V1基线模型的基础上加入中医教材、中医各类网站数据等语料库,训练出一个具有中医知识理解力的预训练语言模型(pre-trained model),之后在此基础上通过海量的中医古籍指令对话数据及通用指令…...

初识表及什么是数据表
一、了解表 1.1.概述 表是处理数据和建立关系型数据库及应用程序的基本单元,是构成数据库的基本元素之一,是数据库中数据组织并储存的单元,所有的数据都能以表格的形式组织,目的是可读性强。 1.2.表结构简述 一个表中包括行和列…...
使用Docker部署DataX3.0+DataX-Web
1、准备基础镜像,开通所需端口 先查看3306和9527端口是否开放,如果未开放先在防火墙添加 firewall-cmd --zonepublic --add-port3306/tcp --permanent firewall-cmd --zonepublic --add-port9527/tcp --permanent firewall-cmd --reload systemctl sto…...

庖丁解牛-二叉树的遍历
庖丁解牛-二叉树的遍历 〇、前言 01 文章内容 一般提到二叉树的遍历,我们是在说 前序遍历、中序遍历、后序遍历和层序遍历 或者说三序遍历层序遍历,毕竟三序和层序的遍历逻辑相差比较大下面讨论三序遍历的递归方法、非递归方法和非递归迭代的统一方法然…...

一文了解LM317T的引脚介绍、参数解读
LM317T是一种线性稳压器件,它具有稳定输出电压的特性。LM317T可以通过调整其输出电阻来确保输出电压的稳定性,因此被广泛应用于各种电子设备中。 LM317T引脚图介绍 LM317T共有3个引脚,分别是: 输入引脚(输入电压V_in&…...

【2024.02.22】定时执行专家 V7.0 发布 - TimingExecutor V7.0 Release - 龙年春节重大更新版本
目录 ▉ 新版本 V7.0 下载地址 ▉ V7.0 新功能 ▼2024-02-21 V7.0 - 更新日志▼ ▉ V7.0 新UI设计 ▉ 新版本 V7.0 下载地址 BoomWorks软件的最新版本-CSDN博客文章浏览阅读10w次,点赞9次,收藏41次。▉定时执行专家—毫秒精度、专业级的定时任务执行…...

☀️将大华摄像头画面接入Unity 【1】配置硬件和初始化摄像头
一、硬件准备 目前的设想是后期采用网口供电的形式把画面传出来,所以这边我除了大华摄像头还准备了POE供电交换机,为了方便索性都用大华的了,然后全都连接电脑主机即可。 二、软件准备 这边初始化摄像头需要用到大华的Configtool软件&#…...

直流电流电压变送器4-20mA 10V信号隔离转换模拟量精度变送器
品牌:泰华仪表 型号:TB-IP(U)XX 产地:中国大陆 省份:安徽省 地市:宿州市 颜色分类:4-20mA转4-20mA,4-20mA转0-10V,4-20mA转0-20mA,4-20mA转0-5V,0-20mA转0-20mA,0-20mA转4-20mA,0-20mA转0-10V,0-20mA转…...

1.1 计算机网络的概念、功能、组成和分类
文章目录 1.1 计算机网络的概念、功能、组成和分类(一)计算机网络的概念(二)计算机网络的功能(三)计算机网络的组成1.组成部分2.工作方式3.功能组成 (四)计算机网络的分类 总结 1.1 …...

排序算法整理
排序种类排序特性代码背景 基于插入的排序直接插入排序原理代码 折半查找排序2路查找排序希尔排序(shell) 缩小增量排序原理代码 基于交换的排序冒泡排序原理代码 快速排序(重要!)原理我的思考 代码 基于选择的排序(简单)选择排序…...

ONLYOFFICE 桌面应用程序 v8.0 发布:全新 RTL 界面、本地主题、Moodle 集成等你期待的功能来了!
目录 📘 前言 📟 一、什么是 ONLYOFFICE 桌面编辑器? 📟 二、ONLYOFFICE 8.0版本新增了那些特别的实用模块? 2.1. 可填写的 PDF 表单 2.2. 双向文本 2.3. 电子表格中的新增功能 单变量求解:…...

c语言---数组(超级详细)
数组 一.数组的概念二. 一维数组的创建和初始化2.1数组的创建2.2数组的初始化错误的初始化 2.3 数组的类型 三. 一维数组的使用3.1数组的下标3.2数组元素的打印3.2数组元素的输入 四. 一维数组在内存中的存储五. 二维数组的创建5.1二维数组的概念5.2如何创建二维数组 六.二维数…...
神经网络权重初始化
诸神缄默不语-个人CSDN博文目录 (如果只想看代码,请直接跳到“方法”一节,开头我介绍我的常用方法,后面介绍具体的各种方案) 神经网络通过多层神经元相互连接构成,而这些连接的强度就是通过权重ÿ…...
代码随想录训练营第三十九天|62.不同路径63. 不同路径 II
62.不同路径 1确定dp数组(dp table)以及下标的含义 从(0,0)出发到(i,j)有 dp[i][j]种路径 2确定递推公式 dp[i][j]dp[i-1][j]dp[i][j-1] 3dp数组如何初始化 for(int i0;i<m…...

学习大数据所需的java基础(5)
文章目录 集合框架Collection接口迭代器迭代器基本使用迭代器底层原理并发修改异常 数据结构栈队列数组链表 List接口底层源码分析 LinkList集合LinkedList底层成员解释说明LinkedList中get方法的源码分析LinkedList中add方法的源码分析 增强for增强for的介绍以及基本使用发2.使…...

Python 光速入门课程
首先说一下,为啥小编在即PHP和Golang之后,为啥又要整Python,那是因为小编最近又拿起了 " 阿里天池 " 的东西,所以小编又不得不捡起来大概五年前学习的Python,本篇文章主要讲的是最基础版本,所以比…...
解决vite打包出现 “default“ is not exported by “node_modules/...问题
项目场景: vue3tsvite项目打包 问题描述 // codemirror 编辑器的相关资源 import Codemirror from codemirror;error during build: RollupError: "default" is not exported by "node_modules/vue/dist/vue.runtime.esm-bundler.js", impor…...

【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...

如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...
Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?
在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...

九天毕昇深度学习平台 | 如何安装库?
pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子: 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...