From e275126f439fac96975a0506346fa7cca2aefd76 Mon Sep 17 00:00:00 2001
From: "Server (Shared Users)" <shmd01.iptime.org>
Date: Tue, 26 Nov 2019 15:17:37 +0000
Subject: [PATCH] final of middle output....

---
 RPi_Client/CoAPthon3/coapclient.py        | 58 ++++++++++++----
 Server_CoAP/CoAPthon3/coapserver.py       |  8 +--
 Server_CoAP/CoAPthon3/exampleresources.py | 81 +++++++++++++++--------
 3 files changed, 102 insertions(+), 45 deletions(-)

diff --git a/RPi_Client/CoAPthon3/coapclient.py b/RPi_Client/CoAPthon3/coapclient.py
index 5dd8596..16671f2 100644
--- a/RPi_Client/CoAPthon3/coapclient.py
+++ b/RPi_Client/CoAPthon3/coapclient.py
@@ -18,14 +18,44 @@ from coapthon.utils import parse_uri
 __author__ = 'Giacomo Tanganelli'
 
 class CoapClient():
-    def __init__(self):
+    def __init__(self): # 문제없음.
         self.ip = "shmd01.iptime.org"
         self.myMAC = ':'.join(re.findall('..', '%012x' % uuid.getnode()))
+        self.clearMyData()
         self.myuuid, self.operate = self.obtainMyID()
-        if self.operate == 1:
+        if self.operate == 1: # rpNode가 이미 한 개 이상존재하는 경우
             self._beacon = BeaconEmit()
+            self.advertiseMe()
+    
+    def clearMyData(self): #문제없음.
+        path = "/rpNodeInfoPath"
+        
+        path = "coap://" + self.ip + path
+        host, port, path = parse_uri(path)
+        try:
+            tmp = socket.gethostbyname(host)
+            host = tmp
+        except socket.gaierror:
+            pass
+
+        client = HelperClient(server=(host, port))
+
+        try:            
+            payload = {
+                'option' : -1, #clear my data from Server
+                'rpMAC' : self.myMAC
+            }
+            response = client.put(path, json.dumps(payload))
+            print((response.pretty_print()))
+            string = json.loads(response.payload)['rpuuid']
+
+        except KeyboardInterrupt:
+            print("obtainMyID Stop")
+            client.stop()
+
+        client.stop()
 
-    def obtainMyID(self):
+    def obtainMyID(self): # 문제없음.
         path = "/rpNodeInfoPath"
         
         path = "coap://" + self.ip + path
@@ -40,7 +70,7 @@ class CoapClient():
 
         try:            
             payload = {
-                'option' : 0,
+                'option' : 0, #obtain rpuuid from Server
                 'rpMAC' : self.myMAC
             }
             response = client.put(path, json.dumps(payload))
@@ -54,7 +84,7 @@ class CoapClient():
         client.stop()
         return string, json.loads(response.payload)['operate']
 
-    def advertiseMe(self):
+    def advertiseMe(self): #문제없음.
         seq = self.myuuid
         length = 3
         string =""
@@ -64,7 +94,7 @@ class CoapClient():
         print(map(''.join, zip(*[iter(seq)]*length)))
         self._beacon.beacon_Start(string)
 
-    def calculateNodePositionAtServer(self):
+    def calculateNodePositionAtServer(self): #문제없음.
         path = "/rpNodeInfoPath"
         
         path = "coap://" + self.ip + path
@@ -79,18 +109,22 @@ class CoapClient():
 
         try:            
             payload = {
-                'option' : 1,
+                'option' : 1, # obtain my position from Server.
                 'rpuuid' : self.myuuid
             }
             response = client.put(path, json.dumps(payload))
             print((response.pretty_print()))
+            if json.loads(response.payload)['operate'] == 0: # Postion 계산이 불가능한 경우
+                client.stop()
+                print("RpNode Exit and delete my data in DB")
+                sys.exit(1)
 
         except KeyboardInterrupt:
             print("obtainMyID Stop")
             client.stop()
         client.stop()
 
-    def putBLEInfo(self):  # pragma: no cover
+    def putBLEInfo(self):  # 문제 없음.
         dev_id = 0
         try:
             self.sock = bluez.hci_open_dev(dev_id)
@@ -139,7 +173,7 @@ class CoapClient():
 
         client.stop()
 
-    def mkJsonbeaconInfo(self, info):
+    def mkJsonbeaconInfo(self, info): #문제 없음.
         n = 2.2
         distance = math.pow(10, (float(info[4]) - float(info[5])) / (10 * n))
         payload = {
@@ -150,7 +184,7 @@ class CoapClient():
         }
         return payload
 
-    def regiRelWithNewPi(self, info):
+    def regiRelWithNewPi(self, info): #문제 없음
         #새로운 rasbPi를 찾은 경우 새로운 rasbPi를 위치측정기로 사용하기 위해서 server에 관련 정보를 저장하는 method
         path = "/rpGraphInfoPath"
         
@@ -173,7 +207,7 @@ class CoapClient():
             client.stop()
         client.stop()
 
-    def mkJsonRpgraphInfo(self, info):
+    def mkJsonRpgraphInfo(self, info): #문제 없음
         n = 2.2
         print(info)
         distance = math.pow(10, ((float(info[4]) - float(info[5])) / (10 * n)))
@@ -186,8 +220,6 @@ class CoapClient():
 
 def main():
     measuringDevice = CoapClient()
-    if measuringDevice.operate == 1:
-        measuringDevice.advertiseMe()
     measuringDevice.calculateNodePositionAtServer()
     putBLEInfoThread = threading.Thread(target = measuringDevice.putBLEInfo)
     putBLEInfoThread.start()
diff --git a/Server_CoAP/CoAPthon3/coapserver.py b/Server_CoAP/CoAPthon3/coapserver.py
index a93974b..51a4a8b 100644
--- a/Server_CoAP/CoAPthon3/coapserver.py
+++ b/Server_CoAP/CoAPthon3/coapserver.py
@@ -12,7 +12,7 @@ from exampleresources import BleInfoResource, RpNodeInfoResource, RpGraphInfoRes
 from pymongo import MongoClient
 
 class CoAPServer(CoAP):
-    def __init__(self, host, port, multicast=False):
+    def __init__(self, host, port, multicast=False): #문제 없음.
         CoAP.__init__(self, (host, port), multicast)
         self.add_resource('bleInfoPath/', BleInfoResource())
         self.add_resource('rpNodeInfoPath/', RpNodeInfoResource())
@@ -39,9 +39,9 @@ class CoAPServer(CoAP):
                     print(c['uuid'])
                     positionCalculationThread = threading.Thread(target = self.positionCalculation, args=([c['uuid']]))
                     positionCalculationThread.start()
-                time.sleep(3.1)
+                time.sleep(2.1)
                 currentTime = time.time()
-                trackingCursor = self.trackingCollection.remove({'updateTime': {'lte' : currentTime - 3}})
+                trackingCursor = self.trackingCollection.remove({'updateTime': {'lte' : currentTime - 2}})
         except KeyboardInterrupt:
             print("existing updateUserLocation")
     
@@ -49,7 +49,7 @@ class CoAPServer(CoAP):
         print(useruuid)
         currentTime = time.time()
         trackingCursor = self.trackingCollection.find({'$and':[{'useruuid': useruuid},
-        {'updateTime':{'$gt' : currentTime - 3}}]})
+        {'updateTime':{'$gt' : currentTime - 2}}]})
         #trackingCursor = self.trackingCollection.find({'$and':[{'useruuid':{'$eq' : useruuid}}]})
         userLocationData =[]
 
diff --git a/Server_CoAP/CoAPthon3/exampleresources.py b/Server_CoAP/CoAPthon3/exampleresources.py
index 2987a89..1e927c7 100644
--- a/Server_CoAP/CoAPthon3/exampleresources.py
+++ b/Server_CoAP/CoAPthon3/exampleresources.py
@@ -6,7 +6,7 @@ from pymongo import MongoClient
 from coapthon import defines
 from coapthon.resources.resource import Resource
 
-class RpNodeInfoResource(Resource):
+class RpNodeInfoResource(Resource): #문제 없음.
     def __init__(self, name="RpNodeInfo"):
         super(RpNodeInfoResource, self).__init__(name)
         self.payload = "RpNodeInfo resource"
@@ -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.calculateNodePosition(sefl.payload)
-        else :
+        if self.payload['option'] == -1:
+            self.deleteNodeData(self.payload)
+        elif self.payload['option'] == 1:
+            response.payload = self.calculateNodePosition(self.payload)
+        else : 
             response.payload = self.postRpNodeInfoInDB(self.payload)
         response.code = defines.Codes.CREATED.number
         return self, response
@@ -34,19 +36,28 @@ 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.calculateNodePosition(self.payload)
-        else :
+        if self.payload['option'] == -1:
+            self.deleteNodeData(self.payload)
+        elif self.payload['option'] == 1:
+            #coapclient.py에서 calculateNodePositionAtServer()이 호출된 경우
+            response.payload = self.calculateNodePosition(self.payload)
+        else :# coapclient.py 에서  obtainMyID()가 호출된 경우
             response.payload = self.postRpNodeInfoInDB(self.payload)
         response.code = defines.Codes.CHANGED.number
         return self, response
 
-    def postRpNodeInfoInDB(self, info):
+    def deleteNodeData(self, info): #문제 없음
+        info = info['rpMAC']
+        graphColletion = self.db.RpGraphData
+        rpuuid = self.collection.find({'rpMAC' : info})[0]['rpuuid']
+        graphColletion.delete_many({'v2' : rpuuid})
+        self.collection.delete_many({'rpMAC' : info})
+
+    def postRpNodeInfoInDB(self, info): #문제 없음
         info = info['rpMAC']
-        self.collection.delete_many({ 'rpMAC' : info })
         rpuuid = "52528282"+str(uuid.uuid4())[8:]
         rpuuid = rpuuid.replace("-","")
-        if self.collection.count() == 0:
+        if self.collection.count() == 0: # 첫번째 rpNode인 경우
             payload = {
                 'rpMAC' : info,
                 'rpuuid' : rpuuid
@@ -55,7 +66,7 @@ class RpNodeInfoResource(Resource):
 
             response = json.dumps({
                 'rpuuid' : rpuuid,
-                'operate' : 0
+                'operate' : 0 # advertise할 필요가 없다.
             })
         else:
             payload = {
@@ -66,35 +77,43 @@ class RpNodeInfoResource(Resource):
 
             response = json.dumps({
                 'rpuuid' : rpuuid,
-                'operate' : 1
+                'operate' : 1 # advertise를 해야한다.
             })
         return response
 
-    def calculateNodePosition(self, info):
+    def calculateNodePosition(self, info): # 문제 없음.
         print("Start calculateNodePosition")
         info = info['rpuuid']
         graphColletion = self.db.RpGraphData
         mydoc = self.collection.find({'rpuuid': info})
-        if mydoc.count() == 1:
-            if self.collection.count() == 1:
+        response = {
+            'operate' : 1
+        }
+        if mydoc.count() == 1: # 자기 자신이 RpNodeData에 있는 경우
+            if self.collection.count() == 1: # 자신이 첫번째 RpNode인 경우
                 self.collection.update({'rpuuid' : info}, {'$set':{'x': 0.0, 'y': 0.0}}, False)
-            elif self.collection.count() == 2:
+            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)
-            elif self.collection.count() == 3:
+            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:
-                        vertexA = tempdoc[0]
-                    vertexB = tempdoc[0]
-                #print("kkkkkkkkkkkkkkk", graphColletion.find({'v1': vertexB['rpuuid'], 'v2': info}) )
+                    if tempdoc[0]['x'] == 0 and tempdoc[0]['y'] == 0: # 첫번째 RpNode 즉, (0,0)
+                        vertexA = tempdoc[0]# 첫번째 RpNode를 vertexA라 한다.
+                    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:
+                    # 3번째 rpNode를 만들 수 없는 경우
+                    print("3번째 rpNode를 만들 수 없습니다.")
+                    response['operate'] = 0
+                    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'])
                 sinA = math.sqrt((1 - math.pow(cosA,2)))
                 x = dis['b'] * cosA
@@ -113,7 +132,10 @@ class RpNodeInfoResource(Resource):
                 nodeLocationData = sorted(nodeLocationData, key=lambda k: k['distance'], reverse = False)
 
                 if len(nodeLocationData) < 3:
-                    return
+                    # 4번째 이상의 rpNode를 만들 수 없는 경우
+                    print("4번째 이상의 rpNode를 만들 수 없습니다.")
+                    response['operate'] = 0
+                    return json.dumps(response)
 
                 nodeList = []
                 for i in range(3):
@@ -127,13 +149,16 @@ class RpNodeInfoResource(Resource):
                 x, y = triangulation.doTriangulation()
 
                 if x == None:
-                    return
+                    # 4번째 이상의 rpNode를 만들 수 없는 경우
+                    print("4번째 이상의 rpNode를 만들 수 없습니다.")
+                    response['operate'] = 0
+                    return json.dumps(response)
 
                 self.collection.update({'rpuuid' : info}, {'$set':{'x': x, 'y': y}}, False)
-                
-        
 
-class RpGraphInfoResource(Resource):
+                return json.dump(response)
+                
+class RpGraphInfoResource(Resource): #문제 없음
     def __init__(self, name="RpGraphInfo"):
         super(RpGraphInfoResource, self).__init__(name)
         self.payload = "RpGraphInfo resource"
@@ -171,7 +196,7 @@ class RpGraphInfoResource(Resource):
         response.code = defines.Codes.DELETED.number
         return True, response
 
-    def postRpGraphInfoInDB(self, info):
+    def postRpGraphInfoInDB(self, info): #문제 없음.
         info = json.loads(info)
         mydoc = self.collection.find({'v1':info['v1'], 'v2':info['v2']})
         if mydoc.count() > 0:
@@ -194,7 +219,7 @@ class RpGraphInfoResource(Resource):
                 'count': 1
                 }, upsert=True)
 
-class BleInfoResource(Resource):
+class BleInfoResource(Resource): #문제없음.
     def __init__(self, name="BleInfo"):
         super(BleInfoResource, self).__init__(name)
         self.payload = "BleInfo resource"
-- 
GitLab