关于物联网个人技术汇总

最近公司让我在做对一套物联网系统的技术调研,对这套物联网系统的熟悉,以及我们公司即将要做的的一些定制化开发和需求是否满足。

先来系统介绍一下关于物联网解决的问题,以及什么形势下或者什么场景下诞生了这种广泛应用的系统:

随着中国制造2025、美国先进制造伙伴计划、德国工业4.0等等,

一些国家战略的提出和实施,工业物联网应运而生,实际上就是为了解决工业体系智能化的推手,它完全应用在了各个环节,设计、生产、管理、服务全生命周期,

而且工业基本是传统产业,物联网系统在这个基础上,在面向工业领域的企业服务中获取价值,实现产业升级,提供信息化服务,是工业领域软件化的必经之路。

平台为设备提供安全可靠的连接通信能力,向下通过边缘端软件对接海量工业设备,支撑工业设备数据采集与工业网关的远程控制;向上能够与数据中台和多种应用系统对接,实现数据的多维度应用,打造更丰富的应用场景。

在物联网的架构中,PLC、智能仪表、智能设备、上位机等工业设备位于最底层。

技术调研:

当前物联网设备对接支持很多方式,但目前我接触到的就两种

HTTP:其实在这种方式下,完全就是端对端的调用,设备上调试好对接地址,以及协议地址,直接就往接口里面塞数据,这种就体现一个问题,我多个设备中属性不一致怎么办,我每次都要单独写一个接口单独对接这个设备,每次新增设备我都要增加一套增删改查

MQTT:这种方式下其实虽然也是端对端的调用,但是可以理解为一端对多端,我只提供一套进入方式,你只需要告诉我ip:host,以及clientId,账号密码,就能从MQTT协议下,指定我的clientID找我想要的设备去写入数据,我认为这个东西就是一个低代码的前身,这个完全就是一个思维的转变,我不再需要去库中每次新增设备都维护一个表,我可以提前维护好一套属性模型,我在我的设备中引用这个属性模型,我不再需要每次新写一套增删改查

数据处理服务:

很显然,处理服务就是处理接收到的数据的地方。"处理"是一个抽象的词语,例如保存数据,以及转换数据以使其看上去更易懂,还有从多台传感器的数据中发现新的数据,这些都是处理。使用者的目的不同,处理服务器的内容也各异 拿一个市面上在流行的平台举例,它的每个模型属性下有自己的事件

持久化:就是我当前这个数据事件到底要不要入库(时序数据库)

数仓 :为什么有数仓这个概念,数仓其实没什么特别的,数仓可以是任何东西,只要能存数据,只要能存满足我要求的数据,你拿个记事本也能叫数仓,前提是你放的进去,取得出来,回到为什么有数仓,因为设备数据量太大了,一般设备八秒就要传输一次数据,我每次传输都要存到我的数据库里吗,如果八秒一条数据,假设我有八个设备一天就要86400条,你存是是存上去了,半年以后你怎么取,你跟我说加索引,首先加索引,你是查的快了,你插数据可就慢了,每次都要重建索引树,开销很大,所以物联网系统一定会用到一个数据库就是时序数据库,这个时序数据库的原理放到下面,所有数据没有直接往关系型数据库放的,开销无敌大,都要往时序数据库放,数仓的作用是什么,作用就是每次进来数据,我只要我想要的数据,我加一步筛选,不合法不合规的数据我拿出来,放到我们的数仓里,比如MySQL,不合法的总归是少数,那合法的我为什么不直接去时序数据库捞呢

脚本 :假设当我这个设备的某一个值达到临界点,假设:传感器知道水太大了,要让闸放开,我们完全可以在脚本中直接调用其他设备

时序数据库

1.时序数据库每一个数据点,也就是每一个属性点都有一个时间戳,不同于我们普通数据库以行为纬度,他的时间戳是以字段为维度的

2.他有自己的脚本语言(查询语言),比如InfluxDB 的高效脚本语言是Flux

3.支持数据保留策略,可以定义数据的保留周期,超过保留期的数据会自动清理,优化存储空间

截取一段JAVA本地连接InfluxDB的代码

xml 复制代码
<dependency>
    <groupId>com.influxdata</groupId>
    <artifactId>influxdb-client-java</artifactId>
    <version>6.9.0</version> <!-- 使用最新版本 -->
</dependency>
ini 复制代码
public static void main(String[] args) {
    // InfluxDB 连接配置
    String url = "ip/host";  // 替换为你的 InfluxDB URL
    String token = "token";  // 替换为你的token
    String bucket = "collect";  // 替换为你要查询的数据库名
    String org = "iiot";  // 替换为你的组织

    // 创建InfluxDB客户端
    InfluxDBClient influxDBClient = InfluxDBClientFactory.create(url, token.toCharArray(), org, bucket);

    // 编写查询语句(比如查询一个测量点的数据)
    String fluxQuery = "from(bucket:"collect") |> range(start: -2d) |> filter(fn: (r) => r["_measurement"] == "TEST2025030400002")";

    // 执行查询
    List<FluxTable> tables = influxDBClient.getQueryApi().query(fluxQuery);

    // 迭代 FluxTable 和 FluxRecord 来获取字段和时间
    for (FluxTable table : tables) {
        table.getRecords().forEach(record -> {
            // 获取字段名称(例如 "temperature_value")
            String fieldName = record.getField();

            // 获取时间戳并格式化成可读格式
            Instant timestamp = record.getTime(); // 获取时间戳
            String formattedTime = DateTimeFormatter
                    .ofPattern("yyyy-MM-dd HH:mm:ss")  // 自定义时间格式
                    .withZone(ZoneId.of("Asia/Shanghai"))  // 设置时区为中国时区(UTC+8)
                    .format(timestamp);

            // 获取字段值
            Object fieldValue = record.getValueByKey("_value"); // 获取字段值

            // 打印结果
            System.out.println("Time: " + formattedTime + " - Field: " + fieldName + " - Value: " + fieldValue);
        });
    }
    // 关闭客户端
    influxDBClient.close();
}

逐个解析字段:

from(bucket:"collect")中collect可以理解为库名

range(start: -2d)中d为天,可以支持小时,就是h

["_measurement"] == "TEST2025030400002")TEST2025030400002为设备编码,这条sql的结果就是查询这个设备下两天所有字段写入值。

注意withZone(ZoneId.of("Asia/Shanghai"))的时区一定要切换,如果直接拿过来不进行切换,平台如果有一些时间上的查询,会不准

报表

我们是有报表需求的,有一些报表的想法和实践可以参考一下

背景:我们要记录一些设备的平均值,汇总值,用户可以切换tab,可以看当天、星期、月纬度

拿到这个需求,我的第一个想法就是,首先肯定不能直接从mysql存mysql取,具体原因上面说过了,那肯定就要从时序数据库取,这个取得方式就需要自己去结合业务考虑

第一,我们肯定不能随查随取,比如我有强迫症,我有时候就逮着一个按钮没事摁俩下,时序数据库就是再快,我每次要走一遍JAVA调时序数据库吧,数据拿出来,我不能直接用吧,我要从代码层面进行业务逻辑算吧,这种情况就是再快,我没事点两下内存开销也受不了

第二,经常从时序数据库里面拿,时序数据库有一个特点就是可以定制周期清理数据,你还清不清了,这功能纯摆设呗

解决方案(可能不成熟)

所以我这边的解决方案就是,每天零点单独跑一个定时任务,或者脚本,这是一个思想,具体怎么做,因人而异

ini 复制代码
@Scheduled(cron = "0 0 0 * * ?")

每天零点单独跑一个任务,利用 range(start: -24h) 的策略,我去把上一天数据全撸出来 (如果要跑的很多,可以直接设置起始时间,避免记录到当天的一些数据,造成数据方面的不准确),这时候我在代码层面,无论是汇总也好,平均值也好,我来把他全部算好,放到我们的mysql的一张表里面,一天就只有一条数据,报表可能很复杂,数据块很多,但是我这一张表只做这一件事儿,就是一对一职责,这个数据库表就单独应对这个数据块的业务,我不要什么聚合逻辑,我就只干这一件事儿,以空间换时间

无论是月汇总,周汇总,统统来这里查、这里汇总

如果有当天24小时的时间段查询,这时候我们可以单独去时序数据库里面查,这个就没必要放到mysql里面了,没必要每小时去时序数据库汇总上一个小时的数据。

最后:如果是第一次做物联网的系统,刚刚接触,以我个人来讲,我拿我以前的项目经验去碰这个东西,我一开始是有点摸不清的,我觉得和我以前接触的系统的模式不一样,刚接触时一定要摒弃一些想法,要跟着它走,慢慢的我发现,其实物联网并不像其他系统的业务粘连性那么强,因为它是为传统行业而服务,它不是一个领先者的概念,它是服务于设备的,是一个附加值

相关推荐
雷渊2 分钟前
mysql-EXPLAIN执行计划分析
java·后端·面试
用户990450177800921 分钟前
JeecgFlow之Camunda开发脚手架介绍,让天下没有难用的工作流
后端
敖行客 Allthinker21 分钟前
Go 语言中 panic 和 recover 的代价:性能与设计的权衡
开发语言·后端·golang
谦行1 小时前
前端视角 Java Web 入门手册 4.4:Web 开发基础—— Listener
java·后端
非优秀程序员2 小时前
使用Python给自己网站生成llms.txt
人工智能·后端·架构
尘鹄2 小时前
一文讲懂Go语言如何使用配置文件连接数据库
开发语言·数据库·后端·golang
benben0442 小时前
Django小白级开发入门
后端·python·django
qw9493 小时前
SpringBoot3—场景整合:环境准备
java·后端
孟and平5 小时前
Flask 打包为exe 文件
后端·python·flask
大只因bug7 小时前
基于Django的协同过滤算法养老新闻推荐系统的设计与实现
后端·python·django·协同过滤算法推荐系统·新闻推荐网站系统·养老新闻推荐系统·个性化新闻推荐网站系统