From 62dc57a3da13f86905560aa347a99921f60bfb40 Mon Sep 17 00:00:00 2001
From: "Server (Shared Users)" <shmd01.iptime.org>
Date: Tue, 26 Nov 2019 04:43:50 +0000
Subject: [PATCH] revise coapserver.py and exampleresource.py

---
 RPi_Client/CoAPthon3/coapclient.py            |  20 +--
 Server_CoAP/CoAPthon3/coapserver.py           |  90 +++++++++++-
 Server_CoAP/CoAPthon3/exampleresources.py     | 129 ++++++++++++------
 Server_CoAP/{ => CoAPthon3}/triangulation.py  |   0
 .../backend/models/rpNodeData.js              |  17 +++
 Server_Vue_Express/backend/models/userNode.js |  17 +++
 Server_Vue_Express/backend/public/chart.js    |  70 ++++++++++
 Server_Vue_Express/backend/routes/api copy.js |  76 +++++++++++
 Server_Vue_Express/backend/routes/api.js      |  64 ++++++++-
 Server_Vue_Express/backend/views/index.pug    |  55 +++++++-
 Server_Vue_Express/backend/views/layout.pug   |   1 +
 Server_Vue_Express/backend/views/users.pug    |  10 ++
 12 files changed, 488 insertions(+), 61 deletions(-)
 rename Server_CoAP/{ => CoAPthon3}/triangulation.py (100%)
 create mode 100644 Server_Vue_Express/backend/models/rpNodeData.js
 create mode 100644 Server_Vue_Express/backend/models/userNode.js
 create mode 100644 Server_Vue_Express/backend/public/chart.js
 create mode 100644 Server_Vue_Express/backend/routes/api copy.js
 create mode 100644 Server_Vue_Express/backend/views/users.pug

diff --git a/RPi_Client/CoAPthon3/coapclient.py b/RPi_Client/CoAPthon3/coapclient.py
index a3812a3..b80a69a 100644
--- a/RPi_Client/CoAPthon3/coapclient.py
+++ b/RPi_Client/CoAPthon3/coapclient.py
@@ -26,7 +26,7 @@ class CoapClient():
             self._beacon = BeaconEmit()
 
     def obtainMyID(self):
-        path = "/rasbpNodeInfoPath"
+        path = "/rpNodeInfoPath"
         
         path = "coap://" + self.ip + path
         host, port, path = parse_uri(path)
@@ -41,11 +41,11 @@ class CoapClient():
         try:            
             payload = {
                 'option' : 0,
-                'myMAC' : self.myMAC
+                'rpMAC' : self.myMAC
             }
             response = client.put(path, json.dumps(payload))
             print((response.pretty_print()))
-            string = json.loads(response.payload)['uuid']
+            string = json.loads(response.payload)['rpuuid']
 
         except KeyboardInterrupt:
             print("obtainMyID Stop")
@@ -65,7 +65,7 @@ class CoapClient():
         self._beacon.beacon_Start(string)
 
     def calculateNodePositionAtServer(self):
-        path = "/rasbpNodeInfoPath"
+        path = "/rpNodeInfoPath"
         
         path = "coap://" + self.ip + path
         host, port, path = parse_uri(path)
@@ -80,7 +80,7 @@ class CoapClient():
         try:            
             payload = {
                 'option' : 1,
-                'myuuid' : self.myuuid
+                'rpuuid' : self.myuuid
             }
             response = client.put(path, json.dumps(payload))
             print((response.pretty_print()))
@@ -143,8 +143,8 @@ class CoapClient():
         n = 2.2
         distance = math.pow(10, (float(info[4]) - float(info[5])) / (10 * n))
         payload = {
-            'rasbpuuid' : self.myuuid,
-            'uuid' : info[1],
+            'rpuuid' : self.myuuid,
+            'useruuid' : info[1],
             'distance' : distance,
             'updateTime' : time.time()
         }
@@ -152,7 +152,7 @@ class CoapClient():
 
     def regiRelWithNewPi(self, info):
         #새로운 rasbPi를 찾은 경우 새로운 rasbPi를 위치측정기로 사용하기 위해서 server에 관련 정보를 저장하는 method
-        path = "/rasbpGraphInfoPath"
+        path = "/rpGraphInfoPath"
         
         path = "coap://" + self.ip + path
         host, port, path = parse_uri(path)
@@ -165,7 +165,7 @@ class CoapClient():
         client = HelperClient(server=(host, port))
 
         try:            
-            response = client.put(path, json.dumps(self.mkJsonRasbpgraphInfo(info)))
+            response = client.put(path, json.dumps(self.mkJsonRpgraphInfo(info)))
             print((response.pretty_print()))
 
         except KeyboardInterrupt:
@@ -173,7 +173,7 @@ class CoapClient():
             client.stop()
         client.stop()
 
-    def mkJsonRasbpgraphInfo(self, info):
+    def mkJsonRpgraphInfo(self, info):
         n = 2.2
         print(info)
         distance = math.pow(10, ((float(info[4]) - float(info[5])) / (10 * n)))
diff --git a/Server_CoAP/CoAPthon3/coapserver.py b/Server_CoAP/CoAPthon3/coapserver.py
index 373183a..66995cf 100644
--- a/Server_CoAP/CoAPthon3/coapserver.py
+++ b/Server_CoAP/CoAPthon3/coapserver.py
@@ -3,24 +3,102 @@ import getopt
 import sys
 import threading
 import _thread
+import time
+import datetime
+import json
 from coapthon.server.coap import CoAP
-from exampleresources import BleInfoResource, RasbpNodeInfoResource, RasbpGraphInfoResource
-
+from exampleresources import BleInfoResource, RpNodeInfoResource, RpGraphInfoResource
+from pymongo import MongoClient
 
 class CoAPServer(CoAP):
     def __init__(self, host, port, multicast=False):
         CoAP.__init__(self, (host, port), multicast)
         self.add_resource('bleInfoPath/', BleInfoResource())
-        self.add_resource('rasbpNodeInfoPath/', RasbpNodeInfoResource())
-        self.add_resource('rasbpGraphInfoPath/', RasbpGraphInfoResource())
+        self.add_resource('rpNodeInfoPath/', RpNodeInfoResource())
+        self.add_resource('rpGraphInfoPath/', RpGraphInfoResource())
 
         print(("CoAP Server start on " + host + ":" + str(port)))
         print((self.root.dump()))
 
+        try:
+            self.conn = MongoClient('mongodb://iotuser:iotsystem@localhost/IoT_System', 27017)
+            self.db = self.conn.IoT_System
+            self.piNodeCollection = self.db.RpNodeData
+            self.userNodeCollection = self.db.UserNodeData
+            self.trackingCollection = self.db.TrackingData
+            self.usersCollection = self.db.users
+        except:
+            print("Could not connect to MongoDB")
+
     def updateUserLocation(self):
-        
-        pass
+        try:
+            while True:
+                cursor = self.usersCollection.find()
+                for c in cursor:
+                    positionCalculationThread = threading.Thread(target = self.positionCalculation, args=([c['uuid']]))
+                    positionCalculationThread.start()
+                time.sleep(3)
+        except KeyboardInterrupt:
+            print("existing updateUserLocation")
+    
+    def positionCalculation(self, useruuid):
+        currentTime = time.time()
+        """
+        trackingCursor = self.trackingCollection.find({'$and':[{'useruuid':{'$eq' : useruuid}},
+        {'updateTime':{'$gt' : currentTime - 3}}]})
+        실제 코드, 밑에는 테스트용 코드
+        """
+        trackingCursor = self.trackingCollection.find({'$and':[{'useruuid':{'$eq' : useruuid}}]})
+        userLocationData =[]
+
+        flag = 0
+        for c in trackingCursor:
+            for i in userLocationData:
+                if i['rpuuid'] == c['rpuuid']:
+                    i['sum']+= c['distance']
+                    i['count']+=1
+                    i['distance'] = i['sum']/i['count']
+                    flag = 1
+                    break
+            if flag == 0:
+                userLocationData.append({
+                    'rpuuid': c['rpuuid'],
+                    'distance': c['distance'],
+                    'sum': c['distance'],
+                    'count':1
+                })
+            flag = 0
+
+        userLocationData = sorted(userLocationData, key=lambda k: k['distance'], reverse = False)
+
+        if len(userLocationData) < 3:
+            return
+
+        node = []
+        for i in range(3):
+            node.append({
+                'x': piNodeCollection.find({'rpuuid': userLocationData[i]['rpuuid']})[i]['x'],
+                'y': piNodeCollection.find({'rpuuid': userLocationData[i]['rpuuid']})[i]['y'],
+                'distance': userLocationData[i]['distance']
+            })
+
+        triangulationInst = triangulation.Triangulation(node[:3])
+        x, y = triangulation.doTriangulation()
+
+        if(x == null)
+            return
 
+        dd = datetime.datetime.now()
+        dd = dd.replace(hour=dd.hour + 9)
+        userNodeData = {
+            'rpuuid': userLocationData[0]['rpuuid'],
+            'useruuid': useruuid,
+            'x': x,
+            'y': y,
+            'updateTime': str(dd)
+        }
+        print(userNodeData)
+        self.userNodeCollection.insert_one(userNodeData)
 
 def usage():  # pragma: no cover
     print("coapserver.py -i <ip address> -p <port>")
diff --git a/Server_CoAP/CoAPthon3/exampleresources.py b/Server_CoAP/CoAPthon3/exampleresources.py
index cffc127..7945e9c 100644
--- a/Server_CoAP/CoAPthon3/exampleresources.py
+++ b/Server_CoAP/CoAPthon3/exampleresources.py
@@ -1,17 +1,19 @@
 import json
 import uuid
+import math
+import triangulation
 from pymongo import MongoClient
 from coapthon import defines
 from coapthon.resources.resource import Resource
 
-class RasbpNodeInfoResource(Resource):
-    def __init__(self, name="RasbpNodeInfo"):
-        super(RasbpNodeInfoResource, self).__init__(name)
-        self.payload = "RasbpNodeInfo resource"
+class RpNodeInfoResource(Resource):
+    def __init__(self, name="RpNodeInfo"):
+        super(RpNodeInfoResource, self).__init__(name)
+        self.payload = "RpNodeInfo resource"
         try:
             self.conn = MongoClient('mongodb://iotuser:iotsystem@localhost/IoT_System', 27017)
             self.db = self.conn.IoT_System
-            self.collection = self.db.RasbpNodeData
+            self.collection = self.db.RpNodeData
         except:
             print("Could not connect to MongoDB")
 
@@ -23,7 +25,7 @@ class RasbpNodeInfoResource(Resource):
         if self.payload['option'] == 1:
             self.calculateNodePosition(sefl.payload)
         else :
-            response.payload = self.postRasbpNodeInfoInDB(self.payload)
+            response.payload = self.postRpNodeInfoInDB(self.payload)
         response.code = defines.Codes.CREATED.number
         return self, response
 
@@ -35,69 +37,114 @@ class RasbpNodeInfoResource(Resource):
         if self.payload['option'] == 1:
             self.calculateNodePosition(self.payload)
         else :
-            response.payload = self.postRasbpNodeInfoInDB(self.payload)
+            response.payload = self.postRpNodeInfoInDB(self.payload)
         response.code = defines.Codes.CHANGED.number
         return self, response
 
-    def postRasbpNodeInfoInDB(self, info):
+    def postRpNodeInfoInDB(self, info):
         info = info['myMAC']
-        self.collection.delete_many({ 'rasbpMAC' : info })
-        ruuid = "52528282"+str(uuid.uuid4())[8:]
-        ruuid = ruuid.replace("-","")
+        self.collection.delete_many({ 'rpMAC' : info })
+        rpuuid = "52528282"+str(uuid.uuid4())[8:]
+        rpuuid = rpuuid.replace("-","")
         if self.collection.count() == 0:
             payload = {
-                'rasbpMAC' : info,
-                'uuid' : ruuid
+                'rpMAC' : info,
+                'rpuuid' : rpuuid
             }
             self.collection.insert_one(payload)
 
             response = json.dumps({
-                'uuid' : ruuid,
+                'rpuuid' : rpuuid,
                 'operate' : 0
             })
         else:
             payload = {
-                'rasbpMAC' : info,
-                'uuid' : ruuid,
+                'rpMAC' : info,
+                'rpuuid' : rpuuid
             }
             self.collection.insert_one(payload)
 
             response = json.dumps({
-                'uuid' : ruuid,
+                'rpuuid' : rpuuid,
                 'operate' : 1
             })
         return response
 
     def calculateNodePosition(self, info):
         print("Start calculateNodePosition")
-        info = info['myuuid']
-        graphColletion = self.db.RasbpGraphData
-        mydoc = self.collection.find({'uuid': info})
-            if mydoc.count() == 1:
-                if self.collection.count() == 1:
-                    pass
-                else if self.collection.count() == 2:
-                    pass
-                else if self.collection.count() == 3:
-                    pass
-                else:
-                    pass
-
-            else :
-                print("This is not registered Node")
+        info = info['rpuuid']
+        graphColletion = self.db.RpGraphData
+        mydoc = self.collection.find({'rpuuid': info})
+        if mydoc.count() == 1:
+            if self.collection.count() == 1:
+                self.collection.update({'rpuuid' : info}, {'$set':{'x': 0.0, 'y': 0.0}}, False)
+            elif self.collection.count() == 2:
+                graphB = graphColletion.find({'v2': info})
+                x = graphB[0]['distance']
+                self.collection.update({'rpuuid' : info}, {'$set':{'x': x, 'y': 0.0}}, False)
+            elif self.collection.count() == 3:
+                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:
+                        vertexA = tempdoc[0]
+                    vertexB = tempdoc[0]
+                dis = {
+                    'a': graphColletion.find({'v1': vertexB[0][rpuuid], 'v2': info})[0]['distance'],
+                    'b': graphColletion.find({'v1': vertexA[0][rpuuid], 'v2': info})[0]['distance'],
+                    'c': vertexB[0]['x']
+                }
+                cosA = (math.pow(dis['b'], 2) + math.pow(dis['c'], 2) - math.pow(dis['a'], 2))
+                / (2 * dis['b'] * dis['c'])
+                sinA = math.sqrt((1 - math.pow(cosA,2)))
+                x = b * cosA
+                y = b * sinA
+                self.collection.update({'rpuuid' : info}, {'$set':{'x': x, 'y': y}}, False)
+            else:
+                graphD = graphColletion.find({'v2' : info})
+                nodeLocationData = []
+
+                for g in graphD:
+                    nodeLocationData.append({
+                    'rpuuid': g['v1'],
+                    'distance': g['distance']
+                })
+
+                nodeLocationData = sorted(nodeLocationData, key=lambda k: k['distance'], reverse = False)
+
+                if len(nodeLocationData) < 3:
+                    return
+
+                node = []
+                for i in range(3):
+                    node.append({
+                        'x': piNodeCollection.find({'rpuuid': nodeLocationData[i]['rpuuid']})[i]['x'],
+                        'y': piNodeCollection.find({'rpuuid': nodeLocationData[i]['rpuuid']})[i]['y'],
+                        'distance': nodeLocationData[i]['distance']
+                    })
+
+                triangulationInst = triangulation.Triangulation(node[:3])
+                x, y = triangulation.doTriangulation()
+
+                if(x == null)
+                    return
+
+                self.collection.update({'rpuuid' : info}, {'$set':{'x': x, 'y': y}}, False)
+                else :
+                    print("This is not registered Node")
+                
         
 
-class RasbpGraphInfoResource(Resource):
-    def __init__(self, name="RasbpGraphInfo"):
-        super(RasbpGraphInfoResource, self).__init__(name)
-        self.payload = "RasbpGraphInfo resource"
-        
+class RpGraphInfoResource(Resource):
+    def __init__(self, name="RpGraphInfo"):
+        super(RpGraphInfoResource, self).__init__(name)
+        self.payload = "RpGraphInfo resource"
         try:
             self.conn = MongoClient('mongodb://iotuser:iotsystem@localhost/IoT_System', 27017)
         except:
             print("Could not connect to MongoDB")
         self.db = self.conn.IoT_System
-        self.collection = self.db.RasbpGraphData
+        self.collection = self.db.RpGraphData
         
     def render_GET_advanced(self, request, response):
         response.payload = self.payload
@@ -109,7 +156,7 @@ class RasbpGraphInfoResource(Resource):
         self.payload = request.payload
         from coapthon.messages.response import Response
         assert(isinstance(response, Response))
-        response.payload = self.postRasbpGraphInfoInDB(self.payload)
+        response.payload = self.postRpGraphInfoInDB(self.payload)
         response.code = defines.Codes.CREATED.number
         return self, response
 
@@ -117,7 +164,7 @@ class RasbpGraphInfoResource(Resource):
         self.payload = request.payload
         from coapthon.messages.response import Response
         assert(isinstance(response, Response))
-        response.payload = self.postRasbpGraphInfoInDB(self.payload)
+        response.payload = self.postRpGraphInfoInDB(self.payload)
         response.code = defines.Codes.CHANGED.number
         return self, response
 
@@ -126,7 +173,7 @@ class RasbpGraphInfoResource(Resource):
         response.code = defines.Codes.DELETED.number
         return True, response
 
-    def postRasbpGraphInfoInDB(self, info):
+    def postRpGraphInfoInDB(self, info):
         info = json.loads(info)
         mydoc = self.collection.find({'v1':info['v1'], 'v2':info['v2']})
         if mydoc.count() > 0:
diff --git a/Server_CoAP/triangulation.py b/Server_CoAP/CoAPthon3/triangulation.py
similarity index 100%
rename from Server_CoAP/triangulation.py
rename to Server_CoAP/CoAPthon3/triangulation.py
diff --git a/Server_Vue_Express/backend/models/rpNodeData.js b/Server_Vue_Express/backend/models/rpNodeData.js
new file mode 100644
index 0000000..f37b168
--- /dev/null
+++ b/Server_Vue_Express/backend/models/rpNodeData.js
@@ -0,0 +1,17 @@
+var mongoose = require('mongoose');
+const Schema = mongoose.Schema;
+ 
+const rpNodeDataSchema = new Schema({
+    rpMAC: { type: String, default: ""  },
+    rpuuid: { type: String, default: ""  },
+    x:{ type: Number, default: 0 },
+    y:{ type: Number, default: 0 },
+    type : { type: String, default: ""  }
+}, { collection : 'RpNodeData', // 컬렉션명 지정 
+    versionKey : false, // "__v" 필드 생성X 
+    strict : false }
+);
+ 
+
+//users collection
+module.exports = mongoose.model('RpNodeData', rpNodeDataSchema);
\ No newline at end of file
diff --git a/Server_Vue_Express/backend/models/userNode.js b/Server_Vue_Express/backend/models/userNode.js
new file mode 100644
index 0000000..448fdde
--- /dev/null
+++ b/Server_Vue_Express/backend/models/userNode.js
@@ -0,0 +1,17 @@
+var mongoose = require('mongoose');
+const Schema = mongoose.Schema;
+ 
+const userNodeSchema = new Schema({
+    rasbpID: { type: String, default: ""  },
+    useruuid: { type: String, default: ""  },
+    x:{ type: Number, default: 0 },
+    y:{ type: Number, default: 0 },
+    updateTime : { type: String, default: ""  }
+}, { collection : 'UserNodeData', // 컬렉션명 지정 
+    versionKey : false, // "__v" 필드 생성X 
+    strict : false }
+);
+ 
+
+//users collection
+module.exports = mongoose.model('UserNodeData', userNodeSchema);
\ No newline at end of file
diff --git a/Server_Vue_Express/backend/public/chart.js b/Server_Vue_Express/backend/public/chart.js
new file mode 100644
index 0000000..d461cc0
--- /dev/null
+++ b/Server_Vue_Express/backend/public/chart.js
@@ -0,0 +1,70 @@
+
+var data = {
+    labels: [
+        "1", "2", "3", "4", "5"
+    ],
+    datasets: [
+        
+    ]
+};
+
+
+var dat = {
+	
+}
+var options = {
+    animation: {
+        animateScale: false
+    },
+    responsive: false,
+    scales: {
+        yAxes: [
+            {
+                ticks: {
+                    //max:30,
+                    beginAtZero: true                                                                    
+                }
+            }
+        ],
+            xAxes: [
+            {
+                ticks: {
+                    //max:20,
+                    beginAtZero: true                                                                    
+                }
+            }
+        ]
+    }
+};
+var ctx = document.getElementById("myChart").getContext('2d');                                           
+var myBarChart = new Chart(ctx, {
+    type: 'bubble',
+    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 copy.js b/Server_Vue_Express/backend/routes/api copy.js
new file mode 100644
index 0000000..0545192
--- /dev/null
+++ b/Server_Vue_Express/backend/routes/api copy.js	
@@ -0,0 +1,76 @@
+var express = require('express');
+var router = express.Router();
+var uuidv1 = require('uuid/v1');
+var User = require('../models/users');
+var Tracking = require('../models/tracking');
+
+/*
+var User = require('../models/users');
+var user = new User({
+  name: "NodeJS Tutorialaaaaa",
+  token: "velopert",
+  uuid:"asdf"
+});
+user.save(function(err, user){
+  if(err) return console.error(err);
+  console.dir(user);
+});
+
+*/
+
+
+
+/* POST CreateNewUser page. */
+router.post('/CreateNewUser', function(req, res, next) {
+  var uuid = uuidv1()
+  
+  var user = new User({
+    name: req.body.name,
+    aID: req.body.aID,
+    uuid:uuid
+  });
+  user.save(function(err, user){
+    if(err) return console.error(err);
+    console.dir(user);
+  });
+  res.send({
+    name: req.body.name,
+    aID: req.body.aID,
+    uuid:uuid
+  });
+});
+
+
+/* Delete User page. */
+router.post('/DeleteUser', function(req, res) {
+  aID  = req.body.aID
+  User.deleteMany({ aID: req.body.aID }, function(err, output){
+    if(err) return res.status(500).json({ error: "database failure" });
+
+    // ( SINCE DELETE OPERATION IS IDEMPOTENT, NO NEED TO SPECIFY )
+    //if(!output.result.n) return res.status(404).json({ error: "user not found" });
+    //res.json({ message: "user deleted" });
+    res.json({message: output, res : req.body});
+  })
+});
+
+
+router.post('/findByUUID', function(req, res) {
+  uuid  = req.body.uuid
+  
+  Tracking.find({uuid:req.body.uuid}, function(err, output){
+    if(err) return res.status(500).json({ error: "database failure" });
+
+    // ( SINCE DELETE OPERATION IS IDEMPOTENT, NO NEED TO SPECIFY )
+    //if(!output.result.n) return res.status(404).json({ error: "user not found" });
+    //res.json({ message: "user deleted" });
+
+    res.json({message: output, res : req.body});
+  })
+});
+
+router.post('/', function(req, res, next) {
+  console.log(req.body)
+  res.render('index', { title: 'Express' });
+});
+module.exports = router;
diff --git a/Server_Vue_Express/backend/routes/api.js b/Server_Vue_Express/backend/routes/api.js
index 0545192..5e43568 100644
--- a/Server_Vue_Express/backend/routes/api.js
+++ b/Server_Vue_Express/backend/routes/api.js
@@ -3,7 +3,8 @@ var router = express.Router();
 var uuidv1 = require('uuid/v1');
 var User = require('../models/users');
 var Tracking = require('../models/tracking');
-
+var UserNode = require('../models/userNode');
+var rpNode = require('../models/rpNodeData');
 /*
 var User = require('../models/users');
 var user = new User({
@@ -17,7 +18,7 @@ user.save(function(err, user){
 });
 
 */
-
+console.log("aaaa")
 
 
 /* POST CreateNewUser page. */
@@ -69,6 +70,65 @@ router.post('/findByUUID', function(req, res) {
   })
 });
 
+router.get('/findUserByUUID/:id', function(req, res, next) {
+  var userData=new Array();
+  var data =new Array();
+  var UserName = "";
+  var UserLocation =[];
+  var rpNodeData=[];
+  //console.log("kkkk")
+  (async () => {
+    try{
+      await User.find({uuid:req.params.id}, (err,output)=>{
+        //res.json(output);
+        console.log(output[0].name)
+        userData.push({name:output[0].name})
+        UserName = output[0].name;
+      })
+      await User.find({uuid:req.params.id}, (err,output)=>{
+        //res.json(output);
+        console.log(output[0].name)
+        userData.push({name:output[0].name})
+        UserName = output[0].name;
+      })
+      await UserNode.find({useruuid:req.params.id}, (err,output)=>{
+        //res.json(output);
+        try{
+          UserLocation ={
+            x:output[0].x, 
+            y:output[0].y,
+            r:10
+          }
+          userData.push({
+            x:output[0].x, 
+            y:output[0].y,
+            updateTime:output[0].updateTime,
+          })
+        }catch(exception){}
+      })
+
+      await rpNode.find((err,output) =>{
+        rpNodeData = output;
+        console.log("tt",JSON.stringify(rpNodeData));
+      })
+    }
+    catch(exception){
+      console.log(exception)
+    }
+
+    res.render('index',{title:'Express',UserName:UserName ,UserLocation: UserLocation, rpNodeData:JSON.stringify(rpNodeData)})
+  })();
+});
+
+
+router.get('/users', function(req, res, next) {
+  User.find((err,output) =>{
+    console.log(output);
+    res.render('users', { data: output });
+  })
+  
+});
+
 router.post('/', function(req, res, next) {
   console.log(req.body)
   res.render('index', { title: 'Express' });
diff --git a/Server_Vue_Express/backend/views/index.pug b/Server_Vue_Express/backend/views/index.pug
index 3d63b9a..ece03bd 100644
--- a/Server_Vue_Express/backend/views/index.pug
+++ b/Server_Vue_Express/backend/views/index.pug
@@ -1,5 +1,56 @@
 extends layout
 
 block content
-  h1= title
-  p Welcome to #{title}
+  p #{UserLocation.x}, #{UserLocation.y}
+  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")
+  script(type='text/javascript').
+    console.log(data);
+    try{
+      data.datasets.push({
+            label: '#{UserName}',
+            data: [
+              {
+                x: #{UserLocation.x},
+                y: #{UserLocation.y},
+                r:10,
+              }
+            ],
+            backgroundColor: [                                                              
+                'rgba(255, 159, 64, 0.2)'
+            ],
+            borderColor: [
+                'rgba(255, 159, 64, 1)'
+            ],
+            borderWidth: 1
+        });
+        var t = [];
+
+        const nodeData = JSON.parse(`#{rpNodeData}`.replace(/&quot;/g, '"'));
+        
+        for(i in nodeData){
+          t.push({
+            x: nodeData[i].x,
+            y: nodeData[i].y,
+            r: 5
+          })
+          
+        }
+        console.log(t)
+        data.datasets.push({
+            label: 'RPi',
+            data: t,
+            backgroundColor: [
+                'rgba(255, 99, 132, 0.2)',
+            ],
+            borderColor: [
+                'rgba(255,99,132,1)',
+            ],
+            borderWidth: 1
+        });
+    }
+    catch (exception){
+      console.log(exception);
+    }
+    myBarChart.update();
\ No newline at end of file
diff --git a/Server_Vue_Express/backend/views/layout.pug b/Server_Vue_Express/backend/views/layout.pug
index 15af079..e39a995 100644
--- a/Server_Vue_Express/backend/views/layout.pug
+++ b/Server_Vue_Express/backend/views/layout.pug
@@ -5,3 +5,4 @@ html
     link(rel='stylesheet', href='/stylesheets/style.css')
   body
     block content
+    
\ No newline at end of file
diff --git a/Server_Vue_Express/backend/views/users.pug b/Server_Vue_Express/backend/views/users.pug
new file mode 100644
index 0000000..e09b850
--- /dev/null
+++ b/Server_Vue_Express/backend/views/users.pug
@@ -0,0 +1,10 @@
+extends layout
+
+block content
+  hr(size='3px')
+  p
+    - let i=0;
+    for i in data
+      a(href='/api/findUserByUUID/'+i.uuid) #{i.name} , uuid:#{i.uuid}
+      br
+      -i++
\ No newline at end of file
-- 
GitLab