调用第三方接口实现数据可视化的功能:
业务实现:调用中间件数据接口——获得传感器实时数据——图表展示
虽然看似很简单一个功能 但是在做的过程中还是走了很多弯路,因为完全是第一次做嘛!!当然这不是借口 也不是托词,下面我要开始陈述我的采坑过程了~~~~~
刚开始不明确业务逻辑 什么节点,传感器,什么APPEUI,DEVEUI,完全不知道是干啥用的,一脸闷逼的我哈。准备了一下几种实施方案:
方案一:直接用MQTT获取实时数据,然后写了一个MQTT 的客户端 用来发送TCP请求 实现订阅获得数据。很完美 呵呵 ~获取到数据了。但是发现了一个问题, 我的数据是要通过chart直接展示的,也就是说需要用户在出发AJax请求的时候 就需要立即展示出一段时间范围内全部数据变化趋势,而MQTT传回客户端大概每隔19秒才传回一条数据。很显然这样是行不通的。。。。。在此有人可能会说 那你为什么不把传回的数据直接存到数据库呢,然后ajax直接请求数据库的数据不就行了! 待我假装沉思几秒。。。。。。。这种方案确实可行呢 ,但是我觉得它还是有以下一个弊端:
- 因为每个节点传回的数据类型都是不同的,这就意味着 有多少种类型 就需要建相应的表,去储存 这样当类型很多的时候,数据量特别大的时候 很消耗内存。我们既然值做个数据可视化 ,那完全就没有这种必要了嘛!
方案二:直接调用第三方平台的的日志数据,而且都不用我去获取jwt直接跳过登录直接获取数据了而且还是解析完的数据,都不用我再去解密了。。卧槽感觉我的这个想法太完美了。但是当我看到返回的一堆数据是这样的:
完全不是json格式嘛………….获取自己想要的数据太麻烦了,果断放弃了这种方式。。。。
方案三:也是最后实行的一种方案。直接调用历史数据接口。
- 我在登陆的时候获得用httpclient带用户名和密码发送请求获得jwt,然后储存在session当中,
然后带着jwt 请求相应的数据接口获得数据。
Ajax请求的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
@RequestMapping(params = "chartsData") @ResponseBody public AjaxJson chartsData(HttpServletRequest request, HttpServletResponse response) { String deveui = request.getParameter("deveui"); String beginTime = request.getParameter("beginTime"); String enddate = request.getParameter("endTime"); if(enddate.equals("")) { Date date = new Date(); SimpleDateFormat sp=new SimpleDateFormat("yyyy-MM-dd"); Calendar c = Calendar.getInstance(); c.setTime(date); c.add(Calendar.DAY_OF_MONTH, 1);// 今天+1天 Date tomorrow = c.getTime(); String format = sp.format(tomorrow); enddate=format; } AjaxJson ajson=new AjaxJson(); JSONArray jsonArray = null; JSONArray rmap = new JSONArray(); try { String url="XXXXXXXX="+enddate+"&type=0";//接口地址填自己的 String jwt = (String) request.getSession().getAttribute("jwt"); JSONObject OpenidJSONO = doGetStr(url,jwt); //可以得到的内容 String totalCount = String.valueOf(OpenidJSONO.get("totalCount")); String result1 = String.valueOf(OpenidJSONO.get("result")); jsonArray = OpenidJSONO.getJSONArray("result");//获取数组 if(jsonArray.size()>0){ for(int i=0;i<jsonArray.size();i++){ JSONObject po=new JSONObject(); JSONObject job = jsonArray.getJSONObject(i);// 遍历 jsonarray 数组,把每一个对象转成 json 对象 System.out.println(job.get("payload")+"=");// 得到 每个对象中的属性值 String payload = (String)job.get("payload"); String dateTime = String.valueOf(job.get("dateTime")); // {sensorType:1,frameType:3,Payload:{rs485Payload:2a0101040000400723}} String[] strs = payload.split("rs485Payload:"); String s = strs[1].toString(); System.out.println(s); String[] str = s.split("}"); String n = str[0].toString(); System.out.println(n); Map<String, Object> transformation = VibrationTemperatureSensorController.transformation(n); Object zd = transformation.get("zd");//震动 Object tm = transformation.get("tm");//温度 po.put("zd1",zd); po.put("tm1",tm); po.put("dateTime1",dateTime); rmap.add(po); } } // //用户保存的作用域 ajson.setSuccess(true); ajson.setObj(rmap); ajson.setMsg("获取数据成功"); return ajson; } catch (Exception e) { e.printStackTrace(); ajson.setSuccess(false); ajson.setMsg("获取数据失败"); } return ajson; } |
说明:transformation()这个方法是根据通讯协议解密rs485Payload对应的的值的。被我用最笨的方法截取出来,最后组成json串返回的。
被请求的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
/** * Get请求,方便到一个url接口来获取结果 * @param url * @return */ public static JSONObject doGetStr(String url,String jwt){ DefaultHttpClient defaultHttpClient = new DefaultHttpClient(); HttpGet httpGet = new HttpGet(url); httpGet.addHeader("Accept", "application/json"); // 传输的类型 httpGet.addHeader("Content-Type", "application/json"); httpGet.addHeader("Authorization", "bearer "+jwt); JSONObject jsonObject = null; try{ HttpResponse response = defaultHttpClient.execute(httpGet); HttpEntity entity = response.getEntity(); if(entity != null){ String result = EntityUtils.toString(entity, "UTF-8"); jsonObject = JSONObject.parseObject(result); } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return jsonObject; } |
前台 ajax 请求的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
function ViewChart() { var beginTime = $("input[name='createDate_begin']").val(); var endTime = $("input[name='createDate_end']" ).val(); if(selectid==null||selectid==""){ layer.alert("请先选择传感器",{icon: 5,title :'提示'}); } else{ $.ajax({ type: "GET", url: "minformationController.do?chartsData&beginTime="+beginTime+"&endTime="+endTime+"&deveui=" + "ffffff10000042df", success: function (jsondata) { debugger; a = JSON.parse(jsondata); var obj = a.obj; if(obj.length>0){ var xAxisData = []; var seriesDataH = []; var seriesDataT = []; var echartsWarp= parent.document.getElementById('main'); var myChart = echarts.init(echartsWarp); // $.each(obj,function(key,value){ //遍历键值对 // xAxisData.put(value.dateTime1); // }) for (var i=obj.length-1;i>=0;i--) { xAxisData.push(obj[i].dateTime1); seriesDataT.push(obj[i].tm1); seriesDataH.push(obj[i].zd1); } option = { tooltip: { trigger: 'axis' }, legend: { data: [ '震动','温度'] }, toolbox: { show: true, feature: { dataView: {show: true, readOnly: false}, magicType: {show: true, type: ['line', 'bar']}, restore: {show: true}, saveAsImage: {show: true} } }, calculable: true, xAxis: [ { type: 'category', data: xAxisData } ], yAxis: [ { type: 'value' } ], series: [ { name: '温度', type: 'line', data: seriesDataT, markPoint: { data: [ {type: 'max', name: '最大值'}, {type: 'min', name: '最小值'} ] }, markLine: { data: [ {type: 'average', name: '平均值'} ] } }, { name: '震动', type: 'line', data: seriesDataH, markPoint: { data: [ {type: 'max', name: '最大值'}, {type: 'min', name: '最小值'} ] }, markLine: { data: [ {type: 'average', name: '平均值'} ] } } ] }; myChart.setOption(option); } } }) parent.layer.open({ title:"实时曲线", type: 1, moveOut: true, zIndex:999, area: ['1320px', '640px'], //宽高 content: '<div id="main" style="width:1280px;height:550px"></div>' }); } |