From 9a0527dfab1170a16b83231f172f65dc5df29e8e Mon Sep 17 00:00:00 2001 From: "Server (Shared Users)" <shmd01.iptime.org> Date: Tue, 10 Dec 2019 10:43:54 +0000 Subject: [PATCH] test --- RPi_Client/CoAPthon3/coapclient.py | 1 - RPi_Client/CoAPthon3/testclient.py | 226 +++++++++++++++++ Server_CoAP/CoAPthon3/exampleresources.py | 55 +++-- Server_CoAP/CoAPthon3/testresource.py | 281 ++++++++++++++++++++++ Server_CoAP/CoAPthon3/testserver.py | 175 ++++++++++++++ Server_Vue_Express/backend/routes/api.js | 12 +- Server_Vue_Express/backend/views/rpis.pug | 4 +- 7 files changed, 721 insertions(+), 33 deletions(-) create mode 100644 RPi_Client/CoAPthon3/testclient.py create mode 100644 Server_CoAP/CoAPthon3/testresource.py create mode 100644 Server_CoAP/CoAPthon3/testserver.py diff --git a/RPi_Client/CoAPthon3/coapclient.py b/RPi_Client/CoAPthon3/coapclient.py index e21d620..bbe7bb6 100644 --- a/RPi_Client/CoAPthon3/coapclient.py +++ b/RPi_Client/CoAPthon3/coapclient.py @@ -168,7 +168,6 @@ class CoapClient(): except KeyboardInterrupt: print("PutBLEInfo Stop") client.stop() - client.stop() def mkJsonbeaconInfo(self, info): # complete diff --git a/RPi_Client/CoAPthon3/testclient.py b/RPi_Client/CoAPthon3/testclient.py new file mode 100644 index 0000000..bbe7bb6 --- /dev/null +++ b/RPi_Client/CoAPthon3/testclient.py @@ -0,0 +1,226 @@ +#!/usr/bin/env python +import getopt +import socket +import sys +import re, uuid +import time +import threading +import json +import bluetooth._bluetooth as bluez +import blescan +import _thread +import math +from piBeacon import BeaconEmit + +from coapthon.client.helperclient import HelperClient +from coapthon.utils import parse_uri + +__author__ = 'Giacomo Tanganelli' + +class CoapClient(): + def __init__(self): # complete + 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: # rpNode가 이미 한 개 이상존재하는 경우 + self._beacon = BeaconEmit() + self.advertiseMe() + + def clearMyData(self): # complete + 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())) + + except KeyboardInterrupt: + print("obtainMyID Stop") + client.stop() + + client.stop() + + def obtainMyID(self): # complete + 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' : 0, #obtain rpuuid 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() + return string, json.loads(response.payload)['operate'] + + def advertiseMe(self): # complete + seq = self.myuuid + length = 3 + string ="" + for i in range(0, len(seq), 2): + string += seq[i:i+2]+" " + print(string) + print(map(''.join, zip(*[iter(seq)]*length))) + self._beacon.beacon_Start(string) + + def calculateNodePositionAtServer(self): # complete + 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, # 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 계산이 불가능한 경우 + print("impossible position calculation") + + except KeyboardInterrupt: + print("obtainMyID Stop") + client.stop() + client.stop() + + def putBLEInfo(self): # complete + dev_id = 0 + try: + self.sock = bluez.hci_open_dev(dev_id) + print("ble thread started") + + except: + print("error accessing bluetooth device...") + sys.exit(1) + + blescan.hci_le_set_scan_parameters(self.sock) + blescan.hci_enable_le_scan(self.sock) + + path = "/bleInfoPath" + payload = [] + + 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: + while True : + payload = [] + returnedList = blescan.parse_events(self.sock, 50) + for beacon in returnedList: + beaconInfo = [str(x) for x in beacon.split(',') if x.strip()] + if beaconInfo[1][:8] == "52528282": + print("scanned : "+ str(beaconInfo)) + regiRelThread = threading.Thread(target = self.regiRelWithNewPi, args=([beaconInfo])) + regiRelThread.start() + continue + jsonpayload = self.mkJsonbeaconInfo(beaconInfo) + if jsonpayload['distance'] < 60: + payload.append(jsonpayload) + + response = client.put(path, json.dumps(payload)) + print((response.pretty_print())) + + except KeyboardInterrupt: + print("PutBLEInfo Stop") + client.stop() + client.stop() + + def mkJsonbeaconInfo(self, info): # complete + n = 2.05 + distance = math.pow(10, (float(info[4]) - float(info[5])) / (10 * n)) + payload = { + 'rpuuid' : self.myuuid, + 'userMAC' : info[0], + 'useruuid' : info[1], + 'distance' : distance, + 'updateTime' : time.time() + } + return payload + + def regiRelWithNewPi(self, info): # complete + #새로운 rasbPi를 찾은 경우 새로운 rasbPi를 위치측정기로 사용하기 위해서 server에 관련 정보를 저장하는 method + path = "/rpGraphInfoPath" + + 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: + response = client.put(path, json.dumps(self.mkJsonRpgraphInfo(info))) + print((response.pretty_print())) + + except KeyboardInterrupt: + print("obtainMyID Stop") + client.stop() + client.stop() + + def mkJsonRpgraphInfo(self, info): # complete + n = 2.05 + distance = math.pow(10, ((float(info[4]) - float(info[5])) / (10 * n))) + payload = { + 'v1' : self.myuuid, + 'v2' : info[1], + 'distance' : distance + } + return payload + +def main(): + measuringDevice = CoapClient() + measuringDevice.calculateNodePositionAtServer() + putBLEInfoThread = threading.Thread(target = measuringDevice.putBLEInfo) + putBLEInfoThread.start() + putBLEInfoThread.join() + +if __name__ == "__main__": + main() diff --git a/Server_CoAP/CoAPthon3/exampleresources.py b/Server_CoAP/CoAPthon3/exampleresources.py index f568f26..81babc2 100644 --- a/Server_CoAP/CoAPthon3/exampleresources.py +++ b/Server_CoAP/CoAPthon3/exampleresources.py @@ -37,17 +37,19 @@ class RpNodeInfoResource(Resource): assert(isinstance(response, Response)) self.payload = json.loads(self.payload) if self.payload['option'] == -1: + # coapclient.py에서 clearMyData()가 호출된 경우 self.deleteNodeData(self.payload) elif self.payload['option'] == 1: - #coapclient.py에서 calculateNodePositionAtServer()이 호출된 경우 + # coapclient.py에서 calculateNodePositionAtServer()이 호출된 경우 response.payload = self.calculateNodePosition(self.payload) else : - # coapclient.py 에서 obtainMyID()가 호출된 경우 + # coapclient.py에서 obtainMyID()가 호출된 경우 response.payload = self.postRpNodeInfoInDB(self.payload) response.code = defines.Codes.CHANGED.number return self, response def deleteNodeData(self, info): # complete + return info = info['rpMAC'] graphColletion = self.db.RpGraphData if self.collection.find({'rpMAC' : info}).count() != 0: @@ -93,11 +95,11 @@ 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_one({'rpuuid' : info}, {'$set':{'x': 0.0, 'y': 0.0}}, 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) + self.collection.update_one({'rpuuid' : info}, {'$set':{'x': x, 'y': 0.0}}, False) elif self.collection.count() == 3: # 자신이 세번째 RpNode인 경우 graphC = graphColletion.find({'v2': info}) for doc in graphC: @@ -115,20 +117,20 @@ class RpNodeInfoResource(Resource): 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 + 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']) if cosA >= 1 or cosA <= -1 : # 3번째 rpNode를 만들 수 없는 경우 print("3번째 rpNode를 만들 수 없습니다.(impossible cosA)",cosA) - response['operate'] = 1 + response['operate'] = 0 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) + self.collection.update_one({'rpuuid' : info}, {'$set':{'x': x, 'y': y}}, False) else: graphD = graphColletion.find({'v2' : info}) nodeLocationData = [] @@ -167,7 +169,7 @@ class RpNodeInfoResource(Resource): response['operate'] = 0 return json.dumps(response) - self.collection.update({'rpuuid' : info}, {'$set':{'x': x, 'y': y}}, False) + self.collection.update_one({'rpuuid' : info}, {'$set':{'x': x, 'y': y}}, False) return json.dumps(response) else: @@ -214,26 +216,27 @@ class RpGraphInfoResource(Resource): # complete def postRpGraphInfoInDB(self, info): # complete info = json.loads(info) - mydoc = self.collection.find({'v1':info['v1'], 'v2':info['v2'], 'distance': {'$lte' : 40}}) - if mydoc.count() > 0: - distance = (mydoc[0]['sum']+info['distance']) / (mydoc[0]['count'] + 1) + if info['distance'] < 60: + mydoc = self.collection.find({'v1':info['v1'], 'v2':info['v2']}) - self.collection.update({ 'v1' : info['v1'], 'v2':info['v2']}, { - 'v1':info['v1'], - 'v2': info['v2'], - 'distance' : distance, - 'sum': mydoc[0]['sum']+float(info['distance']), - 'count': mydoc[0]['count']+1 - }, upsert=True) + if mydoc.count() > 0: + distance = (mydoc[0]['sum']+info['distance']) / (mydoc[0]['count'] + 1) - if mydoc.count() == 0: - self.collection.update({ 'v1' : info['v1'], 'v2':info['v2']}, { - 'v1':info['v1'], - 'v2': info['v2'], - 'distance' : float(info['distance']), - 'sum': float(info['distance']), - 'count': 1 - }, upsert=True) + c = mydoc[0]['count'] + 1 + self.collection.update_one({ 'v1' : info['v1'], 'v2':info['v2']}, {"$set":{ + 'distance' : distance, + 'sum': mydoc[0]['sum']+float(info['distance']), + 'count': c + }},upsert = False) + + if mydoc.count() == 0: + self.collection.insert_one({ + 'v1':info['v1'], + 'v2': info['v2'], + 'distance' : float(info['distance']), + 'sum': float(info['distance']), + 'count': 1 + }) class BleInfoResource(Resource): # complete def __init__(self, name="BleInfo"): diff --git a/Server_CoAP/CoAPthon3/testresource.py b/Server_CoAP/CoAPthon3/testresource.py new file mode 100644 index 0000000..015ffcf --- /dev/null +++ b/Server_CoAP/CoAPthon3/testresource.py @@ -0,0 +1,281 @@ +import json +import uuid +import math +import triangulation +from pymongo import MongoClient +from coapthon import defines +from coapthon.resources.resource import 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.testNode + except: + print("Could not connect to MongoDB") + + def render_POST_advanced(self, request, response): + self.payload = request.payload + 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: + response.payload = self.calculateNodePosition(self.payload) + else : + response.payload = self.postRpNodeInfoInDB(self.payload) + response.code = defines.Codes.CREATED.number + return self, response + + def render_PUT_advanced(self, request, response): + self.payload = request.payload + from coapthon.messages.response import Response + assert(isinstance(response, Response)) + self.payload = json.loads(self.payload) + if self.payload['option'] == -1: + # coapclient.py에서 clearMyData()가 호출된 경우 + 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 deleteNodeData(self, info): # complete + info = info['rpMAC'] + graphColletion = self.db.testGraph + if self.collection.find({'rpMAC' : info}).count() != 0: + 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인 경우 + payload = { + 'rpMAC' : info, + 'rpuuid' : rpuuid + } + self.collection.insert_one(payload) + + response = json.dumps({ + 'rpuuid' : rpuuid, + 'operate' : 0 # advertise할 필요가 없다. + }) + else: + payload = { + 'rpMAC' : info, + '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. + print("Start calculateNodePosition") + info = info['rpuuid'] + graphColletion = self.db.testGraph + mydoc = self.collection.find({'rpuuid': info}) + response = { + 'operate' : 1 + } + if mydoc.count() == 1: # 자기 자신이 RpNodeData에 있는 경우 + if self.collection.count() == 1: # 자신이 첫번째 RpNode인 경우 + self.collection.update_one({'rpuuid' : info}, {'$set':{'x': 0.0, 'y': 0.0}}, False) + elif self.collection.count() == 2: # 자신이 두번째 RpNode인 경우 + graphB = graphColletion.find({'v2': info}) + x = graphB[0]['distance'] + self.collection.update_one({'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'] = 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']) + if cosA >= 1 or cosA <= -1 : + # 3번째 rpNode를 만들 수 없는 경우 + print("3번째 rpNode를 만들 수 없습니다.(impossible cosA)",cosA) + response['operate'] = 0 + return json.dumps(response) + + sinA = math.sqrt((1 - math.pow(cosA,2))) + x = dis['b'] * cosA + y = dis['b'] * sinA + self.collection.update_one({'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: + # 4번째 이상의 rpNode를 만들 수 없는 경우 + print("4번째 이상의 rpNode를 만들 수 없습니다.") + response['operate'] = 0 + return json.dumps(response) + + nodeList = [] + + for i in range(3): + print(self.collection.find({'rpuuid': nodeLocationData[i]['rpuuid']})[0]) + nodeList.append({ + 'x': self.collection.find({'rpuuid': nodeLocationData[i]['rpuuid']})[0]['x'], + 'y': self.collection.find({'rpuuid': nodeLocationData[i]['rpuuid']})[0]['y'], + 'distance': nodeLocationData[i]['distance'] + }) + + triangulationInst = triangulation.Triangulation(nodeList[:3]) + print("test : ", nodeList[:3]) + x, y = triangulationInst.doTriangulation() + print("x: ",x,"y : ",y) + if x == None: + # 4번째 이상의 rpNode를 만들 수 없는 경우 + print("4번째 이상의 rpNode를 만들 수 없습니다.") + response['operate'] = 0 + return json.dumps(response) + + self.collection.update_one({'rpuuid' : info}, {'$set':{'x': x, 'y': y}}, False) + + return json.dumps(response) + else: + response['operate'] = 0 + return json.dumps(response) + +class RpGraphInfoResource(Resource): # complete + 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.testGraph + + def render_GET_advanced(self, request, response): + response.payload = self.payload + response.max_age = 20 + response.code = defines.Codes.CONTENT.number + return self, response + + def render_POST_advanced(self, request, response): + self.payload = request.payload + from coapthon.messages.response import Response + assert(isinstance(response, Response)) + response.payload = self.postRpGraphInfoInDB(self.payload) + response.code = defines.Codes.CREATED.number + return self, response + + def render_PUT_advanced(self, request, response): + self.payload = request.payload + from coapthon.messages.response import Response + assert(isinstance(response, Response)) + response.payload = self.postRpGraphInfoInDB(self.payload) + response.code = defines.Codes.CHANGED.number + return self, response + + def render_DELETE_advanced(self, request, response): + response.payload = "Response deleted" + response.code = defines.Codes.DELETED.number + return True, response + + def postRpGraphInfoInDB(self, info): # complete + info = json.loads(info) + if info['distance'] < 60: + mydoc = self.collection.find({'v1':info['v1'], 'v2':info['v2']}) + + if mydoc.count() > 0: + distance = (mydoc[0]['sum']+info['distance']) / (mydoc[0]['count'] + 1) + + c = mydoc[0]['count'] + 1 + self.collection.update_one({ 'v1' : info['v1'], 'v2':info['v2']}, {"$set":{ + 'distance' : distance, + 'sum': mydoc[0]['sum']+float(info['distance']), + 'count': c + }},upsert = False) + + if mydoc.count() == 0: + self.collection.insert_one({ + 'v1':info['v1'], + 'v2': info['v2'], + 'distance' : float(info['distance']), + 'sum': float(info['distance']), + 'count': 1 + }) + +class BleInfoResource(Resource): # complete + def __init__(self, name="BleInfo"): + super(BleInfoResource, self).__init__(name) + self.payload = "BleInfo resource" + try: + self.conn = MongoClient('mongodb://iotuser:iotsystem@localhost/IoT_System', 27017) + self.db = self.conn.IoT_System + self.collection = self.db.testTracking + except: + print("Could not connect to MongoDB") + + def render_GET_advanced(self, request, response): + response.payload = self.payload + response.max_age = 20 + response.code = defines.Codes.CONTENT.number + return self, response + + def render_POST_advanced(self, request, response): + self.payload = request.payload + self.postBLEInfoInDB(self.payload) + from coapthon.messages.response import Response + assert isinstance(response, Response) + response.payload = "Response changed through POST" + response.code = defines.Codes.CREATED.number + return self, response + + def render_PUT_advanced(self, request, response): + self.payload = request.payload + self.postBLEInfoInDB(self.payload) + from coapthon.messages.response import Response + assert isinstance(response, Response) + response.payload = "Response changed through PUT" + response.code = defines.Codes.CHANGED.number + return self, response + + def render_DELETE_advanced(self, request, response): + response.payload = "Response deleted" + response.code = defines.Codes.DELETED.number + return True, response + + def postBLEInfoInDB(self, payload): + self.collection.insert_many(json.loads(payload)) \ No newline at end of file diff --git a/Server_CoAP/CoAPthon3/testserver.py b/Server_CoAP/CoAPthon3/testserver.py new file mode 100644 index 0000000..c56150d --- /dev/null +++ b/Server_CoAP/CoAPthon3/testserver.py @@ -0,0 +1,175 @@ +#!/usr/bin/env python +import getopt +import sys +import threading +import _thread +import time +import datetime +import json +import triangulation +from coapthon.server.coap import CoAP +from testresource import BleInfoResource, RpNodeInfoResource, RpGraphInfoResource +from pymongo import MongoClient + +class CoAPServer(CoAP): + def __init__(self, host, port, multicast=False): # complete + CoAP.__init__(self, (host, port), multicast) + self.add_resource('bleInfoPath/', BleInfoResource()) + 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 + self.updatePeriod = 10 + self.limitDistance = 40 + except: + print("Could not connect to MongoDB") + + def updateUserLocation(self): # complete + try: + while True: + cursor = self.usersCollection.find() + for c in cursor: + positionCalculationThread = threading.Thread(target = self.positionCalculation, args=([c['uuid']])) + positionCalculationThread.start() + time.sleep(self.updatePeriod) + #trackingCursor = self.trackingCollection.remove({'updateTime': {'$lte' : currentTime - self.updatePeriod}}) + except KeyboardInterrupt: + print("existing updateUserLocation") + + 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 =[] + + 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) + for u in userLocationData: + print(userLocationData) + + if len(userLocationData) == 0: + print("userLocationData == 0") + return + + rp1uuid = userLocationData[0]['rpuuid'] + rp1 = self.piNodeCollection.find({'rpuuid' : rp1uuid}) + + if len(userLocationData) < 3: + print("userLocationData < 3") + dd = datetime.datetime.utcnow() + 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 + + 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.utcnow() + 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.utcnow() + 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']}, + '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>") + + +def main(argv): # pragma: no cover + ip = "0.0.0.0" + port = 5683 + multicast = False + try: + opts, args = getopt.getopt(argv, "hi:p:m", ["ip=", "port=", "multicast"]) + except getopt.GetoptError: + usage() + sys.exit(2) + for opt, arg in opts: + if opt == '-h': + usage() + sys.exit() + elif opt in ("-i", "--ip"): + ip = arg + elif opt in ("-p", "--port"): + port = int(arg) + elif opt in ("-m", "--multicast"): + multicast = True + + server = CoAPServer(ip, port, multicast) + try: + #updateUserLocationThread = threading.Thread(target = server.updateUserLocation) + #updateUserLocationThread.start() + server.listen(10) + + except KeyboardInterrupt: + print("Server Shutdown") + server.close() + print("Exiting...") + + +if __name__ == "__main__": # pragma: no cover + main(sys.argv[1:]) diff --git a/Server_Vue_Express/backend/routes/api.js b/Server_Vue_Express/backend/routes/api.js index d7832e8..18e1ede 100644 --- a/Server_Vue_Express/backend/routes/api.js +++ b/Server_Vue_Express/backend/routes/api.js @@ -166,7 +166,7 @@ router.get('/rpis/:id', function(req, res, next) { '$gt': lastUpdateTime - 60, }, - distance: {'$lt': 40} + distance: {'$lt': 50} } }, { '$group': { @@ -175,7 +175,9 @@ router.get('/rpis/:id', function(req, res, next) { } ]); await rpNode.find({'rpuuid': ra[i]._id},(err,output)=>{ - if(output[0].rpname.indexOf(req.params.id) != -1 || req.params.id == "*") + if(output.length == 0) + ; + else if(output[0].rpname.indexOf(req.params.id) != -1 || req.params.id == "*") data.push({ rpuuid: ra[i]._id, rpname: output[0].rpname, @@ -183,7 +185,9 @@ router.get('/rpis/:id', function(req, res, next) { }); }); } - res.render('rpis',{data}); + const searchValue = req.params.id == '*'?"":req.params.id ; + + res.render('rpis',{data, searchValue}); })(); }); @@ -220,7 +224,7 @@ router.get('/aggregateByRPUUID/:id', function(req, res, next) { '$gt': lastUpdateTime - 60*i - 60, }, - distance: {'$lt': 40} + distance: {'$lt': 50} } }, { '$group': { diff --git a/Server_Vue_Express/backend/views/rpis.pug b/Server_Vue_Express/backend/views/rpis.pug index 7ea09a1..c106fa8 100644 --- a/Server_Vue_Express/backend/views/rpis.pug +++ b/Server_Vue_Express/backend/views/rpis.pug @@ -1,8 +1,8 @@ extends layout block content - input(type='text' id='input' name='rpiSearch' placeholder='검색할 단어를 입력하세요') - button(onclick='const k =document.getElementById("input").value; location.href= k!= ""?k:"*" ') 검색 + input(type='text' id='input' name='rpiSearch' placeholder='검색할 단어를 입력하세요' value=searchValue) + button(onclick='const k =document.getElementById("input").value; location.href= k!= ""?k:"*" ' ) 검색 hr(size='3px') p - let i=0; -- GitLab