Example #1
0
class AMQP():
    """ iotJumpWay AMQP IoT Agent

	The AMQP IoT Agent listens for all traffic coming from devices
	connected to the HIAS network using the AMQP protocol.
	"""
    def __init__(self):
        """ Initializes the class. """

        self.Helpers = Helpers("AMQP")
        self.Helpers.logger.info("AMQP Agent initialization complete.")

    def amqpConnect(self):
        """ Initiates the AMQP connection. """

        credentials = self.Helpers.confs["iotJumpWay"]["AMQP"]["un"] + \
         ':' + self.Helpers.confs["iotJumpWay"]["AMQP"]["pw"]
        parameters = pika.URLParameters(
            'amqps://' + credentials + '@' +
            self.Helpers.confs["iotJumpWay"]["host"] + '/' +
            self.Helpers.confs["iotJumpWay"]["AMQP"]["vhost"])
        context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
        context.load_verify_locations(self.Helpers.confs["iotJumpWay"]["cert"])
        parameters.ssl_options = pika.SSLOptions(context)

        self.connection = pika.BlockingConnection(parameters)
        self.channel = self.connection.channel()
        self.amqpPublish(
            json.dumps({
                "Application":
                self.Helpers.confs["iotJumpWay"]["AMQP"]["identifier"],
                "Status":
                "ONLINE"
            }), "Statuses")
        self.Helpers.logger.info("AMQP connection established!")

    def blockchainConnect(self):
        """ Initiates the Blockchain connection. """

        self.Blockchain = Blockchain()
        self.Blockchain.startBlockchain()
        self.Blockchain.w3.geth.personal.unlockAccount(
            self.Helpers.confs["ethereum"]["haddress"],
            self.Helpers.confs["ethereum"]["hpass"], 0)
        self.Blockchain.w3.geth.personal.unlockAccount(
            self.Helpers.confs["ethereum"]["iaddress"],
            self.Helpers.confs["ethereum"]["ipass"], 0)

    def mongoDbConn(self):
        """ Initiates the MongoDB connection. """

        self.MongoDB = MongoDB()
        self.MongoDB.startMongoDB()

    def amqpConsumeSet(self):
        """ Sets up the AMQP queue subscriptions. """

        self.channel.basic_consume('Life', self.lifeCallback, auto_ack=True)
        self.channel.basic_consume('Statuses',
                                   self.statusesCallback,
                                   auto_ack=True)
        self.Helpers.logger.info("AMQP consume setup!")

    def amqpConsumeStart(self):
        """ Starts consuming. """

        self.Helpers.logger.info("AMQP consume starting!")
        self.channel.start_consuming()

    def amqpPublish(self, data, routing_key):
        """ Publishes to an AMQP broker queue. """

        self.channel.basic_publish(
            exchange=self.Helpers.confs["iotJumpWay"]["AMQP"]["exchange"],
            routing_key=routing_key,
            body=data)
        self.Helpers.logger.info("AMQP consume setup!")

    def life(self):
        """ Sends vital statistics to HIAS. """

        cpu = psutil.cpu_percent()
        mem = psutil.virtual_memory()[2]
        hdd = psutil.disk_usage('/').percent
        tmp = psutil.sensors_temperatures()['coretemp'][0].current
        r = requests.get('http://ipinfo.io/json?token=' +
                         self.Helpers.confs["iotJumpWay"]["ipinfo"])
        data = r.json()
        location = data["loc"].split(',')

        self.amqpPublish(
            json.dumps({
                "Application":
                self.Helpers.confs["iotJumpWay"]["AMQP"]["identifier"],
                "CPU":
                str(cpu),
                "Memory":
                str(mem),
                "Diskspace":
                str(hdd),
                "Temperature":
                str(tmp),
                "Latitude":
                float(location[0]),
                "Longitude":
                float(location[1])
            }), "Life")

        self.Helpers.logger.info("Agent life statistics published.")
        threading.Timer(300.0, self.life).start()

    def contextConn(self):
        """ Initiates the Context Broker class. """

        self.ContextBroker = ContextBroker()

    def statusesCallback(self, ch, method, properties, body):
        """ Processes status messages. """
        Thread(target=self.statusesWorker, args=(body, ), daemon=True).start()

    def statusesWorker(self, body):
        """ Processes status messages. """

        self.Helpers.logger.info("Life data callback")
        data = json.loads(body)

        if "Application" in data:
            entityType = "Application"
            entity = data["Application"]
            application = entity
            zone = "NA"
            device = "NA"
            short = "App"
            del data['Application']
        elif "Device" in data:
            entityType = "Device"
            entity = data["Device"]
            application = "NA"
            device = entity
            short = "Device"
            del data['Device']

        status = data['Status']

        requiredAttributes = self.ContextBroker.getRequiredAttributes(
            entity, entityType)

        locationID = int(requiredAttributes["Data"]["lid"]["value"])
        location = requiredAttributes["Data"]["lid"]["entity"]
        if entityType is "Device":
            zone = requiredAttributes["Data"]["zid"]["entity"]
        bcAddress = requiredAttributes["Data"]["blockchain"]["address"]

        if not self.Blockchain.iotJumpWayAccessCheck(bcAddress):
            return

        updateResponse = self.ContextBroker.updateEntity(
            entity, entityType, {
                "status": {
                    "value": status,
                    "timestamp": datetime.now().isoformat()
                }
            })

        if updateResponse["Response"] == "OK":
            self.Helpers.logger.info(entityType + " " + entity +
                                     " status update OK")
            _id = self.MongoDB.insertData(
                self.MongoDB.mongoConn.Statuses, {
                    "Use": entityType,
                    "Location": location,
                    "Zone": zone,
                    "Application": application,
                    "Device": device,
                    "Status": status,
                    "Time": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                }, None)
            Thread(target=self.Blockchain.storeHash,
                   args=(str(_id), self.Blockchain.hashStatus(status),
                         int(time.time()), locationID, entity, bcAddress,
                         short),
                   daemon=True).start()
        else:
            self.Helpers.logger.error(entityType + " " + entity +
                                      " status update KO")

    def lifeCallback(self, ch, method, properties, body):
        """ Processes life messages. """
        Thread(target=self.lifeWorker, args=(body, ), daemon=True).start()

    def lifeWorker(self, body):

        self.Helpers.logger.info("Life data callback")
        data = json.loads(body)

        if "Application" in data:
            entityType = "Application"
            entity = data["Application"]
            application = entity
            zone = "NA"
            device = "NA"
            short = "App"
            del data['Application']
        elif "Device" in data:
            entityType = "Device"
            entity = data["Device"]
            application = "NA"
            device = entity
            short = "Device"
            del data['Device']

        requiredAttributes = self.ContextBroker.getRequiredAttributes(
            entity, entityType)

        locationID = int(requiredAttributes["Data"]["lid"]["value"])
        location = requiredAttributes["Data"]["lid"]["entity"]
        if entityType is "Device":
            zone = requiredAttributes["Data"]["zid"]["entity"]
        bcAddress = requiredAttributes["Data"]["blockchain"]["address"]

        if not self.Blockchain.iotJumpWayAccessCheck(bcAddress):
            return

        updateResponse = self.ContextBroker.updateEntity(
            entity, entityType, {
                "status": {
                    "value": "ONLINE",
                    "timestamp": datetime.now().isoformat()
                },
                "cpuUsage": {
                    "value": data["CPU"]
                },
                "memoryUsage": {
                    "value": data["Memory"]
                },
                "hddUsage": {
                    "value": data["Diskspace"]
                },
                "temperature": {
                    "value": data["Temperature"]
                },
                "location": {
                    "type": "geo:json",
                    "value": {
                        "type":
                        "Point",
                        "coordinates":
                        [float(data["Latitude"]),
                         float(data["Longitude"])]
                    }
                }
            })

        if updateResponse["Response"] == "OK":
            self.Helpers.logger.info(entityType + " " + entity +
                                     " status update OK")
            _id = self.MongoDB.insertData(
                self.MongoDB.mongoConn.Life, {
                    "Use": "Application",
                    "Location": location,
                    "Zone": zone,
                    "Application": application,
                    "Device": device,
                    "Data": data,
                    "Time": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                }, None)
            Thread(target=self.Blockchain.storeHash,
                   args=(str(_id), self.Blockchain.hashLifeData(data),
                         int(time.time()), locationID, entity, bcAddress,
                         short),
                   daemon=True).start()
        else:
            self.Helpers.logger.error(entityType + " " + entity +
                                      " status update KO")

    def agentThreads(self):
        """ Processes status messages. """

        Thread(target=AMQP.life, args=(), daemon=True).start()
        Thread(target=AMQP.amqpConsumeStart, args=(), daemon=True).start()

    def respond(self, responseCode, response):
        """ Builds the request repsonse """

        return Response(response=json.dumps(response, indent=4),
                        status=responseCode,
                        mimetype="application/json")

    def signal_handler(self, signal, frame):
        self.Helpers.logger.info("Disconnecting")
        self.amqpPublish(
            json.dumps({
                "Application":
                self.Helpers.confs["iotJumpWay"]["AMQP"]["identifier"],
                "Status":
                "OFFLINE"
            }), "Statuses")
        self.connection.close()
        sys.exit(1)
Example #2
0
class MQTT():
    """ iotJumpWay MQTT IoT Agent

	The MQTT IoT Agent listens for all traffic coming from devices
	connected to the HIAS network using the MQTT protocol.
	"""
    def __init__(self):
        """ Initializes the class. """

        self.Helpers = Helpers("MQTT")
        self.Helpers.logger.info("MQTT Agent initialization complete.")

    def startIoT(self):
        """ Initiates the iotJumpWay connection. """

        self.Application = Application({
            "host":
            self.Helpers.confs["iotJumpWay"]["host"],
            "port":
            self.Helpers.confs["iotJumpWay"]["MQTT"]["port"],
            "lid":
            self.Helpers.confs["iotJumpWay"]["MQTT"]["Agent"]["lid"],
            "aid":
            self.Helpers.confs["iotJumpWay"]["MQTT"]["Agent"]["aid"],
            "an":
            self.Helpers.confs["iotJumpWay"]["MQTT"]["Agent"]["an"],
            "un":
            self.Helpers.confs["iotJumpWay"]["MQTT"]["Agent"]["un"],
            "pw":
            self.Helpers.confs["iotJumpWay"]["MQTT"]["Agent"]["pw"]
        })
        self.Application.connect()

        self.Application.appChannelSub("#", "#")
        self.Application.appDeviceChannelSub("#", "#", "#")

        self.Application.appLifeCallback = self.appLifeCallback
        self.Application.appSensorCallback = self.appSensorCallback
        self.Application.appStatusCallback = self.appStatusCallback
        self.Application.deviceCommandsCallback = self.deviceCommandsCallback
        self.Application.deviceNfcCallback = self.deviceNfcCallback
        self.Application.deviceSensorCallback = self.deviceSensorCallback
        self.Application.deviceStatusCallback = self.deviceStatusCallback
        self.Application.deviceLifeCallback = self.deviceLifeCallback

        self.Helpers.logger.info("iotJumpWay connection initiated.")

    def contextConn(self):
        """ Initiates the Context Broker class. """

        self.ContextBroker = ContextBroker()

    def mongoDbConn(self):
        """ Initiates the MongoDB connection. """

        self.MongoDB = MongoDB()
        self.MongoDB.startMongoDB()

    def blockchainConn(self):
        """ Initiates the Blockchain connection. """

        self.Blockchain = Blockchain()
        self.Blockchain.startBlockchain()
        self.Blockchain.w3.geth.personal.unlockAccount(
            self.Helpers.confs["ethereum"]["haddress"],
            self.Helpers.confs["ethereum"]["hpass"], 0)
        self.Blockchain.w3.geth.personal.unlockAccount(
            self.Helpers.confs["ethereum"]["iaddress"],
            self.Helpers.confs["ethereum"]["ipass"], 0)

    def life(self):
        """ Sends vital statistics to HIAS """

        cpu = psutil.cpu_percent()
        mem = psutil.virtual_memory()[2]
        hdd = psutil.disk_usage('/').percent
        tmp = psutil.sensors_temperatures()['coretemp'][0].current
        r = requests.get('http://ipinfo.io/json?token=' +
                         self.Helpers.confs["iotJumpWay"]["ipinfo"])
        data = r.json()
        location = data["loc"].split(',')

        self.Application.appChannelPub(
            "Life", self.Helpers.confs["iotJumpWay"]["MQTT"]["Agent"]["aid"], {
                "CPU": str(cpu),
                "Memory": str(mem),
                "Diskspace": str(hdd),
                "Temperature": str(tmp),
                "Latitude": float(location[0]),
                "Longitude": float(location[1])
            })

        self.Helpers.logger.info("Agent life statistics published.")
        threading.Timer(300.0, self.life).start()

    def appStatusCallback(self, topic, payload):
        """
		iotJumpWay Application Status Callback

		The callback function that is triggered in the event of status
		communication via MQTT from an iotJumpWay application.
		"""

        self.Helpers.logger.info("Recieved iotJumpWay Application Status: " +
                                 payload.decode())

        splitTopic = topic.split("/")
        status = payload.decode()

        location = splitTopic[0]
        application = splitTopic[2]

        requiredAttributes = self.ContextBroker.getRequiredAttributes(
            application, "Application")

        locationID = int(requiredAttributes["Data"]["lid"]["value"])
        bcAddress = requiredAttributes["Data"]["blockchain"]["address"]

        if not self.Blockchain.iotJumpWayAccessCheck(bcAddress):
            return

        updateResponse = self.ContextBroker.updateEntity(
            application, "Application", {
                "status": {
                    "value": status,
                    "timestamp": datetime.now().isoformat()
                }
            })

        if updateResponse["Response"] == "OK":
            self.Helpers.logger.info("Application " + application +
                                     " status update OK")
            _id = self.MongoDB.insertData(
                self.MongoDB.mongoConn.Statuses, {
                    "Use": "Application",
                    "Location": location,
                    "Zone": "NA",
                    "Application": application,
                    "Device": "NA",
                    "Status": status,
                    "Time": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                }, None)
            Thread(target=self.Blockchain.storeHash,
                   args=(str(_id), self.Blockchain.hashStatus(status),
                         int(time.time()), locationID, application, bcAddress,
                         "App"),
                   daemon=True).start()
        else:
            self.Helpers.logger.error("Application " + application +
                                      " status update KO")

    def appLifeCallback(self, topic, payload):
        """
		iotJumpWay Application Life Callback

		The callback function that is triggered in the event of life
		communication via MQTT from an iotJumpWay application.
		"""

        self.Helpers.logger.info(
            "Recieved iotJumpWay Application Life Data: " + payload.decode())

        data = json.loads(payload.decode("utf-8"))
        splitTopic = topic.split("/")

        location = splitTopic[0]
        application = splitTopic[2]

        requiredAttributes = self.ContextBroker.getRequiredAttributes(
            application, "Application")

        locationID = int(requiredAttributes["Data"]["lid"]["value"])
        bcAddress = requiredAttributes["Data"]["blockchain"]["address"]

        if not self.Blockchain.iotJumpWayAccessCheck(bcAddress):
            return

        updateResponse = self.ContextBroker.updateEntity(
            application, "Application", {
                "status": {
                    "value": "ONLINE",
                    "timestamp": datetime.now().isoformat()
                },
                "cpuUsage": {
                    "value": data["CPU"]
                },
                "memoryUsage": {
                    "value": data["Memory"]
                },
                "hddUsage": {
                    "value": data["Diskspace"]
                },
                "temperature": {
                    "value": data["Temperature"]
                },
                "location": {
                    "type": "geo:json",
                    "value": {
                        "type":
                        "Point",
                        "coordinates":
                        [float(data["Latitude"]),
                         float(data["Longitude"])]
                    }
                }
            })

        if updateResponse["Response"] == "OK":
            _id = self.MongoDB.insertData(
                self.MongoDB.mongoConn.Life, {
                    "Use": "Application",
                    "Location": location,
                    "Zone": "NA",
                    "Application": application,
                    "Device": "NA",
                    "Data": data,
                    "Time": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                }, None)
            Thread(target=self.Blockchain.storeHash,
                   args=(str(_id), self.Blockchain.hashLifeData(data),
                         int(time.time()), locationID, application, bcAddress,
                         "App"),
                   daemon=True).start()
            self.Helpers.logger.info("Application " + application +
                                     " status update OK")
        else:
            self.Helpers.logger.error("Application " + application +
                                      " life update KO")

    def appSensorCallback(self, topic, payload):
        """
		iotJumpWay Application Sensors Callback

		The callback function that is triggered in the event of sensor
		communication via MQTT from an iotJumpWay application.
		"""

        self.Helpers.logger.info(
            "Recieved iotJumpWay Application Sensors Data: " +
            payload.decode())

        data = json.loads(payload.decode("utf-8"))
        splitTopic = topic.split("/")

        location = splitTopic[0]
        application = splitTopic[2]

        requiredAttributes = self.ContextBroker.getRequiredAttributes(
            application, "Application")

        locationID = int(requiredAttributes["Data"]["lid"]["value"])
        bcAddress = requiredAttributes["Data"]["blockchain"]["address"]

        if not self.Blockchain.iotJumpWayAccessCheck(bcAddress):
            return

        updateResponse = self.ContextBroker.updateEntity(
            application, "Application", {
                "status": {
                    "value": "ONLINE",
                    "timestamp": datetime.now().isoformat()
                },
                "cpuUsage": {
                    "value": data["CPU"]
                },
                "memoryUsage": {
                    "value": data["Memory"]
                },
                "hddUsage": {
                    "value": data["Diskspace"]
                },
                "temperature": {
                    "value": data["Temperature"]
                },
                "location": {
                    "type": "geo:json",
                    "value": {
                        "type":
                        "Point",
                        "coordinates":
                        [float(data["Latitude"]),
                         float(data["Longitude"])]
                    }
                }
            })

        if updateResponse["Response"] == "OK":
            _id = self.MongoDB.insertData(
                self.MongoDB.mongoConn.Life, {
                    "Use": "Application",
                    "Location": location,
                    "Zone": "NA",
                    "Application": application,
                    "Device": "NA",
                    "Data": data,
                    "Time": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                }, None)
            Thread(target=self.Blockchain.storeHash,
                   args=(str(_id), self.Blockchain.hashLifeData(data),
                         int(time.time()), locationID, application, bcAddress,
                         "App"),
                   daemon=True).start()
            self.Helpers.logger.info("Application " + application +
                                     " status update OK")
        else:
            self.Helpers.logger.error("Application " + application +
                                      " life update KO")

        data = json.loads(payload.decode("utf-8"))
        splitTopic = topic.split("/")

        location = splitTopic[0]
        application = splitTopic[2]

        requiredAttributes = self.ContextBroker.getRequiredAttributes(
            application, "Application")

        locationID = int(requiredAttributes["Data"]["lid"]["value"])
        bcAddress = requiredAttributes["Data"]["blockchain"]["address"]

        if not self.Blockchain.iotJumpWayAccessCheck(bcAddress):
            return

        self.MongoDB.insertData(
            self.MongoDB.mongoConn.Sensors, {
                "Use": "Application",
                "Location": splitTopic[0],
                "Zone": 0,
                "Application": splitTopic[2],
                "Device": 0,
                "Sensor": data["Sensor"],
                "Type": data["Type"],
                "Value": data["Value"],
                "Message": data["Message"],
                "Time": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            }, None)

    def deviceStatusCallback(self, topic, payload):
        """
		iotJumpWay Device Status Callback

		The callback function that is triggered in the event of status
		communication via MQTT from an iotJumpWay device.
		"""

        self.Helpers.logger.info("Recieved iotJumpWay Device Status: " +
                                 payload.decode())

        splitTopic = topic.split("/")
        status = payload.decode()

        location = splitTopic[0]
        zone = splitTopic[2]
        device = splitTopic[3]

        requiredAttributes = self.ContextBroker.getRequiredAttributes(
            device, "Device")

        locationID = int(requiredAttributes["Data"]["lid"]["value"])
        bcAddress = requiredAttributes["Data"]["blockchain"]["address"]

        if not self.Blockchain.iotJumpWayAccessCheck(bcAddress):
            return

        updateResponse = self.ContextBroker.updateEntity(
            device, "Device", {
                "status": {
                    "value": status,
                    "timestamp": datetime.now().isoformat()
                }
            })

        if updateResponse["Response"] == "OK":
            self.Helpers.logger.info("Device " + device + " status update OK")
            _id = self.MongoDB.insertData(
                self.MongoDB.mongoConn.Statuses, {
                    "Use": "Device",
                    "Location": location,
                    "Zone": zone,
                    "Application": "NA",
                    "Device": device,
                    "Status": status,
                    "Time": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                }, None)
            Thread(target=self.Blockchain.storeHash,
                   args=(str(_id), self.Blockchain.hashStatus(status),
                         int(time.time()), locationID, device, bcAddress,
                         "Device"),
                   daemon=True).start()
        else:
            self.Helpers.logger.error("Device " + device + " status update KO")

    def deviceLifeCallback(self, topic, payload):
        """
		iotJumpWay Device Life Callback

		The callback function that is triggered in the event of life
		communication via MQTT from an iotJumpWay device.
		"""

        self.Helpers.logger.info("Recieved iotJumpWay Device Life Data: " +
                                 payload.decode())

        data = json.loads(payload.decode("utf-8"))
        splitTopic = topic.split("/")

        location = splitTopic[0]
        zone = splitTopic[2]
        device = splitTopic[3]

        requiredAttributes = self.ContextBroker.getRequiredAttributes(
            device, "Device")

        locationID = int(requiredAttributes["Data"]["lid"]["value"])
        bcAddress = requiredAttributes["Data"]["blockchain"]["address"]

        if not self.Blockchain.iotJumpWayAccessCheck(bcAddress):
            return

        updateResponse = self.ContextBroker.updateEntity(
            device, "Device", {
                "status": {
                    "value": "ONLINE",
                    "timestamp": datetime.now().isoformat()
                },
                "cpuUsage": {
                    "value": data["CPU"]
                },
                "memoryUsage": {
                    "value": data["Memory"]
                },
                "hddUsage": {
                    "value": data["Diskspace"]
                },
                "temperature": {
                    "value": data["Temperature"]
                },
                "location": {
                    "type": "geo:json",
                    "value": {
                        "type":
                        "Point",
                        "coordinates":
                        [float(data["Latitude"]),
                         float(data["Longitude"])]
                    }
                }
            })

        if updateResponse["Response"] == "OK":
            _id = self.MongoDB.insertData(
                self.MongoDB.mongoConn.Life, {
                    "Use": "Application",
                    "Location": location,
                    "Zone": zone,
                    "Application": "NA",
                    "Device": device,
                    "Data": data,
                    "Time": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                }, None)
            Thread(target=self.Blockchain.storeHash,
                   args=(str(_id), self.Blockchain.hashLifeData(data),
                         int(time.time()), locationID, device, bcAddress,
                         "Device"),
                   daemon=True).start()
            self.Helpers.logger.info("Device " + device + " status update OK")
        else:
            self.Helpers.logger.error("Device " + device + " life update KO")

    def deviceCommandsCallback(self, topic, payload):
        """
		iotJumpWay Device Commands Callback

		The callback function that is triggerend in the event of an device
		command communication from the iotJumpWay.
		"""

        self.Helpers.logger.info("Recieved iotJumpWay Device Command Data: " +
                                 payload.decode())

        command = json.loads(payload.decode("utf-8"))
        splitTopic = topic.split("/")

        location = splitTopic[0]
        zone = splitTopic[2]
        device = splitTopic[3]

        requiredAttributes = self.ContextBroker.getRequiredAttributes(
            device, "Device")

        locationID = int(requiredAttributes["Data"]["lid"]["value"])
        bcAddress = requiredAttributes["Data"]["blockchain"]["address"]

        if not self.Blockchain.iotJumpWayAccessCheck(bcAddress):
            return

        _id = self.MongoDB.insertData(
            self.MongoDB.mongoConn.Commands, {
                "Use": "Device",
                "Location": location,
                "Zone": zone,
                "From": command["From"],
                "To": device,
                "Type": command["Type"],
                "Value": command["Value"],
                "Message": command["Message"],
                "Time": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            }, None)

        Thread(target=self.Blockchain.storeHash,
               args=(str(_id), self.Blockchain.hashCommand(command),
                     int(time.time()), locationID, device, bcAddress,
                     "Device"),
               daemon=True).start()
        self.Helpers.logger.info("Device " + device + " command update OK")

    def deviceNfcCallback(self, topic, payload):
        """
		iotJumpWay Device NFC Callback

		The callback function that is triggered in the event of a device
		NFC communication from the iotJumpWay.
		"""

        self.Helpers.logger.info("Recieved iotJumpWay Device NFC Data: " +
                                 payload.decode())

        data = json.loads(payload.decode("utf-8"))
        splitTopic = topic.split("/")

        location = splitTopic[0]
        zone = splitTopic[2]
        device = splitTopic[3]

        requiredAttributes = self.ContextBroker.getRequiredAttributes(
            device, "Device")

        locationID = int(requiredAttributes["Data"]["lid"]["value"])
        bcAddress = requiredAttributes["Data"]["blockchain"]["address"]

        if not self.Blockchain.iotJumpWayAccessCheck(bcAddress):
            return

        check = self.ContextBroker.getNFC(data["Value"])
        if check["Response"] is "OK" and len(check["Data"]):
            self.Application.appDeviceChannelPub(
                "Commands", zone, device, {
                    "From":
                    str(self.Helpers.confs["iotJumpWay"]["MQTT"]["Agent"]
                        ["aid"]),
                    "Type":
                    "NFC",
                    "Value":
                    "Not Authorized",
                    "Message":
                    "NFC Chip Not Authorized"
                })
            self.Helpers.logger.info("Device " + device +
                                     " NFC Not Allowed KO")
            return

        _id = self.MongoDB.insertData(
            self.MongoDB.mongoConn.NFC, {
                "Use": "Device",
                "Location": location,
                "Zone": zone,
                "Application": 0,
                "Device": device,
                "Sensor": data["Sensor"],
                "Value": data["Value"],
                "Message": data["Message"],
                "Time": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            }, None)

        self.Application.appDeviceChannelPub(
            "Commands", zone, device, {
                "From":
                str(self.Helpers.confs["iotJumpWay"]["MQTT"]["Agent"]["aid"]),
                "Type":
                "NFC",
                "Value":
                "Authorized",
                "Message":
                "NFC Chip Authorized"
            })

        Thread(target=self.Blockchain.storeHash,
               args=(str(_id), self.Blockchain.hashNfc(data), int(time.time()),
                     locationID, device, bcAddress, "Device"),
               daemon=True).start()
        self.Helpers.logger.info("Device " + device + " NFC Allowed OK")

    def deviceSensorCallback(self, topic, payload):
        """
		iotJumpWay Application Sensors Callback

		The callback function that is triggered in the event of an device
		sensor communication from the iotJumpWay.
		"""

        self.Helpers.logger.info("Recieved iotJumpWay Device Sensors Data : " +
                                 payload.decode())

        data = json.loads(payload.decode("utf-8"))
        splitTopic = topic.split("/")

        location = splitTopic[0]
        zone = splitTopic[2]
        device = splitTopic[3]

        requiredAttributes = self.ContextBroker.getRequiredAttributes(
            device, "Device")

        locationID = int(requiredAttributes["Data"]["lid"]["value"])
        bcAddress = requiredAttributes["Data"]["blockchain"]["address"]

        if not self.Blockchain.iotJumpWayAccessCheck(bcAddress):
            return

        _id = self.MongoDB.insertData(
            self.MongoDB.mongoConn.Sensors, {
                "Use": "Device",
                "Location": location,
                "Zone": zone,
                "Application": 0,
                "Device": device,
                "Sensor": data["Sensor"],
                "Type": data["Type"],
                "Value": data["Value"],
                "Message": data["Message"],
                "Time": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            }, None)

        Thread(target=self.Blockchain.storeHash,
               args=(str(_id), self.Blockchain.hashSensorData(data),
                     int(time.time()), locationID, device, bcAddress,
                     "Device"),
               daemon=True).start()
        self.Helpers.logger.info("Device " + device + " NFC Allowed OK")

    def respond(self, responseCode, response):
        """ Builds the request repsonse """

        return Response(response=json.dumps(response, indent=4),
                        status=responseCode,
                        mimetype="application/json")

    def signal_handler(self, signal, frame):
        self.Helpers.logger.info("Disconnecting")
        self.Application.appDisconnect()
        sys.exit(1)
Example #3
0
class iotJumpWay():
    """ iotJumpWay Class

	The iotJumpWay Class listens for data from the network and
	stores it in the Mongo db.
	"""
    def __init__(self):
        """ Initializes the class. """

        self.Helpers = Helpers("GeniSysAI")
        self.Helpers.logger.info("GeniSysAI Class initialization complete.")

    def startIoT(self):
        """ Initiates the iotJumpWay connection class. """

        self.Application = Application({
            "host":
            self.Helpers.confs["iotJumpWay"]["host"],
            "port":
            self.Helpers.confs["iotJumpWay"]["port"],
            "lid":
            self.Helpers.confs["iotJumpWay"]["lid"],
            "aid":
            self.Helpers.confs["iotJumpWay"]["paid"],
            "an":
            self.Helpers.confs["iotJumpWay"]["pan"],
            "un":
            self.Helpers.confs["iotJumpWay"]["pun"],
            "pw":
            self.Helpers.confs["iotJumpWay"]["ppw"]
        })
        self.Application.connect()

        self.Application.appChannelSub("#", "#")
        self.Application.appDeviceChannelSub("#", "#", "#")

        self.Application.appCommandsCallback = self.appCommandsCallback
        self.Application.appLifeCallback = self.appLifeCallback
        self.Application.appSensorCallback = self.appSensorCallback
        self.Application.appStatusCallback = self.appStatusCallback
        self.Application.appTriggerCallback = self.appTriggerCallback
        self.Application.deviceCameraCallback = self.deviceCameraCallback
        self.Application.deviceCommandsCallback = self.deviceCommandsCallback
        self.Application.deviceNfcCallback = self.deviceNfcCallback
        self.Application.deviceSensorCallback = self.deviceSensorCallback
        self.Application.deviceStatusCallback = self.deviceStatusCallback
        self.Application.deviceTriggerCallback = self.deviceTriggerCallback
        self.Application.deviceLifeCallback = self.deviceLifeCallback

        self.Helpers.logger.info("GeniSysAI Class initialization complete.")

    def mySqlConn(self):
        """ Initiates the MySQL connection class. """

        self.MySQL = MySQL()
        self.MySQL.startMySQL()

    def mongoDbConn(self):
        """ Initiates the MongoDB connection class. """

        self.MongoDB = MongoDB()
        self.MongoDB.startMongoDB()

    def blockchainConn(self):
        """ Initiates the Blockchain connection class. """

        self.Blockchain = Blockchain()
        self.Blockchain.startBlockchain()
        self.Blockchain.w3.geth.personal.unlockAccount(
            self.Helpers.confs["ethereum"]["haddress"],
            self.Helpers.confs["ethereum"]["hpass"], 0)
        self.Blockchain.w3.geth.personal.unlockAccount(
            self.Helpers.confs["ethereum"]["iaddress"],
            self.Helpers.confs["ethereum"]["ipass"], 0)

    def life(self):
        """ Sends vital statistics to HIAS """

        cpu = psutil.cpu_percent()
        mem = psutil.virtual_memory()[2]
        hdd = psutil.disk_usage('/').percent
        tmp = psutil.sensors_temperatures()['coretemp'][0].current
        r = requests.get('http://ipinfo.io/json?token=' +
                         self.Helpers.confs["iotJumpWay"]["ipinfo"])
        data = r.json()
        location = data["loc"].split(',')

        self.Helpers.logger.info("GeniSysAI Life (TEMPERATURE): " + str(tmp) +
                                 "\u00b0")
        self.Helpers.logger.info("GeniSysAI Life (CPU): " + str(cpu) + "%")
        self.Helpers.logger.info("GeniSysAI Life (Memory): " + str(mem) + "%")
        self.Helpers.logger.info("GeniSysAI Life (HDD): " + str(hdd) + "%")
        self.Helpers.logger.info("GeniSysAI Life (LAT): " + str(location[0]))
        self.Helpers.logger.info("GeniSysAI Life (LNG): " + str(location[1]))

        # Send iotJumpWay notification
        self.Application.appChannelPub(
            "Life", self.Helpers.confs["iotJumpWay"]["paid"], {
                "CPU": str(cpu),
                "Memory": str(mem),
                "Diskspace": str(hdd),
                "Temperature": str(tmp),
                "Latitude": float(location[0]),
                "Longitude": float(location[1])
            })

        threading.Timer(300.0, self.life).start()

    def appStatusCallback(self, topic, payload):
        """
		iotJumpWay Application Status Callback

		The callback function that is triggerend in the event of an application
		status communication from the iotJumpWay.
		"""

        self.Helpers.logger.info("Recieved iotJumpWay Application Status: " +
                                 payload.decode())

        splitTopic = topic.split("/")
        status = payload.decode()

        application = self.MySQL.getApplication(splitTopic[2])

        if not self.Blockchain.iotJumpWayAccessCheck(application[12]):
            return

        self.MySQL.updateApplicationStatus(status, splitTopic)

        _id = self.MongoDB.insertData(
            self.MongoDB.mongoConn.Statuses, {
                "Use": "Application",
                "Location": splitTopic[0],
                "Zone": 0,
                "Application": splitTopic[2],
                "Device": 0,
                "Status": status,
                "Time": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            })

        Thread(target=self.Blockchain.storeHash,
               args=(str(_id), self.Blockchain.hashStatus(status),
                     int(time.time()), int(splitTopic[2]), application[10],
                     application[12], "App"),
               daemon=True).start()

    def appLifeCallback(self, topic, payload):
        """
		iotJumpWay Application Life Callback

		The callback function that is triggerend in the event of a application
		life communication from the iotJumpWay.
		"""

        self.Helpers.logger.info(
            "Recieved iotJumpWay Application Life Data: " + payload.decode())

        data = json.loads(payload.decode("utf-8"))
        splitTopic = topic.split("/")

        application = self.MySQL.getApplication(splitTopic[2])

        if not self.Blockchain.iotJumpWayAccessCheck(application[12]):
            return

        self.MySQL.updateApplication("Life", data, splitTopic)

        _id = self.MongoDB.insertData(
            self.MongoDB.mongoConn.Life, {
                "Use": "Application",
                "Location": splitTopic[0],
                "Zone": 0,
                "Application": splitTopic[2],
                "Device": 0,
                "Data": data,
                "Time": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            })

        Thread(target=self.Blockchain.storeHash,
               args=(str(_id), self.Blockchain.hashLifeData(data),
                     int(time.time()), int(splitTopic[2]), application[10],
                     application[12], "App"),
               daemon=True).start()

    def appCommandsCallback(self, topic, payload):
        """
		iotJumpWay Application Commands Callback

		The callback function that is triggerend in the event of an application
		command communication from the iotJumpWay.
		"""

        self.Helpers.logger.info(
            "Recieved iotJumpWay Application Command Data: " +
            payload.decode())

        command = json.loads(payload.decode("utf-8"))
        splitTopic = topic.split("/")

        self.MongoDB.insertData(
            self.MongoDB.mongoConn.Commands, {
                "Use": "Application",
                "Location": splitTopic[0],
                "Zone": 0,
                "From": command["From"],
                "To": splitTopic[3],
                "Type": command["Type"],
                "Value": command["Value"],
                "Message": command["Message"],
                "Time": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            })

    def appSensorCallback(self, topic, payload):
        """
		iotJumpWay Application Sensors Callback

		The callback function that is triggerend in the event of an application
		sensor communication from the iotJumpWay.
		"""

        self.Helpers.logger.info(
            "Recieved iotJumpWay Application Sensors Data: " +
            payload.decode())
        command = json.loads(payload.decode("utf-8"))

        splitTopic = topic.split("/")

        self.MongoDB.insertData(
            self.MongoDB.mongoConn.Sensors, {
                "Use": "Application",
                "Location": splitTopic[0],
                "Zone": 0,
                "Application": splitTopic[2],
                "Device": 0,
                "Sensor": command["Sensor"],
                "Type": command["Type"],
                "Value": command["Value"],
                "Message": command["Message"],
                "Time": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            })

    def appTriggerCallback(self, topic, payload):
        """
		iotJumpWay Application Trigger Callback

		The callback function that is triggerend in the event of an application
		trigger communication from the iotJumpWay.
		"""

        self.Helpers.logger.info(
            "Recieved iotJumpWay Application Trigger Data: " +
            payload.decode())
        command = json.loads(payload.decode("utf-8"))

    def deviceStatusCallback(self, topic, payload):
        """
		iotJumpWay Device Status Callback

		The callback function that is triggerend in the event of an device
		status communication from the iotJumpWay.
		"""

        self.Helpers.logger.info("Recieved iotJumpWay Device Status Data: " +
                                 payload.decode())

        splitTopic = topic.split("/")
        status = payload.decode()

        device = self.MySQL.getDevice(splitTopic[3])

        if not self.Blockchain.iotJumpWayAccessCheck(device[8]):
            return

        self.MySQL.updateDeviceStatus(status, splitTopic[3])

        _id = self.MongoDB.insertData(
            self.MongoDB.mongoConn.Statuses, {
                "Use": "Device",
                "Location": splitTopic[0],
                "Zone": splitTopic[2],
                "Application": 0,
                "Device": splitTopic[3],
                "Status": status,
                "Time": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            })

        Thread(target=self.Blockchain.storeHash,
               args=(str(_id), self.Blockchain.hashStatus(status),
                     int(time.time()), int(splitTopic[3]), device[10],
                     device[8], "Device"),
               daemon=True).start()

    def deviceLifeCallback(self, topic, payload):
        """
		iotJumpWay Device Life Callback

		The callback function that is triggerend in the event of a device
		life communication from the iotJumpWay.
		"""

        self.Helpers.logger.info("Recieved iotJumpWay Device Life Data : " +
                                 payload.decode())

        data = json.loads(payload.decode("utf-8"))
        splitTopic = topic.split("/")

        device = self.MySQL.getDevice(splitTopic[3])

        if not self.Blockchain.iotJumpWayAccessCheck(device[8]):
            return

        self.MySQL.updateDevice("Life", data, splitTopic[3])

        _id = self.MongoDB.insertData(
            self.MongoDB.mongoConn.Life, {
                "Use": "Device",
                "Location": splitTopic[0],
                "Zone": splitTopic[2],
                "Application": 0,
                "Device": splitTopic[3],
                "Data": data,
                "Time": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            })

        Thread(target=self.Blockchain.storeHash,
               args=(str(_id), self.Blockchain.hashLifeData(data),
                     int(time.time()), int(splitTopic[3]), device[10],
                     device[8], "Device"),
               daemon=True).start()

    def deviceCommandsCallback(self, topic, payload):
        """
		iotJumpWay Application Commands Callback

		The callback function that is triggerend in the event of an device
		command communication from the iotJumpWay.
		"""

        self.Helpers.logger.info("Recieved iotJumpWay Device Command Data: " +
                                 payload.decode())

        command = json.loads(payload.decode("utf-8"))
        splitTopic = topic.split("/")

        device = self.MySQL.getDevice(splitTopic[3])

        if not self.Blockchain.iotJumpWayAccessCheck(device[8]):
            return

        _id = self.MongoDB.insertData(
            self.MongoDB.mongoConn.Commands, {
                "Use": "Device",
                "Location": splitTopic[0],
                "Zone": splitTopic[2],
                "From": command["From"],
                "To": splitTopic[3],
                "Type": command["Type"],
                "Value": command["Value"],
                "Message": command["Message"],
                "Time": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            })

        Thread(target=self.Blockchain.storeHash,
               args=(str(_id), self.Blockchain.hashCommand(command),
                     int(time.time()), int(splitTopic[3]), device[10],
                     device[8], "Device"),
               daemon=True).start()

    def deviceNfcCallback(self, topic, payload):
        """
		iotJumpWay Device NFC Callback

		The callback function that is triggerend in the event of a device
		NFC communication from the iotJumpWay.
		"""

        self.Helpers.logger.info("Recieved iotJumpWay Device NFC Data: " +
                                 payload.decode())
        data = json.loads(payload.decode("utf-8"))
        splitTopic = topic.split("/")

        if not self.MySQL.getUserNFC(data["Value"]):
            # Send iotJumpWay command
            self.Application.appDeviceChannelPub(
                "Commands", splitTopic[2], splitTopic[3], {
                    "From": str(self.Helpers.confs["iotJumpWay"]["paid"]),
                    "Type": "NFC",
                    "Value": "Not Authorized",
                    "Message": "NFC Chip Not Authorized"
                })
            return

        device = self.MySQL.getDevice(splitTopic[3])

        if not self.Blockchain.iotJumpWayAccessCheck(device[8]):
            return

        _id = self.MongoDB.insertData(
            self.MongoDB.mongoConn.NFC, {
                "Use": "Device",
                "Location": splitTopic[0],
                "Zone": splitTopic[2],
                "Application": 0,
                "Device": splitTopic[3],
                "Sensor": data["Sensor"],
                "Value": data["Value"],
                "Message": data["Message"],
                "Time": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            })

        self.Application.appDeviceChannelPub(
            "Commands", splitTopic[2], splitTopic[3], {
                "From": str(splitTopic[3]),
                "Type": "NFC",
                "Value": "Authorized",
                "Message": "NFC Chip Authorized"
            })

        Thread(target=self.Blockchain.storeHash,
               args=(str(_id), self.Blockchain.hashNfc(data), int(time.time()),
                     int(splitTopic[3]), device[10], device[8], "Device"),
               daemon=True).start()

    def deviceSensorCallback(self, topic, payload):
        """
		iotJumpWay Application Sensors Callback

		The callback function that is triggerend in the event of an device
		sensor communication from the iotJumpWay.
		"""

        self.Helpers.logger.info("Recieved iotJumpWay Device Sensors Data : " +
                                 payload.decode())
        data = json.loads(payload.decode("utf-8"))
        splitTopic = topic.split("/")

        device = self.MySQL.getDevice(splitTopic[3])

        if not self.Blockchain.iotJumpWayAccessCheck(device[8]):
            return

        _id = self.MongoDB.insertData(
            self.MongoDB.mongoConn.Sensors, {
                "Use": "Device",
                "Location": splitTopic[0],
                "Zone": splitTopic[2],
                "Application": 0,
                "Device": splitTopic[3],
                "Sensor": data["Sensor"],
                "Type": data["Type"],
                "Value": data["Value"],
                "Message": data["Message"],
                "Time": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            })

        Thread(target=self.Blockchain.storeHash,
               args=(str(_id), self.Blockchain.hashSensorData(data),
                     int(time.time()), int(splitTopic[3]), device[10],
                     device[8], "Device"),
               daemon=True).start()

    def deviceTriggerCallback(self, topic, payload):
        """
		iotJumpWay Application Trigger Callback

		The callback function that is triggerend in the event of an device
		trigger communication from the iotJumpWay.
		"""

        self.Helpers.logger.info("Recieved iotJumpWay Device Trigger Data: " +
                                 payload.decode())
        command = json.loads(payload.decode("utf-8"))

    def deviceCameraCallback(self, topic, payload):
        """
		iotJumpWay Device Camera Callback

		The callback function that is trigge105rend in the event of a camera detecting a
		known user or intruder.
		"""

        self.Helpers.logger.info("Recieved iotJumpWay Device Camera Data: " +
                                 payload.decode())

        data = json.loads(payload.decode("utf-8"))
        splitTopic = topic.split("/")

        nlu = self.MySQL.getNLU(splitTopic)

        if nlu is not "":

            if data["Value"] is not 0:

                self.MySQL.updateUserLocation(splitTopic, data)

                self.MongoDB.insertData(
                    self.MongoDB.mongoConn.Users, {
                        "User": int(data["Value"]),
                        "Location": splitTopic[0],
                        "Zone": splitTopic[2],
                        "Device": splitTopic[3],
                        "Time": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                    })

                userDetails = self.MySQL.getUser(data)

                if userDetails[1] and nlu[0]:
                    self.Application.appDeviceChannelPub(
                        "Commands", splitTopic[2], nlu[0], {
                            "From": str(splitTopic[3]),
                            "Type": "Welcome",
                            "Message": "Welcome " + userDetails[0],
                            "Value": userDetails[0]
                        })
                    self.MySQL.updateUser(data)

                elif userDetails[1] and userDetails[2] is "ONLINE":
                    print("SEND USER APP NOTIFICATION")

    def signal_handler(self, signal, frame):
        self.Helpers.logger.info("Disconnecting")
        self.Application.appDisconnect()
        sys.exit(1)
Example #4
0
class ContextBroker():
    """ HIAS HDSI Context Broker

	The HIAS HDSI Context Broker handles contextual data
	for all iotJumpWay devices/applications and IoT Agents.
	"""
    def __init__(self):
        """ Initializes the class. """

        self.Helpers = Helpers("ContextBroker")
        self.Helpers.logger.info(
            "HIAS iotJumpWay Context Broker initialization complete.")

    def iotConnection(self):
        """ Initiates the iotJumpWay connection. """

        self.Application = Application({
            "host":
            self.Helpers.confs["iotJumpWay"]["host"],
            "port":
            self.Helpers.confs["iotJumpWay"]["ContextBroker"]["iport"],
            "lid":
            self.Helpers.confs["iotJumpWay"]["ContextBroker"]["lid"],
            "aid":
            self.Helpers.confs["iotJumpWay"]["ContextBroker"]["aid"],
            "an":
            self.Helpers.confs["iotJumpWay"]["ContextBroker"]["an"],
            "un":
            self.Helpers.confs["iotJumpWay"]["ContextBroker"]["un"],
            "pw":
            self.Helpers.confs["iotJumpWay"]["ContextBroker"]["pw"]
        })
        self.Application.connect()

    def life(self):
        """ Sends vital statistics to HIAS """

        cpu = psutil.cpu_percent()
        mem = psutil.virtual_memory()[2]
        hdd = psutil.disk_usage('/').percent
        tmp = psutil.sensors_temperatures()['coretemp'][0].current
        r = requests.get('http://ipinfo.io/json?token=' +
                         self.Helpers.confs["iotJumpWay"]["ipinfo"])
        data = r.json()
        location = data["loc"].split(',')

        # Send iotJumpWay notification
        self.Application.appChannelPub(
            "Life", self.Helpers.confs["iotJumpWay"]["MQTT"]["Agent"]["aid"], {
                "CPU": str(cpu),
                "Memory": str(mem),
                "Diskspace": str(hdd),
                "Temperature": str(tmp),
                "Latitude": float(location[0]),
                "Longitude": float(location[1])
            })

        self.Helpers.logger.info("Broker life statistics published.")
        threading.Timer(300.0, self.life).start()

    def mongoDbConnection(self):
        """ Initiates the MongoDB connection class. """

        self.MongoDB = MongoDB()
        self.MongoDB.startMongoDB()

    def configureBroker(self):
        """ Configures the Context Broker. """

        self.Entities = Entities(self.MongoDB)
        self.Agents = Agents(self.MongoDB)

    def getBroker(self):

        return {
            "Broker": {
                "Version":
                self.Helpers.confs["iotJumpWay"]["ContextBroker"]["version"],
                "Host":
                self.Helpers.confs["iotJumpWay"]["host"],
                "IP":
                self.Helpers.confs["iotJumpWay"]["ip"],
                "Port":
                self.Helpers.confs["iotJumpWay"]["ContextBroker"]["port"],
                "Endpoint":
                self.Helpers.confs["iotJumpWay"]["ContextBroker"]["address"],
                "Locations":
                self.MongoDB.locationsCollection.count_documents(
                    {"type": "Location"}),
                "Zones":
                self.MongoDB.locationsCollection.count_documents(
                    {"type": "Zone"}),
            },
            "Entities": {
                "Applications": {
                    "Count":
                    self.MongoDB.applicationsCollection.count_documents(
                        {"type": "Application"}),
                    "IotAgents":
                    self.MongoDB.applicationsCollection.count_documents({
                        "type":
                        "Application",
                        "category.value.0":
                        "IoT Agent"
                    }),
                    "AiAgents":
                    self.MongoDB.applicationsCollection.count_documents({
                        "type":
                        "Application",
                        "category.value.0":
                        "AI Agent"
                    }),
                    "Staff": {
                        "Administration":
                        self.MongoDB.applicationsCollection.count_documents({
                            "type":
                            "Application",
                            "category.value.0":
                            "Management"
                        }),
                        "Director":
                        self.MongoDB.applicationsCollection.count_documents({
                            "type":
                            "Application",
                            "category.value.0":
                            "Director"
                        }),
                        "Developer":
                        self.MongoDB.applicationsCollection.count_documents({
                            "type":
                            "Application",
                            "category.value.0":
                            "Developer"
                        }),
                        "Doctor":
                        self.MongoDB.applicationsCollection.count_documents({
                            "type":
                            "Application",
                            "category.value.0":
                            "Doctor"
                        }),
                        "Management":
                        self.MongoDB.applicationsCollection.count_documents({
                            "type":
                            "Application",
                            "category.value.0":
                            "Management"
                        }),
                        "Network Security":
                        self.MongoDB.applicationsCollection.count_documents({
                            "type":
                            "Application",
                            "category.value.0":
                            "Network Security"
                        }),
                        "Nurse":
                        self.MongoDB.applicationsCollection.count_documents({
                            "type":
                            "Application",
                            "category.value.0":
                            "Nurse"
                        }),
                        "Security":
                        self.MongoDB.applicationsCollection.count_documents({
                            "type":
                            "Application",
                            "category.value.0":
                            "Security"
                        }),
                        "Supervisor":
                        self.MongoDB.applicationsCollection.count_documents({
                            "type":
                            "Application",
                            "category.value.0":
                            "Supervisor"
                        }),
                        "Cancelled": {
                            "Administration":
                            self.MongoDB.applicationsCollection.
                            count_documents({
                                "type": "Application",
                                "category.value.0": "Management",
                                "cancelled.value": "1"
                            }),
                            "Director":
                            self.MongoDB.applicationsCollection.
                            count_documents({
                                "type": "Application",
                                "category.value.0": "Director",
                                "cancelled.value": "1"
                            }),
                            "Developer":
                            self.MongoDB.applicationsCollection.
                            count_documents({
                                "type": "Application",
                                "category.value.0": "Developer",
                                "cancelled.value": "1"
                            }),
                            "Doctor":
                            self.MongoDB.applicationsCollection.
                            count_documents({
                                "type": "Application",
                                "category.value.0": "Doctor",
                                "cancelled.value": "1"
                            }),
                            "Management":
                            self.MongoDB.applicationsCollection.
                            count_documents({
                                "type": "Application",
                                "category.value.0": "Management",
                                "cancelled.value": "1"
                            }),
                            "Network Security":
                            self.MongoDB.applicationsCollection.
                            count_documents({
                                "type": "Application",
                                "category.value.0": "Network Security",
                                "cancelled.value": "1"
                            }),
                            "Nurse":
                            self.MongoDB.applicationsCollection.
                            count_documents({
                                "type": "Application",
                                "category.value.0": "Nurse",
                                "cancelled.value": "1"
                            }),
                            "Security":
                            self.MongoDB.applicationsCollection.
                            count_documents({
                                "type": "Application",
                                "category.value.0": "Security",
                                "cancelled.value": "1"
                            }),
                            "Supervisor":
                            self.MongoDB.applicationsCollection.
                            count_documents({
                                "type": "Application",
                                "category.value.0": "Supervisor",
                                "cancelled.value": "1"
                            })
                        }
                    }
                },
                "Devices": {
                    "Count":
                    self.MongoDB.devicesCollection.count_documents({}),
                    "Server":
                    self.MongoDB.devicesCollection.count_documents({
                        "type":
                        "Device",
                        "category.value.0":
                        "Server"
                    }),
                    "Camera":
                    self.MongoDB.devicesCollection.count_documents({
                        "type":
                        "Device",
                        "category.value.0":
                        "Camera"
                    }),
                    "Scanner":
                    self.MongoDB.devicesCollection.count_documents({
                        "type":
                        "Device",
                        "category.value.0":
                        "Scanner"
                    }),
                    "Virtual Reality":
                    self.MongoDB.devicesCollection.count_documents({
                        "type":
                        "Device",
                        "category.value.0":
                        "Virtual Reality"
                    }),
                    "Mixed Reality":
                    self.MongoDB.devicesCollection.count_documents({
                        "type":
                        "Device",
                        "category.value.0":
                        "Mixed Reality"
                    }),
                    "Robotics": {
                        "EMAR":
                        self.MongoDB.devicesCollection.count_documents({
                            "type":
                            "Device",
                            "category.value.0":
                            "EMAR"
                        })
                    },
                    "AI": {
                        "GeniSysAI":
                        self.MongoDB.devicesCollection.count_documents({
                            "type":
                            "Device",
                            "category.value.0":
                            "GeniSysAI"
                        }),
                        "TassAI":
                        self.MongoDB.devicesCollection.count_documents({
                            "type":
                            "Device",
                            "category.value.0":
                            "TassAI"
                        }),
                        "AML":
                        self.MongoDB.devicesCollection.count_documents({
                            "type":
                            "Device",
                            "category.value.0":
                            "AMLClassifier"
                        }),
                        "ALL":
                        self.MongoDB.devicesCollection.count_documents({
                            "type":
                            "Device",
                            "category.value.0":
                            "ALLClassifier"
                        }),
                        "COVID":
                        self.MongoDB.devicesCollection.count_documents({
                            "type":
                            "Device",
                            "category.value.0":
                            "COVIDClassifier"
                        }),
                        "Skin":
                        self.MongoDB.devicesCollection.count_documents({
                            "type":
                            "Device",
                            "category.value.0":
                            "SkinCancerClassifier"
                        }),
                    }
                }
            }
        }

    def respond(self, responseCode, response, location=None):
        """ Builds the request repsonse """

        return Response(response=json.dumps(response, indent=4),
                        status=responseCode,
                        mimetype="application/json")

    def signal_handler(self, signal, frame):
        self.Helpers.logger.info("Disconnecting")
        sys.exit(1)