物联网平台搭建的全过程介绍(七)——本地数据批量上传阿里云物联网实例内TSDB

在文章物联网平台搭建的全过程介绍(六)——物联网TSDB之基本知识及读写代码介绍中介绍了TSDB基础知识和读取和写入数据的基本操作。但在该文中只给出了单条数据写入的代码。

那么假如有这样一种情况,我物联网平台已经建立起来了,但是在平台建立之前,我很多设备的数据已经采集存到了本地,我想把这些数据上传到物联网平台内的TSDB内,应该怎么操作呢?

这就需要批量数据上传的问题。本例给出了一种简单的方案,谨供参考。

目录

一、准备工作

1、本地原始数据

2、日期时间转换成时间戳

3、把原始数据按照tsdb数据包格式进行处理

4、将数据转换为txt格式

二、编写jave程序

1、layout设计

2、 添加依赖

3、jave程序

(1)全部代码

(2)把txt文件放入res/raw文件夹下

(3)调取并打开temperature.txt文件

(4)按行读取txt文件内容

(5)把数据上传TSDB

(6)利用Handler来等待网络相关线程结束

三、测试

1、相关代码

2、读取结果


一、准备工作

1、本地原始数据

温度数据
设备编号采集日期时间数值
202110002022年7月11日 12:27:5623.9 
202101382022年4月24日 9:28:0937.6 
202101332022年5月13日 10:05:4932.8 
202101432022年4月26日 13:54:4338.7 
202101392022年6月11日 17:18:4933.2 
202101352022年8月24日 10:08:0035.3 
202101342022年5月11日 10:38:1032.1 
202101302022年5月14日 11:46:1528.8 
202101452022年8月21日 12:22:3823.3 
202101442022年6月18日 7:09:1239.3 
202101322022年5月13日 13:28:0535.5 
202101412022年8月25日 18:41:4237.5 
202101422022年4月28日 9:31:1428.7 
202101372022年4月26日 13:29:0931.2 
202101312022年6月7日 6:24:4330.9 
202101362022年4月24日 15:47:5926.4 
202101402022年6月5日 10:56:1020.2 
202101242022年5月11日 9:31:1828.0 
202101292022年4月28日 10:41:5933.6 
202101602022年5月11日 11:27:3430.5 

2、日期时间转换成时间戳

首先把采集日期和时间转换成时间戳,利用excel即可。计算公式:

timestamp=(XN-19-70*365)*86400-8*3600,XN为日期、时间所在的单元格。注意,此公式计算出来的是秒,本例时间戳的单位为毫秒,所以需要把最终结果再乘1000,得到以下结果。

温度数据
设备编号时间戳数值
202110001657513675760 23.9 
202101381650763688784 37.6 
202101331652407549423 32.8 
202101431650952483023 38.7 
202101391654939129220 33.2 
202101351661306880379 35.3 
202101341652236689967 32.1 
202101301652499974879 28.8 
202101451661055757676 23.3 
202101441655507351683 39.3 
202101321652419684665 35.5 
202101411661424101807 37.5 
202101421651109473699 28.7 
202101371650950949310 31.2 
202101311654554282844 30.9 
202101361650786478805 26.4 
202101401654397769561 20.2 
202101241652232678091 28.0 
202101291651113719028 33.6 
202101601652239653588 30.5 

3、把原始数据按照tsdb数据包格式进行处理

metric为温度值,命名为:temperature

tag为设备编号,timestamp为时间戳

metric:temperature
tagtimestampvalue
202110001657513675760 23.9 
202101381650763688784 37.6 
202101331652407549423 32.8 
202101431650952483023 38.7 
202101391654939129220 33.2 
202101351661306880379 35.3 
202101341652236689967 32.1 
202101301652499974879 28.8 
202101451661055757676 23.3 
202101441655507351683 39.3 
202101321652419684665 35.5 
202101411661424101807 37.5 
202101421651109473699 28.7 
202101371650950949310 31.2 
202101311654554282844 30.9 
202101361650786478805 26.4 
202101401654397769561 20.2 
202101241652232678091 28.0 
202101291651113719028 33.6 
202101601652239653588 30.5 

4、将数据转换为txt格式

把以上数据去除表头之后的数据转换为txt格式,命名为temperature.txt并存放起来,以备用。 

注意,此txt文件最好是从excel直接拷贝过来的。这样保证每列数据之间是tab格,而不是多个空格,如果有多余的空格,后边读取每一行字符串并解析设备编号、时间戳和温度值三个变量数据的时候会出错。文本最后一行多余的空格也要删掉。

二、编写jave程序

1、layout设计

随便放一个按钮和Textview,点按钮后执行写入程序,Textview用于显示操作结果即可,不详细介绍了。

2、 添加依赖

    implementation 'com.aliyun:hitsdb-client:0.2.7'
    implementation 'org.slf4j:slf4j-simple:1.7.25'

3、jave程序

(1)全部代码

package com.example.readtsdb;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.TextView;
import android.widget.Button;

import android.content.ContentValues;
import android.content.Intent;
import android.view.View;
import android.widget.TextClock;


import com.aliyun.hitsdb.client.TSDB;
import com.aliyun.hitsdb.client.TSDBClientFactory;
import com.aliyun.hitsdb.client.TSDBConfig;
import com.aliyun.hitsdb.client.value.request.Point;
import com.aliyun.hitsdb.client.value.request.Point;


import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.io.InputStream;
import android.content.res.Resources;

public class MainActivity extends AppCompatActivity {
    Button bt1;
    TextView tv1;
    String connectString = "ts-*****************.hitsdb.rds.aliyuncs.com";
    int port = 3242;
    //实例详情页面中的时序数据存储用户名、密码。
    String username = "iotuser";
    String password = "***********";    


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bt1=this.findViewById(R.id.write);
        tv1 = this.findViewById(R.id.status);
        final Resources res = super.getResources();//获取资源文件

        
        //以下为点按钮把数据写入tsdb

        bt1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

        
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    final TSDBConfig config = TSDBConfig.address(connectString, port)
                            .basicAuth(username, password)
                            // 网络连接池大小,默认为64。
                            .httpConnectionPool(128)
                            // HTTP 等待时间,单位为秒,默认为90秒。
                            .httpConnectTimeout(90)
                            // IO 线程数,默认为1。
                            .ioThreadCount(1)
                            .config();

                    TSDB tsdbClient = TSDBClientFactory.connect(config);
                    long now = System.currentTimeMillis();

                    
                    // 读取raw目录下txt文件temperature
                    InputStream input = res.openRawResource(R.raw.temperature);	
                    
                    // 实例化Scan
                    Scanner scan = new Scanner(input);

                    String TempInfo = null; //定义txt文件内的行字段变量

                    // 循环读取
                    while (scan.hasNext()) {								
                        
                        // 按行读取
                        TempInfo =scan.nextLine();
                        
                        //数据按空格拆分存入数组内                          
                        String[] ArrayTempInfo=TempInfo.split("\\t+");

                        //从数组中取出时间戳、设备编号、温度等字符串并转成相应类型数据
                        long timestamp = Long.parseLong(TempInfo[1]);
                        String deviceName=TempInfo[0];
                        Double temp=Double.parseDouble(TempInfo[2]);
                                                
                        
                        // 构造Point。
                        Point point = Point.metric("Temperature")
                            .tag("deviceName", deviceName)
                            .timestamp(timestamp).value(temp)
                            .build();
                     
                        //直接提交数据。
                        tsdbClient.put(point);

                    }
                   
                    //关闭输入流
                    scan.close();
                    mHandler.sendEmptyMessage(0);
                    


                } catch (Exception e) {
                    e.printStackTrace();

                }
            }
        }).start();


            }
        });

    }


    @SuppressLint("HandlerLeak")
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 0:
                    tv1.setText("数据写入完成!");
                    break;
            }
        }
    };

}

(2)把txt文件放入res/raw文件夹下

把文件temperature.txt直接拖进raw文件夹内即可。

(3)调取并打开temperature.txt文件

此处注意,打开文件执行完读取操作后,要用.close方法把文件关闭。

final Resources res = super.getResources();//获取资源文件
// 读取raw目录下txt文件temperature
InputStream input = res.openRawResource(R.raw.temperature);	
                    
// 实例化Scan
Scanner scan = new Scanner(input);


//此处添加打开文件后的具体操作




//操作完之后关闭输入流
scan.close();




(4)按行读取txt文件内容

按行读取temperature.txt文件,并把行字符串截分成设备编号、时间戳、数值三部分,存入数组,然后赋值给三个变量timestamp、deviceName、temp。

String TempInfo = null; //定义txt文件内的行字段变量

// 循环读取
while (scan.hasNext()) {								
                        
    // 按行读取
    TempInfo =scan.nextLine();
                        
     //数据按空格拆分存入数组内                          
    String[] ArrayTempInfo=TempInfo.split("\\t+");

    //从数组中取出时间戳、设备编号、温度等字符串并转成相应类型数据
    long timestamp = Long.parseLong(TempInfo[1]);
    String deviceName=TempInfo[0];
    Double temp=Double.parseDouble(TempInfo[2]);


}

(5)把数据上传TSDB

用Point(数据点)类把变量timestamp、deviceName、temp数值打包并上传。

                        // 构造Point。
                        Point point = Point.metric("Temperature")
                            .tag("deviceName", deviceName)
                            .timestamp(timestamp).value(temp)
                            .build();
                     
                        //直接提交数据。
                        tsdbClient.put(point);

(6)利用Handler来等待网络相关线程结束

因为上传数据到tsdb属于网络操作,必须在新开线程里进行。待上传tsdb线程结束后,给Handler发送一条消息,触发Handler内的case 0下的执行语句。

mHandler.sendEmptyMessage(0);//此句是触发mHandler运行的一个条件,放在网络线程结束之后的地方



    @SuppressLint("HandlerLeak")
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 0:
                    tv1.setText("数据写入完成!");
                    break;
            }
        }
    };

三、测试

待上传完成后,要读取一下刚上传的内容是否正确。

1、相关代码

读取代码如下(此部分代码在jave主程序里没有给,可另外设计一个"读取"按钮,把这部分代码放到按钮监听里)

注意:当没有设置tags时,那么就把所有的tags的数据都读出来了。

                    Map<String, String> tags = new HashMap<String, String>();
//                    tags.put("deviceName","20210181");//当不限定tag时,即搜寻所有的tags
                    String metric = "Temperature";


                    LastPointQuery query = LastPointQuery.builder()
                            .timestamp(now)
                            .backScan(0)
                            .msResolution(true)
                            .sub(LastPointSubQuery.builder(metric, tags).build()).build();
                    List<LastDataValue> lastDataValues = tsdbClient.queryLast(query);

                    System.out.println(lastDataValues);

2、读取结果

读取结果如下图所示,可以看到刚上传到tsdb里的数据都可以读取出来了。但发现读取的内容顺序和写入内容的顺序不一致,而且读出来的数据也不是按时间戳排列的。这点还需要再研究一下原因。

 (全文结束)

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值