【嵌入式linux开发】智能家居入门5:老版ONENET,多协议接入(QT、微信小程序、HTTP协议、ONENET云平台、旭日x3派)
智能家居入门5(QT、微信小程序、HTTP协议、ONENET云平台、旭日x3派)
- 前言
- 一、QT界面设计
- 二、云平台产品创建与连接
- 三、下位机端QT代码总览:
- 四、微信小程序端代码总览
- 五、板端测试
前言
前四篇智能家居相关文章都是使用STM32作为主控,本篇使用旭日x3派作为主控,这是一款嵌入式linux开发板,运行linux操作系统。本项目在开发板端运行QT,使用http协议与onenet云平台通信,微信小程序作为移动端,可以接收到下位机上传至服务器的数据,也可以下发指令到服务器,开发板端不断获取指令,进而执行指令。界面设置是在QTcreator中进行,相较于代码设计来说更简单,然后是在电脑虚拟机的ubuntu中进行设计和测试,成功之后直接将项目移植到板端即可,这里是因为开发板能直接运行qt,所以可以直接移植项目,如果板端不能直接运行qt的话,就参考正点原子的交叉编译,最好是使用他官方的开发板。
本文使用的是onenet平台的多协议接入,目前对于新用户已经没有这个功能了,然后老用户之前没创建产品的话,现在也创建不了了,所以本篇文章仅给使用多协议接入的小伙伴参考,新版onenet的接入也已经实现,可以到这篇文章参考。
由于本文的目的主要是在linux下实现双向通信和QT练习,所以没有真的连接温湿度传感器等外设。最终现象如下视频所示:
本文中开发板端称为下位机,微信小程序称为上位机,ONENET云平台称为服务器。
环境:
ubuntu20.04
QT5
旭日x3派
微信开发者工具
一、QT界面设计
虚拟机端的QT5安装,直接网上搜,有很多,一般用命令行安装比较快。
这里直接使用视频的方式来简单展示搭建的过程,主要包括:添加资源文件qrc,添加qss样式表,界面设计等。
视频中用到的qss样式表代码参考如下,都给出了注释很好理解:
①QRadiobutton
QRadioButton::indicator{ //设置点击区域的长和宽width:45px;height:30px;
}
QRadioButton::indicator:unchecked{ //设置未点击时的显示图像image: url(:/images/switch_off.png);
}
QRadioButton::indicator:checked{ //设置点击时的显示图像image: url(:/images/switch_on.png);
}
②QWidget
QWidget#widget { // #特指某个对象,从右上角的类和对象中可以看当前选中的是哪个对象。background-color:rgb(150, 150, 150); //背景颜色background-image: url(:/images/light.png); //背景图片background-repeat: no-repeat; //表示不要应用到子对象上,不设置的话开关里面也会添加一张背景图片background-position: top left; //显示到左上角border-radius: 18px; //边框圆角
}
视频中用到的图像,可以到阿里巴巴矢量图标库中找到,下载png图像即可,然后最好将图像大小重新设置成60*60,不然就有问题:
ps:这里最后设计成自己喜欢的样子就可以了,当然可以不参考我的设计,如果只对通信感兴趣的直接往后看就好了,本文的重点也是在双向通信上。
二、云平台产品创建与连接
1、云平台产品创建
前言中已经提到了多协议接入的问题,这里不再赘述,使用最新物联网组件的小伙伴可以评论区讨论,我看了官方文档的http接入,只看到了数据上传,没有看到获取指令或者数据的部分,是不是新版的onenet中http不支持双向了呢?MQTT协议好像还是和之前差不多的,只是不再是以前的三元组了。
2、云平台连接测试
这部分可以直接参考正点原子的视频,写一个tcp客户端,就可以正常连接云平台了,注意连接的ONENET云平台的IP地址是:183.230.40.33,端口号是:80。
建议直接跟着视频写一下:TCP客户端程序编写,主要是防止后续代码看不懂。
三、下位机端QT代码总览:
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QRadioButton>
#include <QDebug>
#include <QTimer>
//日期时间
#include <QDateTimeEdit>
#include <QTimeEdit>
#include <QDateEdit>
//tcp客户端通过http协议连接云服务器
#include <QTcpSocket>
#include <QJsonObject>
#include <QByteArray>
#include <QJsonDocument>
#include "QHostAddress"
#include <QJsonArray>
#include <QJsonValue>QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();bool deng_flag = 0;int last_mainkongtiaoValue;const char *str[4] = {"POST /devices/1188390993/datapoints HTTP/1.1","api-key:=4T1J3khTpmZO99YYNDHvM5EZiI=","Host:api.heclouds.com",""};QString getbtnRequest = "GET /devices/1188390993/datastreams/ HTTP/1.1\r\napi-key:=4T1J3khTpmZO99YYNDHvM5EZiI=\r\nHost:api.heclouds.com\r\n\r\n" ;private:Ui::MainWindow *ui;QDateTimeEdit *dateTimeEdit;QTimer *timer;QTcpSocket *tcpsocket;private slots:void onRadioButtonToggled(bool checked);//五个radiobuttonvoid onRadioButton2Toggled(bool checked);void onRadioButton3Toggled(bool checked);void onRadioButton4Toggled(bool checked);void onRadioButton5Toggled(bool checked);void updateDateTimeEdit();//刷新日期时间,上传数据至云服务器void receiveMessage();//tcp相关void mStateChange(QAbstractSocket::SocketState);void on_pushButton_clicked();void on_pushButton_2_clicked();};
#endif // MAINWINDOW_H
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);//tcp客户端通过http连接云服务器this->setWindowTitle("智能家居");tcpsocket = new QTcpSocket(this);connect(tcpsocket, SIGNAL(readyRead()), this, SLOT(receiveMessage()));connect(tcpsocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),this, SLOT(mStateChange(QAbstractSocket::SocketState)));connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(on_pushButton_clicked()));connect(ui->pushButton_2,SIGNAL(clicked()),this,SLOT(on_pushButton_2_clicked()));//显示当前的时间和日期dateTimeEdit = new QDateTimeEdit(QDateTime::currentDateTime(),this);dateTimeEdit->setGeometry(50,400, 200, 40);timer = new QTimer(this);connect(timer, &QTimer::timeout, this, &MainWindow::updateDateTimeEdit);timer->start(1000);//下面是按钮对应的信号与槽连接connect(ui->radioButton,SIGNAL(toggled(bool)), this, SLOT(onRadioButtonToggled(bool)));connect(ui->radioButton_2,SIGNAL(toggled(bool)), this, SLOT(onRadioButton2Toggled(bool)));connect(ui->radioButton_3,SIGNAL(toggled(bool)), this, SLOT(onRadioButton3Toggled(bool)));connect(ui->radioButton_4,SIGNAL(toggled(bool)), this, SLOT(onRadioButton4Toggled(bool)));connect(ui->radioButton_5,SIGNAL(toggled(bool)), this, SLOT(onRadioButton5Toggled(bool)));
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::receiveMessage()
{QString response = tcpsocket->readAll();qDebug() << "接收到服务器下发消息" << endl;// 提取 JSON 部分int jsonStartIndex = response.indexOf('{');QString jsonString = response.mid(jsonStartIndex);// 解析 JSONQJsonDocument jsonResponse = QJsonDocument::fromJson(jsonString.toUtf8());QJsonObject jsonObject = jsonResponse.object();QJsonArray dataArray = jsonObject["data"].toArray();for (const QJsonValue &value : dataArray){QJsonObject obj = value.toObject();if (obj["id"].toString() == "led_ctl"){int ledCtlValue = obj["current_value"].toInt();//qDebug() << "LED Control Value:" << ledCtlValue;// 可以在这里处理 ledCtlValue,如更新 UI 显示if(ledCtlValue == 0){ui->textBrowser->append("手机控制关闭客厅灯");ui->radioButton->setText("客厅灯|离线");ui->radioButton->setChecked(0);}else if(ledCtlValue == 1){ui->textBrowser->append("手机控制打开客厅灯");ui->radioButton->setText("客厅灯|在线");ui->radioButton->setChecked(1);}}else if (obj["id"].toString() == "mainroom_kongtiao"){int mainkongtiaoValue = obj["current_value"].toInt();bool ischecked = ui->radioButton_3->isChecked();if((ischecked == 1) && (mainkongtiaoValue ==0)){ui->textBrowser->append("手机控制关闭主卧空调");ui->radioButton_3->setText("空调|离线");ui->radioButton_3->setChecked(0);}else if((ischecked == 0) && (mainkongtiaoValue ==1)){ui->textBrowser->append("手机控制打开主卧空调");ui->radioButton_3->setText("空调|在线");ui->radioButton_3->setChecked(1);}}}
}void MainWindow::mStateChange(QAbstractSocket::SocketState state)
{switch (state) {case QAbstractSocket::UnconnectedState:ui->textBrowser->append("因某种原因与服务端连接断开,尝试重连");qDebug() << "因某种原因与服务端连接断开,尝试重连" << endl;tcpsocket->connectToHost(QHostAddress("183.230.40.33"),80);ui->pushButton->setEnabled(true);ui->pushButton_2->setEnabled(false);break;case QAbstractSocket::ConnectedState:qDebug() << "已连接服务器" << endl;ui->textBrowser->append("已连接服务端");ui->pushButton->setEnabled(false);ui->pushButton_2->setEnabled(true);break;default:break;}
}//开启关闭客厅灯
void MainWindow::onRadioButtonToggled(bool checked)
{if (checked) {ui->radioButton->setText("客厅灯|在线");//deng_flag = 1;qDebug() << "客厅灯打开" << endl;} else {ui->radioButton->setText("客厅灯|离线");//deng_flag = 0;qDebug() << "客厅灯关闭" << endl;}
}//场景选择:居家
void MainWindow::onRadioButton2Toggled(bool checked)
{if (checked) {qDebug() << "居家模式已打开" << endl;} else {qDebug() << "居家模式已关闭" << endl;}
}//开启关闭主卧空调
void MainWindow::onRadioButton3Toggled(bool checked)
{if (checked) {ui->radioButton_3->setText("空调|在线");qDebug() << "主卧空调打开" << endl;} else {ui->radioButton_3->setText("空调|离线");qDebug() << "主卧空调关闭" << endl;}
}//场景选择:暂时出门
void MainWindow::onRadioButton4Toggled(bool checked)
{if (checked) {//ui->radioButton_3->setForegroundRole();qDebug() << "暂时出门模式已打开" << endl;} else {//ui->radioButton_3->setText("空调|离线");qDebug() << "暂时出门模式已关闭" << endl;}
}//场景选择:出远门
void MainWindow::onRadioButton5Toggled(bool checked)
{if (checked) {qDebug() << "出远门模式已打开" << endl;} else {qDebug() << "出远门模式已关闭" << endl;}
}void MainWindow::on_pushButton_clicked()
{tcpsocket->connectToHost(QHostAddress("183.230.40.33"),80);
}void MainWindow::on_pushButton_2_clicked()
{tcpsocket->disconnectFromHost();
}//定时器刷新时间、上传数据至服务器、刷新本地显示数据
void MainWindow::updateDateTimeEdit() {static int flag = 0;dateTimeEdit->setDateTime(QDateTime::currentDateTime());//请求设备数据,这里会读回来所有的数据,比如温适度和数据流模板QByteArray getbtnRequestBytes = getbtnRequest.toUtf8();if(tcpsocket->state() == QAbstractSocket::ConnectedState) {tcpsocket->write(getbtnRequestBytes);//qDebug() << "请求已发送" << endl;;} else {ui->textBrowser->append("请先连接服务端");//qDebug() << "请先连接服务器" << endl;;}if(flag == 10){ui->label_6->setText("14度");ui->label_8->setText("70");ui->label_10->setText("9.7 ppm");QJsonObject postData;postData["temp"] = 14;postData["humi"] = 70;QJsonDocument jsonDoc(postData);QByteArray jsonData = jsonDoc.toJson(QJsonDocument::Compact);// 计算请求体的长度int contentLength = jsonData.size();// 构建HTTP请求QString httpRequestString ="POST /devices/1188390993/datapoints?type=3 HTTP/1.1\r\n""api-key:=4T1J3khTpmZO99YYNDHvM5EZiI=\r\n" // 请注意api-key的值需要是您的实际API密钥"Host: api.heclouds.com\r\n""Content-Length: " + QString::number(contentLength) + "\r\n" // 设置正确的内容长度"\r\n" // 请求头和请求体之间的空行+ QString(jsonData) // 添加JSON请求体;QByteArray httpRequest(httpRequestString.toUtf8());if(tcpsocket->state() == QAbstractSocket::ConnectedState) {tcpsocket->write(httpRequest);qDebug() << "请求已发送" << endl;} else {ui->textBrowser->append("请先连接服务端");//qDebug() << "请先连接服务器" << endl;;}flag = 0;}flag++;
}
只要简单学过QT,上述的代码都能看懂,并不是直接复制就能用,如果自己画的ui界面和我的不一样,那就要改代码,有兴趣的可以私聊拿原项目。
四、微信小程序端代码总览
有用的目录格式如下:
各部分的代码如下,注意只测试了温度和湿度,其他的想加很简单(微信小程序直接使用的b站up的代码:彼岸有光我们有船):
index.js:
Page({data: {temp:0},// 事件处理函数getinfo(){var that = thiswx.request({url: "https://api.heclouds.com/devices/1188390993/datapoints", //将请求行中的数字换成自己的设备IDheader: {"api-key": "=4T1J3khTpmZO99YYNDHvM5EZiI="},method: "GET",success: function (e) {console.log("获取成功",e)that.setData({temp:e.data.data.datastreams[0].datapoints[0].value,humi:e.data.data.datastreams[2].datapoints[0].value,})console.log("temp==",that.data.temp),console.log("humi==",that.data.humi)}});},kai:function(){let data={"datastreams": [ {"id": "led_ctl","datapoints":[{"value": 1}]},//led是数据流的名称,value是要传上去的数值] }//按钮发送命令控制硬件wx.request({url:'https://api.heclouds.com/devices/1188390993/datapoints',header: {'content-type': 'application/json','api-key':'=4T1J3khTpmZO99YYNDHvM5EZiI='},method: 'POST',data: JSON.stringify(data),//data数据转换成JSON格式success(res){console.log("成功",res.data)},fail(res){console.log("失败",res)}})
},guan:function(){let data={"datastreams": [ {"id": "led_ctl","datapoints":[{"value": 0}]},//led是数据流的名称,value是要传上去的数值] }//按钮发送命令控制硬件wx.request({url:'https://api.heclouds.com/devices/1188390993/datapoints',header: {'content-type': 'application/json','api-key':'=4T1J3khTpmZO99YYNDHvM5EZiI='},method: 'POST',data: JSON.stringify(data),//data数据转换成JSON格式success(res){console.log("成功",res.data)},fail(res){console.log("失败",res)}})
},kaikong:function(){let data={"datastreams": [ {"id": "mainroom_kongtiao","datapoints":[{"value": 1}]},//led是数据流的名称,value是要传上去的数值] }//按钮发送命令控制硬件wx.request({url:'https://api.heclouds.com/devices/1188390993/datapoints',header: {'content-type': 'application/json','api-key':'=4T1J3khTpmZO99YYNDHvM5EZiI='},method: 'POST',data: JSON.stringify(data),//data数据转换成JSON格式success(res){console.log("成功",res.data)},fail(res){console.log("失败",res)}})
},guankong:function(){let data={"datastreams": [ {"id": "mainroom_kongtiao","datapoints":[{"value": 0}]},//led是数据流的名称,value是要传上去的数值] }//按钮发送命令控制硬件wx.request({url:'https://api.heclouds.com/devices/1188390993/datapoints',header: {'content-type': 'application/json','api-key':'=4T1J3khTpmZO99YYNDHvM5EZiI='},method: 'POST',data: JSON.stringify(data),//data数据转换成JSON格式success(res){console.log("成功",res.data)},fail(res){console.log("失败",res)}})
},onLoad() {var that = thissetInterval(function(){that.getinfo()},5000)}})
index.wxml:
<view class="userinfo"><image class="img" src="../images/温度 .png"></image><text>温度:{{temp}}℃</text>
</view><view class="userinfo"><image class="img" src="../images/湿度.png"></image><text>湿度:{{humi}}%</text>
</view><view class="userinfo"><image class="img" src="../images/甲烷.png"></image><text>天然气:{{gas_ch4}}PPM</text>
</view><view class="userinfo"><image class="img" src="../images/可燃气体.png"></image><text>可燃气体:{{ranqi}}PPM</text>
</view><button type="primary" style="margin-top: 20px;" bindtap="kai">开灯</button>
<button type="warn" bindtap="guan">关灯</button><button type="primary" style="margin-top: 20px;" bindtap="kaikong">开主卧空调</button>
<button type="warn" bindtap="guankong">关主卧空调</button>
index.wxss:
/**index.wxss**/
.userinfo {display: flex;flex-direction: column;align-items: center;color: rgb(141, 10, 10);font-size: 15px;
}.img {width: 100rpx;height: 100rpx;
}.usermotto {margin-top: 200px;
}
index.json:
{"usingComponents": {}
}
也是非常简单,比起qt还要更简单,简单看看就能看懂。愉快的测试即可。
五、板端测试
虚拟机端代码跑通之后其实就可以到板子上跑了。直接远程登录开发板,然后安装QT5:
sudo apt-get install qt5-default qt5-qmake qtcreator
随后将项目拷贝至任意目录下,打开qtcreator,然后打开项目,即可运行。
相关文章:

【嵌入式linux开发】智能家居入门5:老版ONENET,多协议接入(QT、微信小程序、HTTP协议、ONENET云平台、旭日x3派)
智能家居入门5(QT、微信小程序、HTTP协议、ONENET云平台、旭日x3派) 前言一、QT界面设计二、云平台产品创建与连接三、下位机端QT代码总览:四、微信小程序端代码总览五、板端测试 前言 前四篇智能家居相关文章都是使用STM32作为主控…...

软考-软件设计师(程序设计语言习题)
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 非常期待和您一起在这个小…...

「C++系列」vector 容器
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站:人工智能教程 文章目录 一、vector 容器1. 基本特性2. 基本操作3. 注意事项 二、应用场景1. 应用场景2. 案例案例一࿱…...
梯度的概念
梯度 机器学习中,梯度下降法,牛顿法都会用到梯度概念 对于一元函数,梯度可以看成导数 对于多元函数,梯度可以看成偏导数 如果多元函数包含N个自变量: x 1 , x 2 , . . . , x n x_1, x_2, ..., x_n x1,x2,...,x…...
低代码开发:机遇与挑战并存的技术革新
近年来,随着数字化转型的加速,低代码开发平台如雨后春笋般涌现,承诺让非专业人士也能快速构建应用程序。这种新兴技术正在挑战传统软件开发模式,引发了IT行业的广泛讨论。低代码平台是提高效率的利器,还是降低了编程门…...

Linux之RabbitMQ集群部署
RabbitMQ 消息中间件 1、消息中间件 消息(message): 指在服务之间传送的数据。可以是简单的文本消息,也可以是包含复杂的嵌入对象的消息 消息队列(message queue): 指用来存放消息的队列,一般采用先进先出的队列方式,即最先进入的…...

【JAVA CORE_API】Day19 多线程API(2)、多线程并发安全问题、同步
多线程API 进程和线程 进程:进程就像是一个程序在电脑里运行时的一个实例。你可以把它想象成一个独立的小工人,专门负责完成某项任务(比如打开浏览器、播放音乐)。每个进程都有自己独立的资源(比如内存)和…...

最新Windows 11 23H2精简版,免费获取!稳定流畅!
今日,系统之家小编给大家带来了2024最新的Windows11 23H2精简版系统,该版本系统经过适度地优化与精简,保留大部分功能,完全能满足日常使用需求,兼容性非常出色,无需担心应用程序出现闪退问题。大家可以通过…...
PostgreSQL SELECT 语句:深入解析与实例应用
PostgreSQL SELECT 语句:深入解析与实例应用 PostgreSQL 是一款功能强大的开源关系数据库管理系统,它以稳定性、可靠性以及支持高级功能而著称。在 PostgreSQL 中,SELECT 语句是最基本也是最重要的查询语句之一,用于从数据库表中检索数据。本文将详细介绍 SELECT 语句的用…...

【自然语言处理】 构建文本对话系统
构建文本对话系统的框架如下: 根据聊天系统目的功用的不同,可分成三大类型: 闲聊式机器人:较有代表性的有微软小冰、微软小娜、苹果的 Siri、小 i 机器人等,主要以娱乐为目的。 **知识问答型机器人:**知识…...
java: 程序包org.slf4j不存在
当在Java项目中遇到“程序包org.slf4j不存在”的错误时,这通常意味着你的项目没有正确地包含SLF4J(Simple Logging Facade for Java)的库。SLF4J是一个Java的日志门面(Facade),它允许你在后端使用不同的日志…...

图片转PDF怎么转?教你3种快捷方便的jpg转pdf方法
图片文件以及PDF文档已经是我们工作当中不可或缺的一部分,我们在一些商务合作的场景下经常需要把拍摄下来的合同、企划书、画册等图片内容转换为PDF格式后再发送,这样能够极大程度的保证文件的安全性,那么图片应该如何转换成PDF文件呢?今天来…...

数据防泄密软件如何防止数据泄密?七大措施筑起数据安全壁垒
数据防泄密软件通过集成多种安全防护技术,旨在全面保护企业数据的安全性和保密性。以安企神软件为例,其实现全面防泄密的方式主要包括以下7个方面,为企业筑起数据安全壁垒。 1. 透明加密技术 安企神软件采用先进的透明加密技术,确…...

GNU/Linux - systemd介绍
systemd官网: System and Service Manager systemd systemd Github地址: https://github.com/systemd/systemd 首次发布 2010年3月30日 System and Service Manager systemd 是一套 Linux 系统的基本构件。它提供了一个系统和服务管理器,作为…...

如何理解递归
在二叉树的题目中,我们难免会用到递归方法,递归思想很简单,但运用起来却因为抽象而难以理解。 理解递归的关键在于认识到它是一种解决问题的方法,允许函数直接或间接地调用自身。以下是对递归的概述以及如何理解它的几个要点&…...
Spring Cache sync属性
在Spring Cache中,Cacheable注解用于标记一个方法,使其返回值可以被缓存。sync属性是Spring 4.3引入的一个新特性,用于控制缓存的同步行为。 sync 属性 sync属性的默认值是false,表示异步缓存。如果将sync设置为true,…...

【Unity】通用GM QA工具 运行时数值修改 命令行 测试工具
GM工具使用: GM工具通常用于游戏运行时修改数值(加钱/血量)、解锁关卡等,用于快速无死角测试游戏。一个通用型GM工具对于游戏项目是非常实用且必要的,但通用不能向易用妥协,纯命令行GM门槛太高,对QA不友好。 这类运行时命令行工具…...

[Spring] Spring原理(SpringBoot完结)
🌸个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 🏵️热门专栏: 🧊 Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 🍕 Collection与…...
python | rq,一个无敌的 关于Redis 的Python 库!
本文来源公众号“python”,仅用于学术分享,侵权删,干货满满。 原文链接:rq,一个无敌的 Python 库! 大家好,今天为大家分享一个无敌的 Python 库 - rq。 Github地址:https://githu…...

Redis的缓存淘汰策略
1. 查看Redis 最大的占用内存 打开redis配置文件, 设置maxmemory参数,maxmemory 是bytes字节类型, 注意转换 2. Redis默认内存多少可以用 注意: 在64bit系统下, maxmemory 设置为 0 表示不限制Redis内存使用 3. 一般生产上如何配置 一般推荐Redis 设置内…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

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

什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...