diff --git a/RPi_Client/CoAPthon3/coapclient.py b/RPi_Client/CoAPthon3/coapclient.py index 2b815b3a9af358818b99a60e751e91a29e37c25a..bbc12949f1655a78658f06cb039c4f0ba23ef1a1 100644 --- a/RPi_Client/CoAPthon3/coapclient.py +++ b/RPi_Client/CoAPthon3/coapclient.py @@ -21,12 +21,15 @@ class CoapClient(): def __init__(self): # complete self.ip = "shmd01.iptime.org" self.myMAC = ':'.join(re.findall('..', '%012x' % uuid.getnode())) - self.clearMyData() + #self.clearMyData() self.myuuid, self.operate = self.obtainMyID() if self.operate == 1: # rpNode가 이미 한 개 이상존재하는 경우 self._beacon = BeaconEmit() self.advertiseMe() - + + if self.operate != 2: + self.calculateNodePositionAtServer() +""" def clearMyData(self): # complete path = "/rpNodeInfoPath" @@ -53,6 +56,7 @@ class CoapClient(): client.stop() client.stop() +""" def obtainMyID(self): # complete path = "/rpNodeInfoPath" @@ -114,10 +118,7 @@ class CoapClient(): response = client.put(path, json.dumps(payload)) print((response.pretty_print())) if json.loads(response.payload)['operate'] == 0: # Postion 계산이 불가능한 경우 - client.stop() - self.clearMyData() - print("RpNode Exit and delete my data in DB") - sys.exit(1) + print("impossble position calculation") except KeyboardInterrupt: print("obtainMyID Stop") @@ -162,7 +163,7 @@ class CoapClient(): regiRelThread.start() continue jsonpayload = self.mkJsonbeaconInfo(beaconInfo) - if jsonpayload['distance'] < 60: + if jsonpayload['distance'] < 40: payload.append(jsonpayload) response = client.put(path, json.dumps(payload)) @@ -176,12 +177,19 @@ class CoapClient(): def mkJsonbeaconInfo(self, info): # complete n = 2.05 + h = 0 + ad = 0 distance = math.pow(10, (float(info[4]) - float(info[5])) / (10 * n)) + if distance < h: + ad = 0 + else: + ad = sqrt(distance * distance - h * h) + payload = { 'rpuuid' : self.myuuid, 'userMAC' : info[0], 'useruuid' : info[1], - 'distance' : distance, + 'distance' : ad, 'updateTime' : time.time() } return payload @@ -221,7 +229,6 @@ class CoapClient(): def main(): measuringDevice = CoapClient() - measuringDevice.calculateNodePositionAtServer() putBLEInfoThread = threading.Thread(target = measuringDevice.putBLEInfo) putBLEInfoThread.start() putBLEInfoThread.join() diff --git a/Server_CoAP/CoAPthon3/coapserver.py b/Server_CoAP/CoAPthon3/coapserver.py index bea544be62d85544821dd4b3d683a211a91b0871..a721e4f67b30f772aa1ccbf1d83f0dc6be0058c4 100644 --- a/Server_CoAP/CoAPthon3/coapserver.py +++ b/Server_CoAP/CoAPthon3/coapserver.py @@ -28,7 +28,7 @@ class CoAPServer(CoAP): self.userNodeCollection = self.db.UserNodeData self.trackingCollection = self.db.TrackingData self.usersCollection = self.db.users - self.updatePeriod = 5 + self.updatePeriod = 10 self.limitDistance = 40 except: print("Could not connect to MongoDB") @@ -84,7 +84,7 @@ class CoAPServer(CoAP): if len(userLocationData) < 3: print("userLocationData < 3") - dd = datetime.datetime.now() + dd = datetime.datetime.utcnow() userNodeData = { 'rp1': {'rpuuid' : userLocationData[0]['rpuuid'], 'distance': userLocationData[0]['distance']}, 'useruuid': useruuid, @@ -110,7 +110,7 @@ class CoAPServer(CoAP): if x == None: print("no solution") - dd = datetime.datetime.now() + dd = datetime.datetime.utcnow() userNodeData = { 'rp1': {'rpuuid' : userLocationData[0]['rpuuid'], 'distance': userLocationData[0]['distance']}, 'useruuid': useruuid, @@ -122,7 +122,7 @@ class CoAPServer(CoAP): self.userNodeCollection.insert_one(userNodeData) return - dd = datetime.datetime.now() + dd = datetime.datetime.utcnow() userNodeData = { 'rp1': {'rpuuid' : userLocationData[0]['rpuuid'], 'distance': userLocationData[0]['distance']}, 'rp2': {'rpuuid' : userLocationData[1]['rpuuid'], 'distance' : userLocationData[1]['distance']}, diff --git a/Server_CoAP/CoAPthon3/exampleresources.py b/Server_CoAP/CoAPthon3/exampleresources.py index f568f2633b222e67b132ce26590105b1bed2e915..e9026f9416c6022f815100c6f5489909efb520d3 100644 --- a/Server_CoAP/CoAPthon3/exampleresources.py +++ b/Server_CoAP/CoAPthon3/exampleresources.py @@ -22,9 +22,11 @@ class RpNodeInfoResource(Resource): from coapthon.messages.response import Response assert(isinstance(response, Response)) self.payload = json.loads(self.payload) + """ if self.payload['option'] == -1: self.deleteNodeData(self.payload) - elif self.payload['option'] == 1: + """ + if self.payload['option'] == 1: response.payload = self.calculateNodePosition(self.payload) else : response.payload = self.postRpNodeInfoInDB(self.payload) @@ -46,7 +48,7 @@ class RpNodeInfoResource(Resource): response.payload = self.postRpNodeInfoInDB(self.payload) response.code = defines.Codes.CHANGED.number return self, response - +""" def deleteNodeData(self, info): # complete info = info['rpMAC'] graphColletion = self.db.RpGraphData @@ -54,33 +56,47 @@ class RpNodeInfoResource(Resource): rpuuid = self.collection.find({'rpMAC' : info})[0]['rpuuid'] graphColletion.remove({'v2' : rpuuid}) self.collection.remove({'rpMAC' : info}) +""" def postRpNodeInfoInDB(self, info): # complete info = info['rpMAC'] - rpuuid = "52528282"+str(uuid.uuid4())[8:] - rpuuid = rpuuid.replace("-","") - if self.collection.count() == 0: # 첫번째 rpNode인 경우 + cursor = self.collection.find({'rpMAC' : info['rpMAC']}) + if len(list(cursor)) == 1: + rpuuid = cursor[0]['rpuuid'] payload = { - 'rpMAC' : info, + 'rpMAC' : info['rpMAC'], 'rpuuid' : rpuuid } - self.collection.insert_one(payload) response = json.dumps({ 'rpuuid' : rpuuid, - 'operate' : 0 # advertise할 필요가 없다. + 'operate' : 2 # node position calculation할 필요가 없다 }) else: - payload = { - 'rpMAC' : info, - 'rpuuid' : rpuuid - } - self.collection.insert_one(payload) + rpuuid = "52528282"+str(uuid.uuid4())[8:] + rpuuid = rpuuid.replace("-","") + if self.collection.count() == 0: # 첫번째 rpNode인 경우 + payload = { + 'rpMAC' : info['rpMAC'], + 'rpuuid' : rpuuid + } + self.collection.insert_one(payload) - response = json.dumps({ - 'rpuuid' : rpuuid, - 'operate' : 1 # advertise를 해야한다. - }) + response = json.dumps({ + 'rpuuid' : rpuuid, + 'operate' : 0 # advertise할 필요가 없다. + }) + else: + payload = { + 'rpMAC' : info['rpMAC'], + 'rpuuid' : rpuuid + } + self.collection.insert_one(payload) + + response = json.dumps({ + 'rpuuid' : rpuuid, + 'operate' : 1 # advertise를 해야한다. + }) return response def calculateNodePosition(self, info): # complete , need to check 4-th case. @@ -96,39 +112,53 @@ class RpNodeInfoResource(Resource): self.collection.update({'rpuuid' : info}, {'$set':{'x': 0.0, 'y': 0.0}}, False) elif self.collection.count() == 2: # 자신이 두번째 RpNode인 경우 graphB = graphColletion.find({'v2': info}) + if len(list(graphB) == 0): + #type 0 : position을 구하지 못하는 경우 + print("2번째 rpNode를 만들 수 없습니다.(exist not one line)") + response['operate'] = 0 + self.collection.update({'rpuuid' : info}, {'$set' : {'type' : 0}}, False) + return json.dumps(response) + else: + x = graphB[0]['distance'] + self.collection.update({'rpuuid' : info}, {'$set':{'x': x, 'y': 0.0, 'type' : 1}}, False) x = graphB[0]['distance'] self.collection.update({'rpuuid' : info}, {'$set':{'x': x, 'y': 0.0}}, False) elif self.collection.count() == 3: # 자신이 세번째 RpNode인 경우 graphC = graphColletion.find({'v2': info}) - for doc in graphC: - tempdoc = self.collection.find({'rpuuid': doc['v1']}) - if tempdoc[0]['x'] == 0 and tempdoc[0]['y'] == 0: # 첫번째 RpNode 즉, (0,0) - vertexA = tempdoc[0]# 첫번째 RpNode를 vertexA라 한다. - elif tempdoc[0]['y'] == 0: - vertexB = tempdoc[0]#두번째 RpNode를 vertexB라 한다. - - dis = { - 'a': graphColletion.find({'v1': vertexB['rpuuid'], 'v2': info})[0]['distance'], - 'b': graphColletion.find({'v1': vertexA['rpuuid'], 'v2': info})[0]['distance'], - 'c': vertexB['x'] - } - if ((dis['a'] + dis['b']) <= dis['c']) or dis['a'] == 0 or dis['b'] == 0 or dis['c'] == 0: - # 3번째 rpNode를 만들 수 없는 경우 - print("3번째 rpNode를 만들 수 없습니다.(no triangle)") - response['operate'] = 1 - return json.dumps(response) - - cosA = (math.pow(dis['b'], 2) + math.pow(dis['c'], 2) - math.pow(dis['a'], 2)) / (2 * dis['b'] * dis['c']) - if cosA >= 1 or cosA <= -1 : - # 3번째 rpNode를 만들 수 없는 경우 - print("3번째 rpNode를 만들 수 없습니다.(impossible cosA)",cosA) - response['operate'] = 1 + if len(list(graphC) < 2): + print("3번째 rpNode를 만들 수 없습니다.(exist not two line)") + response['operate'] = 0 + self.collection.update({'rpuuid' : info}, {'$set' : {'type' : 0}}, False) return json.dumps(response) + else: + for doc in graphC: + tempdoc = self.collection.find({'rpuuid': doc['v1']}) + if tempdoc[0]['x'] == 0 and tempdoc[0]['y'] == 0: # 첫번째 RpNode 즉, (0,0) + vertexA = tempdoc[0]# 첫번째 RpNode를 vertexA라 한다. + elif tempdoc[0]['y'] == 0: + vertexB = tempdoc[0]#두번째 RpNode를 vertexB라 한다. + dis = { + 'a': graphColletion.find({'v1': vertexB['rpuuid'], 'v2': info})[0]['distance'], + 'b': graphColletion.find({'v1': vertexA['rpuuid'], 'v2': info})[0]['distance'], + 'c': vertexB['x'] + } + if ((dis['a'] + dis['b']) <= dis['c']) or dis['a'] == 0 or dis['b'] == 0 or dis['c'] == 0: + # 3번째 rpNode를 만들 수 없는 경우 + print("3번째 rpNode를 만들 수 없습니다.(no triangle)") + response['operate'] = 1 + return json.dumps(response) + + cosA = (math.pow(dis['b'], 2) + math.pow(dis['c'], 2) - math.pow(dis['a'], 2)) / (2 * dis['b'] * dis['c']) + if cosA >= 1 or cosA <= -1 : + # 3번째 rpNode를 만들 수 없는 경우 + print("3번째 rpNode를 만들 수 없습니다.(impossible cosA)",cosA) + response['operate'] = 1 + return json.dumps(response) - sinA = math.sqrt((1 - math.pow(cosA,2))) - x = dis['b'] * cosA - y = dis['b'] * sinA - self.collection.update({'rpuuid' : info}, {'$set':{'x': x, 'y': y}}, False) + sinA = math.sqrt((1 - math.pow(cosA,2))) + x = dis['b'] * cosA + y = dis['b'] * sinA + self.collection.update({'rpuuid' : info}, {'$set':{'x': x, 'y': y}}, False) else: graphD = graphColletion.find({'v2' : info}) nodeLocationData = [] diff --git a/Server_Vue_Express/backend/models/aggregateCache.js b/Server_Vue_Express/backend/models/aggregateCache.js new file mode 100644 index 0000000000000000000000000000000000000000..8181d3efb824629c5290ebde14aa844b7939b750 --- /dev/null +++ b/Server_Vue_Express/backend/models/aggregateCache.js @@ -0,0 +1,15 @@ +var mongoose = require('mongoose'); +const Schema = mongoose.Schema; + +const aggregateCacheSchema = new Schema({ + rpuuid: { type: String, default: "" }, + count:{ type: Number, default: 0 }, + time:{ type: Number, default: 0 }, +}, { collection : 'AggregateCache', // 컬렉션명 지정 + versionKey : false, // "__v" 필드 생성X + strict : false } +); + + +//users collection +module.exports = mongoose.model('AggregateCache', aggregateCacheSchema); \ No newline at end of file diff --git a/Server_Vue_Express/backend/models/rpNodeData.js b/Server_Vue_Express/backend/models/rpNodeData.js index f37b1688b6ba734b17695af09dec23d37d6768c8..86a9f216eae3004963f08c317ad97aec14ba1cf7 100644 --- a/Server_Vue_Express/backend/models/rpNodeData.js +++ b/Server_Vue_Express/backend/models/rpNodeData.js @@ -4,6 +4,7 @@ const Schema = mongoose.Schema; const rpNodeDataSchema = new Schema({ rpMAC: { type: String, default: "" }, rpuuid: { type: String, default: "" }, + rpname: { type: String, default: "" }, x:{ type: Number, default: 0 }, y:{ type: Number, default: 0 }, type : { type: String, default: "" } diff --git a/Server_Vue_Express/backend/public/lineChart.js b/Server_Vue_Express/backend/public/lineChart.js new file mode 100644 index 0000000000000000000000000000000000000000..8be019ad137b6a1d5076c6e019caa64ff59fd421 --- /dev/null +++ b/Server_Vue_Express/backend/public/lineChart.js @@ -0,0 +1,69 @@ + +var data = { + labels: [ + ], + datasets: [ + + ] +}; + + +var dat = { + +} +var options = { + animation: { + animateScale: false + }, + responsive: false, + scales: { + yAxes: [ + { + ticks: { + + beginAtZero: true + } + } + ], + xAxes: [ + { + ticks: { + + beginAtZero: true + } + } + ] + } +}; +var ctx = document.getElementById("myChart").getContext('2d'); +var myBarChart = new Chart(ctx, { + type: 'line', + data: data, + options: options +}); +var button = document.getElementById("sendAjax") + +button.addEventListener("click", function() { + sendAjax('http://localhost:3000/'); +}) + +function sendAjax(url) { + var oReq = new XMLHttpRequest(); + + oReq.open('POST', url); + oReq.setRequestHeader('Content-Type', "application/json") // json 형태로 보낸다 + oReq.send(); + + oReq.addEventListener('load', function() { + var result = JSON.parse(oReq.responseText); + var score = result.score; + var comp_data = data.datasets[0].data; + + for (var i = 0; i < comp_data.length; i++) { + comp_data[i] = score[i]; + } + + data.datasets[0].data = comp_data; + myBarChart.update(); + }) +} \ No newline at end of file diff --git a/Server_Vue_Express/backend/routes/api.js b/Server_Vue_Express/backend/routes/api.js index 5b148bf128472231e68a4b030c098053d74c8c02..d7832e831eacc27b7ac6733f364f67a1cbc839f2 100644 --- a/Server_Vue_Express/backend/routes/api.js +++ b/Server_Vue_Express/backend/routes/api.js @@ -5,6 +5,7 @@ var User = require('../models/users'); var Tracking = require('../models/tracking'); var UserNode = require('../models/userNode'); var rpNode = require('../models/rpNodeData'); +var aggregateCache = require('../models/aggregateCache'); /* var User = require('../models/users'); var user = new User({ @@ -86,49 +87,47 @@ router.get('/findUserByUUID/:id', function(req, res, next) { //console.log(output[0].name) UserName = output[0].name; }) - await User.find({uuid:req.params.id}, (err,output)=>{ - //res.json(output); - //console.log(output[0].name) - UserName = output[0].name; - }) - await UserNode.find({useruuid:req.params.id}, (err,output)=>{ + await UserNode.find({useruuid:req.params.id}).sort({updateTime : -1}).exec((err,output)=>{ //res.json(output); //console.log("tt,",output[0].rp1) - + console.log(output[0].updateTime, output[0]._id); try{ - temp =[output[output.length-1].rp1,output[output.length-1].rp2,output[output.length-1].rp3]; + temp =[output[0].rp1,output[0].rp2,output[0].rp3]; UserLocation ={ - x:output[output.length-1].x, - y:output[output.length-1].y, + x:output[0].x, + y:output[0].y, r:10 } }catch(exception){} - }) - - // await rpNode.find((err,output) =>{ - // rpNodeData = output; - // console.log("tt",JSON.stringify(rpNodeData)); - // }) - for(i in temp){ - console.log(i, temp[i].rpuuid) - await rpNode.find({'rpuuid': temp[i].rpuuid},(err,output)=>{ - console.log(output) - if(output.length != 0) - rpNodeData.push({ - rpuuid : temp[i].rpuuid, - x: output[0].x, - y: output[0].y, - r: temp[i].distance * 20 + //console.log("kkk",temp); + (async ()=>{ + for(i in temp){ + console.log(i, temp[i].rpuuid) + await rpNode.find({'rpuuid': temp[i].rpuuid},(err,output)=>{ + console.log(output[0]) + if(err) + console.log(err); + if(output.length != 0) + rpNodeData.push({ + rpname : output[0].rpname, + rpuuid : temp[i].rpuuid, + x: output[0].x, + y: output[0].y, + r: temp[i].distance + }) }) - }) - //console.log(rpNodeData,i) - } + } + console.log(rpNodeData) + res.render('index',{title:'Express',UserName:UserName ,UserLocation: UserLocation, rpNodeData:JSON.stringify(rpNodeData)}) + + })(); + + }) } catch(exception){ console.log(exception) } - console.log(rpNodeData) - res.render('index',{title:'Express',UserName:UserName ,UserLocation: UserLocation, rpNodeData:JSON.stringify(rpNodeData)}) + })(); }); @@ -141,7 +140,7 @@ router.get('/users', function(req, res, next) { }); -router.get('/rpis', function(req, res, next) { +router.get('/rpis/:id', function(req, res, next) { // User.find((err,output) =>{ // console.log(output); // res.render('users', { data: output }); @@ -153,10 +152,40 @@ router.get('/rpis', function(req, res, next) { } } ],function(rr,ra){ - if(ra){ - console.log(ra); - res.render('rpis',{data:ra}); - } + var data = []; + (async ()=>{ + let lastUpdateTime = Math.floor(Number(new Date())/1000); + for(i in ra){ + + temp =await Tracking.aggregate([ + { + '$match': { + 'rpuuid': ra[i]._id, + 'updateTime': { + '$lt': lastUpdateTime, + '$gt': lastUpdateTime - 60, + + }, + distance: {'$lt': 40} + } + }, { + '$group': { + '_id': '$userMAC' + } + } + ]); + await rpNode.find({'rpuuid': ra[i]._id},(err,output)=>{ + if(output[0].rpname.indexOf(req.params.id) != -1 || req.params.id == "*") + data.push({ + rpuuid: ra[i]._id, + rpname: output[0].rpname, + count: temp.length, + }); + }); + } + res.render('rpis',{data}); + })(); + }); }); @@ -165,36 +194,91 @@ router.get('/aggregateByRPUUID/:id', function(req, res, next) { // console.log(output); // res.render('users', { data: output }); // }) - Tracking.findOne({rpuuid: req.params.id},(err, output) => { + var timeLogs = []; + Tracking.findOne({rpuuid: req.params.id}).sort({updateTime : -1}).exec((err, output) => { console.log(output); - const lastUpdateTime = output.updateTime; - const lastUpdateTimeObject = new Date(Date(output.updateTime)); - console.log(Date(lastUpdateTime)); - - console.log(output.distance) - - Tracking.aggregate([ - { - '$match': { - 'rpuuid': output.rpuuid, - 'updateTime': { - '$gt': lastUpdateTime - 10 - }, - distance: {'$lt': 10} + let rpname = ""; + let lastUpdateTime = Math.floor(output.updateTime); + lastUpdateTime -= lastUpdateTime%60; + const lastUpdateTimeObject = new Date(lastUpdateTime*1000); + var temp =[]; + + (async ()=>{ + await rpNode.find({rpuuid: output.rpuuid},(err,output)=>{ + rpname = output[0].rpname; + }); + for(let i = 0; i< 60; i++){ + + temp = await aggregateCache.find({'rpuuid':output.rpuuid,time:lastUpdateTime - 60*i}); + if(temp.length == 0){ + temp =await Tracking.aggregate([ + { + '$match': { + 'rpuuid': output.rpuuid, + 'updateTime': { + '$lt': lastUpdateTime - 60*i, + '$gt': lastUpdateTime - 60*i - 60, + + }, + distance: {'$lt': 40} + } + }, { + '$group': { + '_id': '$userMAC' + } + } + ]); + var out = await new aggregateCache({ + rpuuid: output.rpuuid, + count: temp.length, + time: lastUpdateTime - 60*i, + }).save(); + + + await Tracking.deleteMany({ + 'rpuuid': output.rpuuid, + 'updateTime': { + '$lt': lastUpdateTime - 60*i, + '$gt': lastUpdateTime - 60*i - 60, + } + }); + // console.log(out); + timeLogs.push(temp.length); } - }, { - '$group': { - '_id': '$userMAC' + else{ + // console.log(temp[0].count); + timeLogs.push(temp[0].count); } + } - ],function(rr,ra){ - if(ra){ - console.log(ra); - res.json({Date : lastUpdateTimeObject.toLocaleString('ko-KR', { - timeZone: 'Asia/Seoul' - }),count : ra.length,result: ra}); - } - }) + // console.log(timeLogs); + res.render('rpisAggregate',{timeLogs:timeLogs,lastUpdateTime:lastUpdateTime,rpname}); + })(); + + + + // Tracking.aggregate([ + // { + // '$match': { + // 'rpuuid': output.rpuuid, + // 'updateTime': { + // '$gt': lastUpdateTime - 60 + // }, + // distance: {'$lt': 10} + // } + // }, { + // '$group': { + // '_id': '$userMAC' + // } + // } + // ],function(rr,ra){ + // if(ra){ + // console.log(ra); + // res.json({Date : lastUpdateTimeObject.toLocaleString('ko-KR', { + // timeZone: 'Asia/Seoul' + // }),count : ra.length,result: ra}); + // } + // }) }) //res.json({}); }); diff --git a/Server_Vue_Express/backend/views/index.pug b/Server_Vue_Express/backend/views/index.pug index 5f97ba7249f5236c62a6faa7337755ccd4707bb0..8bb0b28eaca381f31c3f96f24de375a92d654cb8 100644 --- a/Server_Vue_Express/backend/views/index.pug +++ b/Server_Vue_Express/backend/views/index.pug @@ -1,7 +1,9 @@ extends layout block content + p #{UserName} p #{UserLocation.x}, #{UserLocation.y} + p(id="closeRpNode") script(type='text/javascript', src ="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.js") canvas(id="myChart",width="700", height="400") script(type='text/javascript', src ="/chart.js") @@ -28,7 +30,7 @@ block content var t = []; const nodeData = JSON.parse(`#{rpNodeData}`.replace(/"/g, '"')); - + document.getElementById("closeRpNode").innerText = nodeData[0].rpname +", "+(nodeData[0].r).toFixed(2)+"M 근처"; for(i in nodeData){ t.push({ x: nodeData[i].x, diff --git a/Server_Vue_Express/backend/views/rpis.pug b/Server_Vue_Express/backend/views/rpis.pug index 69a80d86ec992d46ed3115b105ad63302845c9cf..7ea09a13b75faa3c3d92330f722465e08779b484 100644 --- a/Server_Vue_Express/backend/views/rpis.pug +++ b/Server_Vue_Express/backend/views/rpis.pug @@ -1,10 +1,12 @@ extends layout block content + input(type='text' id='input' name='rpiSearch' placeholder='검색할 단어를 입력하세요') + button(onclick='const k =document.getElementById("input").value; location.href= k!= ""?k:"*" ') 검색 hr(size='3px') p - let i=0; for i in data - a(href='/api/aggregateByRPUUID/'+i._id) #{i.name} , uuid:#{i._id} + a(href='/api/aggregateByRPUUID/'+i.rpuuid) #{i.rpname} , #{i.count}명 , uuid:#{i.rpuuid} br -i++ \ No newline at end of file diff --git a/Server_Vue_Express/backend/views/rpisAggregate.pug b/Server_Vue_Express/backend/views/rpisAggregate.pug new file mode 100644 index 0000000000000000000000000000000000000000..c4dc36e03eab637ac4d3395607a86bfb5544c855 --- /dev/null +++ b/Server_Vue_Express/backend/views/rpisAggregate.pug @@ -0,0 +1,33 @@ +extends layout + +block content + script(type='text/javascript', src ="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.js") + canvas(id="myChart",width="700", height="400") + script(type='text/javascript', src ="/lineChart.js") + script(type='text/javascript'). + var timeLogs = [#{timeLogs}]; + console.log(#{lastUpdateTime}); + var dataset =[]; + + for(var i=1;i<=60;i++){ + dataset.push({x:i,y:timeLogs[60-i]}); + + data.labels.push(new Date((#{lastUpdateTime}-3600+32400)*1000 + i*60000).toISOString().replace('T', ' ').substr(0, 16)) + } + console.log(dataset) + try{ + data.datasets.push({ + label: '#{rpname}', + data: dataset, + backgroundColor: [ + 'rgba(255, 159, 64, 0.2)' + ], + borderColor: [ + 'rgba(255, 159, 64, 1)' + ], + borderWidth: 1 + }); + }catch{ + console.log("err"); + } + myBarChart.update(); \ No newline at end of file