物联网实战--平台篇之(二)基础搭建

目录

一、Qt工程创建

二、数据库知识

三、通信协议

四、名词定义


本项目的交流QQ群:701889554

物联网实战--入门篇https://blog.csdn.net/ypp240124016/category_12609773.html

物联网实战--驱动篇https://blog.csdn.net/ypp240124016/category_12631333.html

一、Qt工程创建

        Qt方面有三个工程需要创建,分别是应用服务器程序、数据服务器程序和客户端APP,他们各自的作用在上一篇已经说过了,这一篇主要创建工程的基础结构,主要是MQTT通讯和数据库相关等基础文件。对于应用服务器和数据服务器程序是不需要界面的,用控制台程序即可,所以它们的.pro文件都有一个:

QT -= gui

        对于MQTT之前已经有大概讲解过了,可以去参考之前的文章,我们这里主要还是对开源库进行封装,把域名解析、话题订阅、证书添加等内容进行内部处理。在这里我们主要介绍下数据库相关的内容。

物联网实战--入门篇之(七)嵌入式-MQTT_mqtt嵌入式-CSDN博客

项目工程集合 https://download.csdn.net/download/ypp240124016/89248704

二、数据库知识

        QT对各类数据库进行封装,可以驱动很多类型的数据,包括ODBC、SQLite、MySQL、PostgreSQL、SQL Server、Oracle等,不同类型的数据库驱动类型略有区别,一般数据库都需要另外安装软件,比如MySQL,可以参考这篇文章Mysql的安装配置教程(非常详细)从零基础入门到精通,看完这一篇就够了_mysql安装教程-CSDN博客

        对于没接触过数据库的同学会觉得比较麻烦,所以我们这个项目为了方便,直接使用SQLite作为数据库了,它无需额外安装软件,生成的数据库是独立文件,就像普通配置文件一样。数据库的操作,核心就是增删改查,利用数据库语句进行操作,这里可以大概看下教程SQLite 教程 | 菜鸟教程

        以下是数据库驱动SQLite的封装文件和代码:

#include "BaseSqlite.h"BaseSqlite::BaseSqlite(QObject *parent) : QObject(parent)
{
}BaseSqlite::~BaseSqlite()
{
//    closeDataBase();
}void BaseSqlite::closeDataBase(void)
{
//    qDebug()<<m_dbName<<" ## "<<m_connName<<"closeDataBase";
//    QSqlDatabase::removeDatabase(m_connName);m_sqlDataBase.close();
}//打开数据库
bool BaseSqlite::openDataBase(QString db_name, QString conn_name)
{if(m_sqlDataBase.isOpen()){qDebug()<<m_dbName<<" "<<m_connName<< " is opened.";return false;}m_dbName=db_name;m_connName=conn_name;if(QSqlDatabase::contains(m_connName))m_sqlDataBase = QSqlDatabase::database(m_connName);elsem_sqlDataBase = QSqlDatabase::addDatabase("QSQLITE", m_connName);//    m_sqlDataBase = QSqlDatabase::addDatabase("QSQLITE", conn_name);m_sqlDataBase.setDatabaseName(db_name);if(!m_sqlDataBase.open()){qDebug()<<m_dbName<<" "<<m_connName<< "Error: Failed to connect database." << m_sqlDataBase.lastError();return false;}else{m_sqlQuery = QSqlQuery(m_sqlDataBase);
//        qDebug()<<m_dbName<<" "<<m_connName<< "Succeed to open database." ;}return true;
}bool BaseSqlite::isOpened(void)
{return m_sqlDataBase.isOpen();
}//执行语句
bool BaseSqlite::runSqlQuery(QString str_query)
{
//    QSqlQuery query(m_sqlDataBase);if(!m_sqlQuery.exec(str_query)){qDebug()<<m_sqlQuery.lastError();}else{return true;}return false;
}//启动事务
bool BaseSqlite::beginTransaction(void)
{QString str_query = "BEGIN TRANSACTION";if(runSqlQuery(str_query)==false){return false;}return true;
}//停止事务
bool BaseSqlite::endTransaction(void)
{QString str_query = "COMMIT";if(runSqlQuery(str_query)==false){return false;}return true;
}

        看起来也很简单,主要就是打开、关闭数据库,执行数据库语句;另外还有启动和停止事务,主要是用于数据流比较大的场景,比如数据服务器的数据保存,用数据库的事务功能可以避免频繁打开、关闭数据库,浪费时间,可以累积数据或者定时写入数据,提高效率。

三、通信协议

        这里的通讯协议指的是应用层的协议,理论上各个公司都是自定义的,没有标准。在这里,我们从实际需求出发,也自定义了一种协议,具体如下:

        协议看着比较复杂,分成两部分来看,一个是整体定义,一个是数据包内容。首先协议采用二进制传输,整体上包含帧头,便于检索,校验码、数据长度该有的也都有了;1~16字节内容都是明文,都有相应解释,其中app_id和dev_sn稍后详细说明;17~N的数据区需要加密,我们整个系统采用一型多密的方案,即一种型号配套多组密码,根据自己需要使用,密码在设备生产定义时确定,需要注意保护,协议中的索引就是密码索引,这样可以明确数据包内用了哪一组的密码。

        协议的核心还是数据区里的内容,这里使用的是一种嵌套的思想,因为在实际项目中我们经常会用到无线组网的方式,一个网关加多个节点,对于节点数据是需要通过网关转发的,那就相当于把节点数据嵌套在网关数据内部,这时候网关的顶层命令固定为100,意思就是本次数据包是转发的节点数据,要根据数据包的内容进一步解析;下行的时候也是一样,节点的控制指令需要经过网关进行转发,转发命令固定为200,网关解析后会把数据提取出来,至于怎么转发是网关跟节点之间的事了,后面在做LoRa组网的时候会具体演示。

        理论上可以一直嵌套下去,不过一般就一层,网关+节点,节点后面再挂载节点的情况比较少见了。

        对于不同的设备会包含不同的命令类型,需要从设备的实际需求出发,一般来讲,针对每一种类型的设备或者新产品,都要有规范的协议文档,这样在开发和维护过程中比较清晰,出现问题容易定位。

        协议内容都是字节序的形式传输,避免大小端的问题,我们约定数据高位先传输,比如协议里的app_id是四个字节,以AABB1122为例,那传输顺序就是AA、BB、11、22;对于数据的定义可以参考之前的净化器数值,简单讲就是我们只传输正整数,产品定义的时候就要把某个数据的范围和精度确定好,这样就可以把这个数据转为正整数了,然后传输依然是高位在前,低位在后的原则。这样,整个协议的统一性就很高了,对于具体的代码在后续合适的章节会体现,不会很复杂。

四、名词定义

        整个体系会有一些专有名词,这里统一做一下解释。

        账户:这个不用过多解释了,就像微信号一样,在整个系统里是唯一的,一般采用字符和数字的形式,我们这个系统以手机号为核心,注册的时候需要跟手机绑定,用验证码的方式注册,属于比较常规的。

        子账户:有时候手机号就一个,账户又想要多个,那么就可以用主账户去新建子账户,子账户的使用上跟主账户类似,但是子账户不能再创建子账户了。

        应用ID:就是协议里的app_id,长度是4个字节,每个账户下可以创建多个应用,每个应用下包含多个设备,举例说明,一般来讲,智能家居中一套房子创建一个应用,这个应用下有空调、冰箱、净化器等设备,这时候假设你有多套房子,每套房子都要整一套智能家居产品,显然,如果把所有设备都放在一个应用下就不太好管理了,这时候就可以为每套房子新建一个应用,各自的设备放在对应的应用下,彼此就很好管理了,这就是应用ID存在的意义。从技术角度来讲,设备发布消息的话题形式是这样的dev/pub/data/123001,其中123001就是应用ID,这样对于用户端APP来讲,只要根据app_id来订阅,该应用下的设备数据就会发到正确的用户端。所以说,app_id在整个系统的管理上起到了一个很关键的作用。

        设备序列号:就是协议里的dev_sn,是设备的身份标识,长度是4个字节,对于dev_sn是需要规范的,不能随便定义,在这里我们定义,高2字节代表设备类型,低2字节代表地址码,例如16进制A3010001,其中A301代表设备类型,比如四路主机,这个在产品定义时就要确定,那么0001就是地址码,这是在生产时确定的,于是四路主机所有的序列号就是A3010001~A301FFFF,理论上可以生产6万多个。实际上,再加上app_id的区分,其实不要在同一个应用里使用相同的dev_sn就行了,这样一来,在实际项目中都是够用的了。我们的密码体系是一型多密原则,这里的型就是指dev_sn的高2字节,理论上可以创建6万多种型号,够用了。总体来讲,app_id和dev_sn是我们整个系统设计的核心,一切都是围绕这两个概念展开的。

        解析插件:每一种型号的设备对应一个解析插件,主要就是负责对设备数据进行解析和操作,后期的产品开发主要就是设备端和对应解析插件的开发,这也是端到端开发模式的由来。解析插件主要是对用户端APP的不断扩充,包含两个内容,一个是后端C++对数据进行解析,一个是前端QML做该型号设备的展示界面,就像入门篇里所展示的净化器界面一样。这样,平台端无需增加开发,一个简单的物联网开发模式就形成了。

        网关/主机:这一类设备是直接跟服务器连接的,它们一般带有网口、WIFI或者4G等互联网接口,设备端的加密/解密也是在这类设备中完成的;它们有时候是独立的个体,比如WiFi空调,有时候是作为其它设备的数据中转站,比如LoRa网关,主要作用就是对LoRa节点设备的数据进行转发。

        节点:与上面所述的网关配合使用,节点的特点一般是数量较多,每个都有联网功能的话成本较高,所以选择用网关作为统一的联网媒介,比如485温湿度、LoRa门磁等等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/5493.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何使用ChatGPT进行高效的中文到科学英文翻译?

如何使用ChatGPT进行高效的中文到科学英文翻译 在全球化加速的今天&#xff0c;科学交流往往需要跨越语言障碍。特别是在科研领域&#xff0c;有效地将中文研究成果转化为精准的科学英语描述&#xff0c;对于学术发表和国际合作尤为关键。AI翻译工具如ChatGPT可以在这一过程中…

ubuntu入门

基础命令 cd 切换命令 ls 查看当前目录下所有的文件 cp a.c b.c 拷贝a.c 到 b.c touch a.c 创建a.c文件 mkdir file 创建文件夹file rm file 删除文件 rmdir 删除test文件夹 rmdir test/ mv 移动文件 mv a.c b.c 把a.c 替换成b.c ifconfig 查看电脑网络信息 rm xx 删…

虹科Pico汽车示波器 | 免拆诊断案例 | 起动机免拆诊断故障 2 例

电磁开关、换向器烧蚀及炭刷磨损均会导致起动机偶尔不工作&#xff0c;使发动机偶尔无法起动。由于故障是偶发的&#xff0c;且没有故障代码&#xff0c;这往往会让维修人员无从下手&#xff0c;而用Pico示波器测量起动电流&#xff0c;就会让这些“亚健康状态”一目了然。 案例…

MongoDB磁盘空间占满,导致数据库被锁定,如何清理数据和磁盘空间

一、问题 1、我在实际项目中&#xff0c;遇到一个问题&#xff0c;随着数据每天的不断增加&#xff0c;导致mongodb的磁盘空间站满了&#xff0c;数据库被锁了&#xff0c;无法使用。 2、故障表现 部署的应用程序突然无法将数据写入数据库&#xff0c;但是可以正常读取数据。…

与 Apollo 共创生态:观看7周年大会的心路历程

前言 在科技飞速发展的今天&#xff0c;自动驾驶技术已然成为行业创新的热点之一。作为一名长期关注自动驾驶领域的技术人员&#xff0c;我有幸见证了Apollo平台的成长与壮大。七年前&#xff0c;Apollo的诞生为我们带来了无尽的想象与期待&#xff1b;七年后的今天&#xff0…

1天搞定uniApp+Vue3+vite+Element UI或者Element Plus开发学习,使用vite构建管理项目,HBuilderX做为开发者工具

我们通常给小程序或者app开发后台时&#xff0c;不可避免的要用到可视化的数据管理后台&#xff0c;而vue和Element是我们目前比较主流的开发管理后台的主流搭配。所以今天石头哥就带大家来一起学习下vue3和Element plus的开发。 准备工作 1&#xff0c;下载HBuilderX 开发者…

STL——stackqueue

stack stack即为栈&#xff0c;先进后出是其特点 栈只有栈顶元素能被外界使用&#xff0c;故不存在遍历行为 栈中常用接口 构造函数 stack<T> stk; //默认构造方式 stack(const stack &stk); //拷贝构造 赋值操作 stack& operator(const stack &stk); …

Linux服务器安全基础 - 查看入侵痕迹

1. 常见系统日志 /var/log/cron 记录了系统定时任务相关的日志 /var/log/dmesg 记录了系统在开机时内核自检的信息&#xff0c;也可以使用dmesg命令直接查看内核自检信息 /var/log/secure:记录登录系统存取数据的文件;例如:pop3,ssh,telnet,ftp等都会记录在此. /var/log/btmp:记…

Flask教程1:flask框架基础入门,路由、模板、装饰器

文章目录 一、 简介二、 概要 一、 简介 Flask是一个非常小的Python Web框架&#xff0c;被称为微型框架&#xff1b;只提供了一个稳健的核心&#xff0c;其他功能全部是通过扩展实现的&#xff1b;意思就是我们可以根据项目的需要量身定制&#xff0c;也意味着我们需要学习各…

(7)快速调优

文章目录 前言 1 安装脚本 2 运行 QuikTune 3 高级配置 前言 VTOL QuikTune Lua 脚本简化了为多旋翼飞行器的姿态控制参数寻找最佳调整的过程。 脚本会缓慢增加相关增益&#xff0c;直到检测到振荡。然后&#xff0c;它将增益降低 60%&#xff0c;并进入下一个增益。所有增…

VScode 无法连接云服务器

试了很多方法&#xff0c;比如更换VScode版本&#xff0c;卸载重装&#xff0c;删除配置文件 重启电脑&#xff0c;都无法成功。最后重置电脑后才连接上&#xff0c;但是重启服务器后又出现该问题。 方法一&#xff1a;修改环境 方法二&#xff1a;把vscode卸载干净重下

JVM支持的可配置参数查看和分类

JVM参数大致可以分为三类: 标注指令:-开头。 这些是所有的HotSpot都支持的参数。可以用java-help 打印出来。 非标准指令: -X开头。 这些指令通常是跟特定的HotSpot版本对应的。可以用java -X打印出来。 不稳定参数: -XX 开头。 这一类参数是跟特定HotSpot版本对应的&#x…

Java Maven 编译资源文件拷贝错误 dirCompressed.zip failed with MalformedInputException:

完整的错误信息为&#xff1a; [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.3.1:resources (default-resources) on project core-java-io: filtering C:\WorkDir\Repository\iSharkfly-Docs\java-tutorials\core-java-modules\core-ja…

VitePress 构建的博客如何部署到 Netlify 平台?

VitePress 构建的博客如何部署到 Netlify 平台&#xff1f; 前言 之前写了篇文章【使用 Vitepress 构建博客并部署到 github 平台】&#xff0c;有个老哥说 github page 访问太慢了&#xff0c;希望放到 Netlify 平台上面。 咱也没部署过&#xff0c;就试了一下&#xff0c;发…

【计算智能】基本遗传算法在优化问题中的应用与实验【理论到程序】

文章目录 1. 引言&#xff1a;遗传算法简介2. 基本遗传算法&#xff08;SGA&#xff09;2.1 基本遗传算法的构成要素1. 染色体编码2. 适应度函数3. 遗传算子 2.2 实验设计与方法1. 算法流程2. 伪代码3. python实现1. 导入模块2. 目标函数 f(x)3 初始化种群4. 计算适应度5. 选择…

再谈有效地访问Github

文章目录 1. 知识回顾2. 问题描述3. 问题解决3.1 Mac系统3.2 Windows系统4. 内容总结1. 知识回顾 我们在之前的内容中介绍过如何有效地访问Github。如果大家忘记的话可以点击这里查看。之前的内容主要偏重于问题的分析和解决的思路,有些朋友看了后还是不清楚如何解决问题。 …

设计模式之工厂模式FactoryPattern(二)

一、简单工厂 package com.xu.demo.factoryPattern;/*** 简单工厂模式类*/ public class SimpleFactoryPattern {public static Phone create(String name) {//根据输入对象名称判断返回相匹配的对象if("IPhone".equals(name)) {//返回对象return new IPhone();}else…

【补充】图神经网络前传——图论

本文作为对图神经网络的补充。主要内容是看书。 仅包含Introduction to Graph Theory前五章以及其他相关书籍的相关内容&#xff08;如果后续在实践中发现前五章不够&#xff0c;会补上剩余内容&#xff09; 引入 什么是图&#xff1f; 如上图所示的路线图和电路图都可以使用…

国家开放大学2024年春《Matlab语言及其应用》实验一熟悉Matlab 操作环境参考答案

实验报告 姓名&#xff1a; 学号&#xff1a; 实验一名称&#xff1a;熟悉 Matlab 操作环境 实验目标&#xff1a;通过简单变量和矩阵的录入、计算和查看相关信息&#xff0c;了解 Matlab 操作界面 及各子窗口使用方法。熟悉一系列便于使用的 Matlab 函数和文件的工具。 实…

复旦 北大 | 从头训练中文大模型:CT-LLM

引言 当前&#xff0c;绝大多数大模型&#xff08;LLMs&#xff09;基本上都是以英文语料库训练得到的&#xff0c;然后经过SFT来匹配不同的语种。然而&#xff0c;今天给大家分享的这篇文章旨在从头开始训练中文大模型&#xff0c;在训练过程中「主要纳入中文文本数据」&…