From 6164174a1b0d681d3840b9dd43c0f32a00227650 Mon Sep 17 00:00:00 2001
From: nsc <skdiakffn@ajou.ac.kr>
Date: Sat, 7 Dec 2019 15:09:55 +0900
Subject: [PATCH] revise

---
 RPi_Client/CoAPthon3/coapclient.py        |   5 +-
 Server_CoAP/CoAPthon3/coapserver.py       | 206 +++++++++++++++-------
 Server_CoAP/CoAPthon3/dbClear.py          |   1 +
 Server_CoAP/CoAPthon3/exampleresources.py |  79 +++++----
 4 files changed, 192 insertions(+), 99 deletions(-)

diff --git a/RPi_Client/CoAPthon3/coapclient.py b/RPi_Client/CoAPthon3/coapclient.py
index 2b815b3..42b4af3 100644
--- a/RPi_Client/CoAPthon3/coapclient.py
+++ b/RPi_Client/CoAPthon3/coapclient.py
@@ -114,10 +114,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("impossible postision calculation")
             
         except KeyboardInterrupt:
             print("obtainMyID Stop")
diff --git a/Server_CoAP/CoAPthon3/coapserver.py b/Server_CoAP/CoAPthon3/coapserver.py
index bea544b..d0afea2 100644
--- a/Server_CoAP/CoAPthon3/coapserver.py
+++ b/Server_CoAP/CoAPthon3/coapserver.py
@@ -26,6 +26,7 @@ class CoAPServer(CoAP):
             self.db = self.conn.IoT_System
             self.piNodeCollection = self.db.RpNodeData
             self.userNodeCollection = self.db.UserNodeData
+            self.personNodeCollection = self.db.PersonNodeData
             self.trackingCollection = self.db.TrackingData
             self.usersCollection = self.db.users
             self.updatePeriod = 5
@@ -33,29 +34,77 @@ class CoAPServer(CoAP):
         except:
             print("Could not connect to MongoDB")
 
-    def updateUserLocation(self): # complete
+    def deleteLocationHalfHour(self):
         try:
+            timeFlag = 1
             while True:
-                cursor = self.usersCollection.find()
+                dd = datetime.datetime.utcnow()
+                if ((dd.minute == 0 and dd.second == 0) or (dd.minute == 30 and dd.second == 0)) and timeFlag == 0:
+                    deleteLocationThread = threading.Thread(target = self.deleteLocation)
+                    deleteLocationThread.start()
+                    timeFlag = 1
+                if dd.minute < 30 and timeFlag == 1:
+                    time.sleep((29 - dd.minute) * 60 + (59 - dd.second))
+                    timeFlag = 0
+                if dd.minute > 30 and timeFlag == 1:
+                    time.sleep((59 - dd.minute) * 60 + (59 - dd.second))
+
+        except KeyboardInterrupt:
+            print("existing deleteLocation")
+
+    def deleteLocation(self):
+        d = datetime.datetime.utcnow()
+        dd = replplace(sencond = 0)
+
+        cursor1 = self.personNodeCollection.find({'$and' : [{'updateTime' : {'$lt' : dd}},{'type' : 'current'}]}).sort('updateTime', 1)
+        cursor2 = self.userNodeCollection.find({'$and' : [{'updateTime' : {'$lt' : dd}},{'type' : 'current'}]}).sort('updateTime', 1)
+        temp = []
+        for c in cursor1:
+            if not c['useruuid'] in temp:
+                temp.append(c['useruuid'])
+                self.personNodeCollection.update_one({'_id' : c['_id']}, {'$set': {'type' : 'past'}}, False)
+
+        temp = []
+        for c in cursor2:
+            if not c['useruuid'] in temp:
+                temp.append(c['useruuid'])
+                self.personNodeCollection.update_one({'_id' : c['_id']}, {'$set': {'type' : 'past'}}, False)
+
+        self.personNodeCollection.delete_many({'$and' : [{'updateTime' : {'$lt' : dd}}, {'type': 'current'}]})
+        self.userNodeCollection.delete_many({'$and' : [{'updateTime' : {'$lt' : dd}}, {'type': 'current'}]})
+
+    def updateLocation(self): # complete
+        try:
+            while True:
+                currentTime = time.time()
+                cursor = self.trackingCollection.find()
+                temp = []
                 for c in cursor:
-                    positionCalculationThread = threading.Thread(target = self.positionCalculation, args=([c['uuid']]))
-                    positionCalculationThread.start()
+                    if not c['useruuid'] in temp:
+                        temp.append(c['useruuid'])
+                        positionCalculationThread = threading.Thread(target = self.positionCalculation, args=([c['useruuid']]))
+                        positionCalculationThread.start()
                 time.sleep(self.updatePeriod)
-                #trackingCursor = self.trackingCollection.remove({'updateTime': {'$lte' : currentTime - self.updatePeriod}})
+                trackingCursor = self.trackingCollection.delete_many({'updateTime': {'$lt' : currentTime}})
         except KeyboardInterrupt:
-            print("existing updateUserLocation")
+            print("existing updateLocation")
     
     def positionCalculation(self, useruuid): # complete but need to check triangulation.py
-        print(useruuid)
         currentTime = time.time()
         trackingCursor = self.trackingCollection.find({'$and':[{'useruuid': useruuid},
-        {'updateTime':{'$gt' : currentTime - self.updatePeriod}},{'distance': {'$lt' : self.limitDistance}}]})
-        #trackingCursor = self.trackingCollection.find({'$and':[{'useruuid':{'$eq' : useruuid}}]})
-        userLocationData =[]
-
+        {'updateTime':{'$gte' : currentTime - self.updatePeriod}},{'distance': {'$lt' : self.limitDistance}}]})
+        userCursor = self.userNodeCollection.find()
+        locationData =[]
         flag = 0
+        userFlag = 0
+
+        for c in userCursor:
+            if useruuid == c['uuid']:
+                userFlag = 1
+                break
+
         for c in trackingCursor:
-            for i in userLocationData:
+            for i in locationData:
                 if i['rpuuid'] == c['rpuuid']:
                     i['sum']+= c['distance']
                     i['count']+=1
@@ -63,7 +112,7 @@ class CoAPServer(CoAP):
                     flag = 1
                     break
             if flag == 0:
-                userLocationData.append({
+                locationData.append({
                     'rpuuid': c['rpuuid'],
                     'distance': c['distance'],
                     'sum': c['distance'],
@@ -71,69 +120,96 @@ class CoAPServer(CoAP):
                 })
             flag = 0
 
-        userLocationData = sorted(userLocationData, key=lambda k: k['distance'], reverse = False)
-        for u in userLocationData:
-            print(userLocationData)
+        locationData = sorted(locationData, key=lambda k: k['distance'], reverse = False)
+        for u in locationData:
+            print(locationData)
         
-        if len(userLocationData) == 0:
-            print("userLocationData == 0")
+        if len(locationData) == 0:
+            print("locationData == 0")
             return
         
-        rp1uuid = userLocationData[0]['rpuuid']
+        rp1uuid = locationData[0]['rpuuid']
         rp1 = self.piNodeCollection.find({'rpuuid' : rp1uuid})
 
-        if len(userLocationData) < 3:
-            print("userLocationData < 3")
-            dd = datetime.datetime.now()
-            userNodeData = {
-                'rp1': {'rpuuid' : userLocationData[0]['rpuuid'], 'distance': userLocationData[0]['distance']},
+        if rp1[0]['type'] == 0:
+            print("rpNode don't have position")
+            dd = datetime.datetime.utcnow()
+            nodeData = {
+                'rp1': {'rpuuid' : locationData[0]['rpuuid'], 'distance': locationData[0]['distance']},
+                'useruuid': useruuid,
+                'updateTime': str(dd)
+            }
+            print(nodeData)
+            if userFlag == 1:
+                self.userNodeCollection.insert_one(nodeData)
+                self.personNodeCollection.insert_one(nodeData)
+            else :
+                self.personNodeCollection.insert_one(nodeData)
+            return
+
+        if len(locationData) < 3:
+            print("locationData < 3")
+            dd = datetime.datetime.utcnow()
+            nodeData = {
+                'rp1': {'rpuuid' : locationData[0]['rpuuid'], 'distance': locationData[0]['distance']},
                 'useruuid': useruuid,
                 'x' : rp1[0]['x'],
                 'y' : rp1[0]['y'],
                 'updateTime': str(dd)
             }
-            print(userNodeData)
-            self.userNodeCollection.insert_one(userNodeData)
+            print(nodeData)
+            if userFlag == 1:
+                self.userNodeCollection.insert_one(nodeData)
+                self.personNodeCollection.insert_one(nodeData)
+            else :
+                self.personNodeCollection.insert_one(nodeData)
             return
-
-        else :
-            nodeList = []
-            for i in range(3):
-                nodeList.append({
-                    'x': self.piNodeCollection.find({'rpuuid': userLocationData[i]['rpuuid']})[0]['x'],
-                    'y': self.piNodeCollection.find({'rpuuid': userLocationData[i]['rpuuid']})[0]['y'],
-                    'distance': userLocationData[i]['distance']
-                })
-
-            triangulationInst = triangulation.Triangulation(nodeList[:3])
-            x, y = triangulationInst.doTriangulation()
-
-            if x == None:
-                print("no solution")
-                dd = datetime.datetime.now()
-                userNodeData = {
-                    'rp1': {'rpuuid' : userLocationData[0]['rpuuid'], 'distance': userLocationData[0]['distance']},
-                    'useruuid': useruuid,
-                    'x': rp1[0]['x'],
-                    'y': rp1[0]['y'],
-                    'updateTime': str(dd)
-                }
-                print(userNodeData)
-                self.userNodeCollection.insert_one(userNodeData)
-                return
-
-            dd = datetime.datetime.now()
-            userNodeData = {
-                'rp1': {'rpuuid' : userLocationData[0]['rpuuid'], 'distance': userLocationData[0]['distance']},
-                'rp2': {'rpuuid' : userLocationData[1]['rpuuid'], 'distance' : userLocationData[1]['distance']},
-                'rp3': {'rpuuid' : userLocationData[2]['rpuuid'], 'distance' : userLocationData[2]['distance']},
+    
+        nodeList = []
+        for i in range(3):
+            nodeList.append({
+                'x': self.piNodeCollection.find({'rpuuid': locationData[i]['rpuuid']})[0]['x'],
+                'y': self.piNodeCollection.find({'rpuuid': locationData[i]['rpuuid']})[0]['y'],
+                'distance': locationData[i]['distance']
+            })
+
+        triangulationInst = triangulation.Triangulation(nodeList[:3])
+        x, y = triangulationInst.doTriangulation()
+
+        if x == None:
+            print("no solution")
+            dd = datetime.datetime.utcnow()
+            nodeData = {
+                'rp1': {'rpuuid' : locationData[0]['rpuuid'], 'distance': locationData[0]['distance']},
                 'useruuid': useruuid,
-                'x': x,
-                'y': y,
+                'x': rp1[0]['x'],
+                'y': rp1[0]['y'],
                 'updateTime': str(dd)
             }
-            print(userNodeData)
-        self.userNodeCollection.insert_one(userNodeData)
+            print(nodeData)
+            if userFlag == 1:
+                self.userNodeCollection.insert_one(nodeData)
+                self.personNodeCollection.insert_one(nodeData)
+            else :
+                self.personNodeCollection.insert_one(nodeData)
+            return
+
+        dd = datetime.datetime.utcnow()
+        nodeData = {
+            'rp1': {'rpuuid' : locationData[0]['rpuuid'], 'distance': locationData[0]['distance']},
+            'rp2': {'rpuuid' : locationData[1]['rpuuid'], 'distance' : locationData[1]['distance']},
+            'rp3': {'rpuuid' : locationData[2]['rpuuid'], 'distance' : locationData[2]['distance']},
+            'useruuid': useruuid,
+            'x': x,
+            'y': y,
+            'updateTime': str(dd)
+        }
+        print(nodeData)
+        if userFlag == 1:
+            self.userNodeCollection.insert_one(nodeData)
+            self.personNodeCollection.insert_one(nodeData)
+        else :
+            self.personNodeCollection.insert_one(nodeData)
 
 def usage():  # pragma: no cover
     print("coapserver.py -i <ip address> -p <port>")
@@ -161,8 +237,10 @@ def main(argv):  # pragma: no cover
 
     server = CoAPServer(ip, port, multicast)
     try:
-        updateUserLocationThread = threading.Thread(target = server.updateUserLocation)
-        updateUserLocationThread.start()
+        updateLocationThread = threading.Thread(target = server.updateLocation)
+        updateLocationThread.start()
+        deleteLocationHalfHourThread = threading.Thread(target = server.deleteLocationHalfHour)
+        deleteLocationHalfHourThread.start()
         server.listen(10)
 
     except KeyboardInterrupt:
diff --git a/Server_CoAP/CoAPthon3/dbClear.py b/Server_CoAP/CoAPthon3/dbClear.py
index 89141dc..3c60299 100644
--- a/Server_CoAP/CoAPthon3/dbClear.py
+++ b/Server_CoAP/CoAPthon3/dbClear.py
@@ -1,4 +1,5 @@
 from pymongo import MongoClient
+import json
 
 class MyMongoDB():
     def __init__(self): #문제 없음.
diff --git a/Server_CoAP/CoAPthon3/exampleresources.py b/Server_CoAP/CoAPthon3/exampleresources.py
index f568f26..05154b5 100644
--- a/Server_CoAP/CoAPthon3/exampleresources.py
+++ b/Server_CoAP/CoAPthon3/exampleresources.py
@@ -93,42 +93,57 @@ class RpNodeInfoResource(Resource):
         }
         if mydoc.count() == 1: # 자기 자신이 RpNodeData에 있는 경우
             if self.collection.count() == 1: # 자신이 첫번째 RpNode인 경우
-                self.collection.update({'rpuuid' : info}, {'$set':{'x': 0.0, 'y': 0.0}}, False)
+                self.collection.update({'rpuuid' : info}, {'$set':{'x': 0.0, 'y': 0.0, 'type' : 1}}, False)
             elif self.collection.count() == 2: # 자신이 두번째 RpNode인 경우
                 graphB = graphColletion.find({'v2': info})
-                x = graphB[0]['distance']
-                self.collection.update({'rpuuid' : info}, {'$set':{'x': x, 'y': 0.0}}, False)
+                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)
             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'] = 0
+                        self.collection.update({'rpuuid' : info}, {'$set' : {'type' : 0}}, False)
+                        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'] = 0
+                        self.collection.update({'rpuuid' : info}, {'$set' : {'type' : 0}}, False)
+                        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, 'tpye' : 0}}, False)
             else:
                 graphD = graphColletion.find({'v2' : info})
                 nodeLocationData = []
@@ -145,6 +160,7 @@ class RpNodeInfoResource(Resource):
                     # 4번째 이상의 rpNode를 만들 수 없는 경우
                     print("4번째 이상의 rpNode를 만들 수 없습니다.")
                     response['operate'] = 0
+                    self.collection.update({'rpuuid' : info}, {'$set' : {'type' : 0}}, False)
                     return json.dumps(response)
 
                 nodeList = []
@@ -165,9 +181,10 @@ class RpNodeInfoResource(Resource):
                     # 4번째 이상의 rpNode를 만들 수 없는 경우
                     print("4번째 이상의 rpNode를 만들 수 없습니다.")
                     response['operate'] = 0
+                    self.collection.update({'rpuuid' : info}, {'$set' : {'type' : 0}}, False)
                     return json.dumps(response)
 
-                self.collection.update({'rpuuid' : info}, {'$set':{'x': x, 'y': y}}, False)
+                self.collection.update({'rpuuid' : info}, {'$set':{'x': x, 'y': y, 'type' : 1}}, False)
 
             return json.dumps(response)
         else:
-- 
GitLab