diff --git a/Agents/AMQP.py b/Agents/AMQP.py
new file mode 100644
index 0000000..ee9314d
--- /dev/null
+++ b/Agents/AMQP.py
@@ -0,0 +1,374 @@
+#!/usr/bin/env python3
+######################################################################################################
+#
+# Organization: Peter Moss Leukemia AI Research
+# Repository: HIAS: Hospital Intelligent Automation System
+#
+# Author: Adam Milton-Barker (AdamMiltonBarker.com)
+#
+# Title: iotJumpWay AMQP IoT Agent
+# Description: The AMQP IoT Agent listens for all traffic coming from devices connected to the HIAS
+# HIAS network using the AMQP protocol, translates them into a format compatible with
+# the HIAS iotJumpWay Context Broker and sends the data to the broker for processing
+# and storage.
+# License: MIT License
+# Last Modified: 2020-10-18
+#
+######################################################################################################
+
+
+import os
+import sys
+import time
+
+sys.path.insert(0, os.path.abspath(
+ os.path.join(os.path.dirname(__file__), '..')))
+
+from gevent import monkey
+monkey.patch_all()
+
+import json
+import pika
+import psutil
+import requests
+import signal
+import ssl
+import threading
+
+from datetime import timedelta
+from datetime import datetime
+from flask import Flask, request, Response
+from threading import Thread
+
+from Classes.Helpers import Helpers
+from Classes.Blockchain import Blockchain
+from Classes.ContextBroker import ContextBroker
+from Classes.MongoDB import MongoDB
+
+
+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)
+
+
+app = Flask(__name__)
+AMQP = AMQP()
+
+
+@app.route('/About', methods=['GET'])
+def about():
+ """ Responds to POST requests sent to the North Port About API endpoint. """
+
+ return AMQP.respond(200, {
+ "Identifier": AMQP.Helpers.confs["iotJumpWay"]["MQTT"]["Agent"]["identifier"],
+ "Host": AMQP.Helpers.confs["iotJumpWay"]["ip"],
+ "NorthPort": AMQP.Helpers.confs["iotJumpWay"]["MQTT"]["Agent"]["northPort"],
+ "CPU": psutil.cpu_percent(),
+ "Memory": psutil.virtual_memory()[2],
+ "Diskspace": psutil.disk_usage('/').percent,
+ "Temperature": psutil.sensors_temperatures()['coretemp'][0].current
+ })
+
+
+@app.route('/Commands', methods=['POST'])
+def commands():
+ """ Responds to POST requests sent to the North Port Commands API endpoint. """
+
+ if request.headers["Content-Type"] == "application/json":
+ command = request.json
+ if command["ToType"] is "Device":
+ print("Device Command")
+ elif command["ToType"] is "Application":
+ print("Application Command")
+ else:
+ return AMQP.respond(400, {
+ "Response": "Failed",
+ "Error": "BadRequest",
+ "Description": "Command type not supported!"
+ })
+ else:
+ return AMQP.respond(405, {
+ "Response": "Failed",
+ "Error": "MethodNotAlowed",
+ "Description": "Method not allowed!"
+ })
+
+def main():
+
+ signal.signal(signal.SIGINT, AMQP.signal_handler)
+ signal.signal(signal.SIGTERM, AMQP.signal_handler)
+
+ # Starts the IoT Agent
+ AMQP.contextConn()
+ AMQP.mongoDbConn()
+ AMQP.blockchainConnect()
+ AMQP.amqpConnect()
+ AMQP.amqpConsumeSet()
+ AMQP.agentThreads()
+
+ app.run(host=AMQP.Helpers.confs["iotJumpWay"]["ip"],
+ port=AMQP.Helpers.confs["iotJumpWay"]["AMQP"]["northPort"])
+
+if __name__ == "__main__":
+ main()
diff --git a/Agents/MQTT.py b/Agents/MQTT.py
new file mode 100644
index 0000000..e71dec6
--- /dev/null
+++ b/Agents/MQTT.py
@@ -0,0 +1,695 @@
+#!/usr/bin/env python3
+######################################################################################################
+#
+# Organization: Peter Moss Leukemia AI Research
+# Repository: HIAS: Hospital Intelligent Automation System
+#
+# Author: Adam Milton-Barker (AdamMiltonBarker.com)
+#
+# Title: iotJumpWay MQTT IoT Agent
+# Description: The MQTT IoT Agent listens for all traffic coming from devices connected to the HIAS
+# HIAS network using the MQTT & Websocket protocols, translates them into a format
+# compatible with the HIAS iotJumpWay Context Broker and sends the data to the broker
+# for processing and storage.
+# License: MIT License
+# Last Modified: 2020-10-13
+#
+######################################################################################################
+
+import json
+import os
+import psutil
+import requests
+import signal
+import sys
+import time
+import threading
+
+sys.path.insert(0, os.path.abspath(
+ os.path.join(os.path.dirname(__file__), '..')))
+
+from datetime import datetime
+from datetime import timedelta
+
+from flask import Flask, request, Response
+from threading import Thread
+
+from web3 import Web3
+
+from Classes.Helpers import Helpers
+from Classes.ContextBroker import ContextBroker
+from Classes.Blockchain import Blockchain
+from Classes.MQTT import Application
+from Classes.MongoDB import MongoDB
+
+
+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)
+
+app = Flask(__name__)
+MQTT = MQTT()
+
+@app.route('/About', methods=['GET'])
+def about():
+ """ Responds to POST requests sent to the North Port About API endpoint. """
+
+ return MQTT.respond(200, {
+ "Identifier": MQTT.Helpers.confs["iotJumpWay"]["MQTT"]["Agent"]["identifier"],
+ "Host": MQTT.Helpers.confs["iotJumpWay"]["ip"],
+ "NorthPort": MQTT.Helpers.confs["iotJumpWay"]["MQTT"]["Agent"]["northPort"],
+ "CPU": psutil.cpu_percent(),
+ "Memory": psutil.virtual_memory()[2],
+ "Diskspace": psutil.disk_usage('/').percent,
+ "Temperature": psutil.sensors_temperatures()['coretemp'][0].current
+ })
+
+@app.route('/Commands', methods=['POST'])
+def commands():
+ """ Responds to POST requests sent to the North Port Commands API endpoint. """
+
+ if request.headers["Content-Type"] == "application/json":
+ command = request.json
+ if command["ToType"] is "Device":
+ MQTT.Application.appDeviceChannelPub("Commands", command["ToLocation"], command["ToDevice"], {
+ "From": command["From"],
+ "Type": command["FromType"],
+ "Value": command["Value"],
+ "Message": command["Message"]
+ })
+ elif command["ToType"] is "Application":
+ MQTT.Application.appChannelPub("Commands", command["ToApplication"], {
+ "From": command["From"],
+ "Type": command["FromType"],
+ "Value": command["Value"],
+ "Message": command["Message"]
+ })
+ else:
+ return MQTT.respond(400, {
+ "Response": "Failed",
+ "Error": "BadRequest",
+ "Description": "Command type not supported!"
+ })
+ else:
+ return MQTT.respond(405, {
+ "Response": "Failed",
+ "Error": "MethodNotAlowed",
+ "Description": "Method not allowed!"
+ })
+
+def main():
+
+ signal.signal(signal.SIGINT, MQTT.signal_handler)
+ signal.signal(signal.SIGTERM, MQTT.signal_handler)
+
+ # Starts the application
+ MQTT.contextConn()
+ MQTT.mongoDbConn()
+ MQTT.blockchainConn()
+ MQTT.startIoT()
+
+ Thread(target=MQTT.life, args=(), daemon=True).start()
+
+ app.run(host=MQTT.Helpers.confs["iotJumpWay"]["ip"],
+ port=MQTT.Helpers.confs["iotJumpWay"]["MQTT"]["Agent"]["northPort"])
+
+if __name__ == "__main__":
+ main()
diff --git a/Classes/Blockchain.py b/Classes/Blockchain.py
index 570cf21..22584e8 100644
--- a/Classes/Blockchain.py
+++ b/Classes/Blockchain.py
@@ -1,14 +1,16 @@
+#!/usr/bin/env python3
######################################################################################################
#
-# Organization: Peter Moss Leukemia AI Research
+# Organization: Asociacion De Investigacion En Inteligencia Artificial Para La Leucemia Peter Moss
# Repository: HIAS: Hospital Intelligent Automation System
+# Module: Blockchain
#
# Author: Adam Milton-Barker (AdamMiltonBarker.com)
#
# Title: Blockchain Class
# Description: Handles communication with the HIAS Blockchain.
# License: MIT License
-# Last Modified: 2020-09-20
+# Last Modified: 2020-10-18
#
######################################################################################################
@@ -21,7 +23,6 @@
from web3 import Web3
from Classes.Helpers import Helpers
-from Classes.MySQL import MySQL
class Blockchain():
@@ -40,17 +41,14 @@ def __init__(self):
self.Helpers.logger.info("Blockchain Class initialization complete.")
def startBlockchain(self):
- """ Connects to MySQL database. """
+ """ Connects to HIAS Blockchain. """
self.w3 = Web3(Web3.HTTPProvider(self.Helpers.confs["ethereum"]["bchost"], request_kwargs={
- 'auth': HTTPBasicAuth(self.Helpers.confs["ethereum"]["user"], self.Helpers.confs["ethereum"]["pass"])}))
-
- self.authContract = self.w3.eth.contract(self.w3.toChecksumAddress(
- self.Helpers.confs["ethereum"]["authContract"]), abi=json.dumps(self.Helpers.confs["ethereum"]["authAbi"]))
- self.iotContract = self.w3.eth.contract(self.w3.toChecksumAddress(
- self.Helpers.confs["ethereum"]["iotContract"]), abi=json.dumps(self.Helpers.confs["ethereum"]["iotAbi"]))
- self.patientsContract = self.w3.eth.contract(self.w3.toChecksumAddress(
- self.Helpers.confs["ethereum"]["patientsContract"]), abi=json.dumps(self.Helpers.confs["ethereum"]["patientsAbi"]))
+ 'auth': HTTPBasicAuth(self.Helpers.confs["iotJumpWay"]["identifier"], self.Helpers.confs["iotJumpWay"]["auth"])}))
+
+ self.authContract = self.w3.eth.contract(self.w3.toChecksumAddress(self.Helpers.confs["ethereum"]["authContract"]), abi=json.dumps(self.Helpers.confs["ethereum"]["authAbi"]))
+ self.iotContract = self.w3.eth.contract(self.w3.toChecksumAddress(self.Helpers.confs["ethereum"]["iotContract"]), abi=json.dumps(self.Helpers.confs["ethereum"]["iotAbi"]))
+ self.patientsContract = self.w3.eth.contract(self.w3.toChecksumAddress(self.Helpers.confs["ethereum"]["patientsContract"]), abi=json.dumps(self.Helpers.confs["ethereum"]["patientsAbi"]))
self.Helpers.logger.info("Blockchain connections started")
def hiasAccessCheck(self, typeof, identifier):
@@ -79,8 +77,8 @@ def getBalance(self, contract):
return balance
except:
e = sys.exc_info()
- self.Helpers.logger.info("Get Balance Failed!")
- self.Helpers.logger.info(str(e))
+ self.Helpers.logger.error("Get Balance Failed!")
+ self.Helpers.logger.error(str(e))
return False
def hashCommand(self, data):
@@ -107,8 +105,7 @@ def hashLifeData(self, data):
""" Hashes the data for data integrity. """
hasher = str(data["CPU"]) + str(data["Memory"]) + str(data["Diskspace"]) + \
- str(data["Temperature"]) + \
- str(data["Latitude"]) + str(data["Longitude"])
+ str(data["Temperature"]) + str(data["Latitude"]) + str(data["Longitude"])
return bcrypt.hashpw(hasher.encode(), bcrypt.gensalt())
@@ -129,15 +126,18 @@ def replenish(self, contract, to, replenish):
"gas": 1000000,
"value": self.w3.toWei(replenish, "ether")})
self.Helpers.logger.info("HIAS Blockchain Replenish Transaction OK! ")
- self.Helpers.logger.info(tx_hash)
- tx_receipt = self.w3.eth.waitForTransactionReceipt(tx_hash)
- self.Helpers.logger.info("HIAS Blockchain Replenish OK!")
- self.Helpers.logger.info(str(tx_receipt))
+ #self.Helpers.logger.info(tx_hash)
+ txr = self.w3.eth.waitForTransactionReceipt(tx_hash)
+ if txr["status"] is 1:
+ self.Helpers.logger.info("HIAS Blockchain Data Hash OK!")
+ #self.Helpers.logger.info(str(txr))
+ else:
+ self.Helpers.logger.error("HIAS Blockchain Data Hash KO!")
return True
except:
e = sys.exc_info()
- self.Helpers.logger.info("HIAS Blockchain Replenish Failed! ")
- self.Helpers.logger.info(str(e))
+ self.Helpers.logger.error("HIAS Blockchain Replenish Failed! ")
+ self.Helpers.logger.error(str(e))
return False
def storeHash(self, dbid, hashed, at, inserter, identifier, to, typeof):
@@ -148,13 +148,16 @@ def storeHash(self, dbid, hashed, at, inserter, identifier, to, typeof):
"from": self.w3.toChecksumAddress(self.Helpers.confs["ethereum"]["iaddress"]),
"gas": 1000000})
self.Helpers.logger.info("HIAS Blockchain Data Transaction OK!")
- self.Helpers.logger.info(txh)
+ #self.Helpers.logger.info(txh)
txr = self.w3.eth.waitForTransactionReceipt(txh)
- self.Helpers.logger.info("HIAS Blockchain Data Hash OK!")
- self.Helpers.logger.info(str(txr))
+ if txr["status"] is 1:
+ self.Helpers.logger.info("HIAS Blockchain Data Hash OK!")
+ #self.Helpers.logger.info(str(txr))
+ else:
+ self.Helpers.logger.error("HIAS Blockchain Data Hash KO!")
except:
e = sys.exc_info()
- self.Helpers.logger.info("HIAS Blockchain Data Hash Failed!")
- self.Helpers.logger.info(str(e))
- self.Helpers.logger.info(str(e))
+ self.Helpers.logger.error("HIAS Blockchain Data Hash KO!")
+ self.Helpers.logger.error(str(e))
+ self.Helpers.logger.error(str(e))
diff --git a/Classes/ContextBroker.py b/Classes/ContextBroker.py
new file mode 100644
index 0000000..455297a
--- /dev/null
+++ b/Classes/ContextBroker.py
@@ -0,0 +1,86 @@
+#!/usr/bin/env python3
+######################################################################################################
+#
+# Organization: Peter Moss Leukemia AI Research
+# Repository: HIAS: Hospital Intelligent Automation System
+#
+# Author: Adam Milton-Barker (AdamMiltonBarker.com)
+#
+# Title: HIAS Context Broker Helpers
+# Description: Helper functions that allow the HIAS iotAgents to communicate with the Context
+# Broker.
+# License: MIT License
+# Last Modified: 2020-10-18
+#
+######################################################################################################
+
+import json
+import requests
+
+from Classes.Helpers import Helpers
+
+
+class ContextBroker():
+ """ HIAS Context Broker Helpers
+
+ Helper functions that allow the HIAS iotAgents
+ to communicate with the Context Broker.
+ """
+
+ def __init__(self):
+ """ Initializes the class. """
+
+ self.Helpers = Helpers("ContextBroker")
+ self.headers = {"content-type": 'application/json'}
+ self.Helpers.logger.info("Context Broker initialization complete.")
+
+ def getRequiredAttributes(self, _id, typeof):
+ """ Gets required attributes. """
+
+ if typeof is "Application":
+ params = "&attrs = blockchain.address, lid.value, lid.entity"
+ else:
+ params = "&attrs = blockchain.address, lid.value, lid.entity, zid.entity"
+
+ apiUrl = "https://" + self.Helpers.confs["iotJumpWay"]["host"] + "/" + self.Helpers.confs["iotJumpWay"]["ContextBroker"]["address"] + "/entities/" + _id + "?type=" + typeof + "&attrs=blockchain.address,lid.value,lid.entity"
+
+ response = requests.get(apiUrl, headers=self.headers, auth=(
+ self.Helpers.confs["iotJumpWay"]["identifier"], self.Helpers.confs["iotJumpWay"]["auth"]))
+
+ return json.loads(response.text)
+
+ def getNFC(self, nfc):
+ """ Gets required attributes. """
+
+ apiUrl = "https://" + self.Helpers.confs["iotJumpWay"]["host"] + "/" + \
+ self.Helpers.confs["iotJumpWay"]["ContextBroker"]["address"] + \
+ "/entities?type=Staff&values=nfc.value|nfc"
+
+ response = requests.get(apiUrl, headers=self.headers, auth=(
+ self.Helpers.confs["iotJumpWay"]["identifier"], self.Helpers.confs["iotJumpWay"]["auth"]))
+
+ return json.loads(response.text)
+
+ def getNLU(self, zone):
+ """ Gets required attributes. """
+
+ apiUrl = "https://" + self.Helpers.confs["iotJumpWay"]["host"] + "/" + \
+ self.Helpers.confs["iotJumpWay"]["ContextBroker"]["address"] + \
+ "/entities?type=Device&category.value=GeniSysAI&values=zid.value|" + zone + ",status|ONLINE"
+
+ response = requests.get(apiUrl, headers=self.headers, auth=(
+ self.Helpers.confs["iotJumpWay"]["identifier"], self.Helpers.confs["iotJumpWay"]["auth"]))
+
+ return json.loads(response.text)
+
+ def updateEntity(self, _id, typeof, data):
+ """ Updates an entity. """
+
+ apiUrl = "https://" + self.Helpers.confs["iotJumpWay"]["host"] + "/" + \
+ self.Helpers.confs["iotJumpWay"]["ContextBroker"]["address"] + \
+ "/entities/" + _id + "/attrs?type=" + typeof
+
+ response = requests.patch(apiUrl, data=json.dumps(data), headers=self.headers, auth=(
+ self.Helpers.confs["iotJumpWay"]["identifier"], self.Helpers.confs["iotJumpWay"]["auth"]))
+
+ return json.loads(response.text)
diff --git a/Classes/Helpers.py b/Classes/Helpers.py
index 0cdd849..8fe6662 100644
--- a/Classes/Helpers.py
+++ b/Classes/Helpers.py
@@ -1,7 +1,8 @@
######################################################################################################
#
-# Organization: Peter Moss Leukemia AI Research
+# Organization: Asociacion De Investigacion En Inteligencia Artificial Para La Leucemia Peter Moss
# Repository: HIAS: Hospital Intelligent Automation System
+# Project: GeniSysAI
#
# Author: Adam Milton-Barker (AdamMiltonBarker.com)
# Contributors:
diff --git a/Classes/MQTT.py b/Classes/MQTT.py
new file mode 100644
index 0000000..3cbd11f
--- /dev/null
+++ b/Classes/MQTT.py
@@ -0,0 +1,344 @@
+#!/usr/bin/env python3
+######################################################################################################
+#
+# Organization: Peter Moss Leukemia AI Research
+# Repository: HIAS: Hospital Intelligent Automation System
+#
+# Author: Adam Milton-Barker (AdamMiltonBarker.com)
+#
+# Title: iotJumpWay MQTT
+# Description: iotJumpWay Device & Application MQTT connection classes for HIAS.
+# License: MIT License
+# Last Modified: 2020-10-17
+#
+######################################################################################################
+
+import inspect, json, os
+
+import paho.mqtt.client as mqtt
+
+from Classes.Helpers import Helpers
+
+class Application():
+ """ iotJumpWay Class
+
+ The iotJumpWay Class provides the Hospital Intelligent Automation System with
+ it's IoT functionality.
+ """
+
+ def __init__(self, configs):
+ """ Initializes the class. """
+
+ self.Helpers = Helpers("iotJumpWay")
+ self.confs = configs
+
+ self.Helpers.logger.info("Initiating Local iotJumpWay Application.")
+
+ if self.confs['host'] == None:
+ raise ConfigurationException("** Host (host) property is required")
+ elif self.confs['port'] == None:
+ raise ConfigurationException("** Port (port) property is required")
+ elif self.confs['lid'] == None:
+ raise ConfigurationException("** Location ID (lid) property is required")
+ elif self.confs['aid'] == None:
+ raise ConfigurationException("** Application ID (aid) property is required")
+ elif self.confs['an'] == None:
+ raise ConfigurationException("** Application Name (an) property is required")
+ elif self.confs['un'] == None:
+ raise ConfigurationException("** MQTT UserName (un) property is required")
+ elif self.confs['pw'] == None:
+ raise ConfigurationException("** MQTT Password (pw) property is required")
+
+ self.mqttClient = None
+ self.mqttTLS = "/etc/ssl/certs/DST_Root_CA_X3.pem"
+ self.mqttHost = self.confs['host']
+ self.mqttPort = self.confs['port']
+
+ self.appCommandsCallback = None
+ self.appSensorCallback = None
+ self.appStatusCallback = None
+ self.appTriggerCallback = None
+ self.appLifeCallback = None
+ self.deviceCameraCallback = None
+ self.deviceCommandsCallback = None
+ self.deviceLifeCallback = None
+ self.deviceNfcCallback = None
+ self.deviceSensorCallback = None
+ self.deviceStatusCallback = None
+ self.deviceTriggerCallback = None
+
+ self.Helpers.logger.info("Local iotJumpWay Application Initiated.")
+
+ def connect(self):
+
+ self.Helpers.logger.info("Initiating Local iotJumpWay Application Connection.")
+
+ self.mqttClient = mqtt.Client(client_id = self.confs['an'], clean_session = True)
+ applicationStatusTopic = '%s/Applications/%s/Status' % (self.confs['lid'], self.confs['aid'])
+ self.mqttClient.will_set(applicationStatusTopic, "OFFLINE", 0, False)
+ self.mqttClient.tls_set(self.mqttTLS, certfile=None, keyfile=None)
+ self.mqttClient.on_connect = self.on_connect
+ self.mqttClient.on_message = self.on_message
+ self.mqttClient.on_publish = self.on_publish
+ self.mqttClient.on_subscribe = self.on_subscribe
+ self.mqttClient.username_pw_set(str(self.confs['un']), str(self.confs['pw']))
+ self.mqttClient.connect(self.mqttHost, self.mqttPort, 10)
+ self.mqttClient.loop_start()
+
+ self.Helpers.logger.info("Local iotJumpWay Application Connection Initiated.")
+
+ def on_connect(self, client, obj, flags, rc):
+
+ self.Helpers.logger.info("Local iotJumpWay Application Connection Successful.")
+ self.Helpers.logger.info("rc: " + str(rc))
+
+ self.appStatusPub("ONLINE")
+
+ def appStatusPub(self, data):
+
+ deviceStatusTopic = '%s/Applications/%s/Status' % (self.confs['lid'], self.confs['aid'])
+ self.mqttClient.publish(deviceStatusTopic, data)
+ self.Helpers.logger.info("Published to Application Status " + deviceStatusTopic)
+
+ def on_subscribe(self, client, obj, mid, granted_qos):
+
+ self.Helpers.logger.info("Local iotJumpWay Subscription: "+str(self.confs['an']))
+
+ def on_message(self, client, obj, msg):
+
+ self.Helpers.logger.info("Local iotJumpWay Message Received")
+ splitTopic=msg.topic.split("/")
+
+ if splitTopic[1]=='Applications':
+ if splitTopic[3]=='Status':
+ if self.appStatusCallback == None:
+ self.Helpers.logger.info("** Application Status Callback Required (appStatusCallback)")
+ else:
+ self.appStatusCallback(msg.topic,msg.payload)
+ elif splitTopic[3]=='Command':
+ if self.cameraCallback == None:
+ self.Helpers.logger.info("** Application Camera Callback Required (cameraCallback)")
+ else:
+ self.cameraCallback(msg.topic,msg.payload)
+ elif splitTopic[3]=='Life':
+ if self.appLifeCallback == None:
+ self.Helpers.logger.info("** Application Life Callback Required (appLifeCallback)")
+ else:
+ self.appLifeCallback(msg.topic,msg.payload)
+ elif splitTopic[1] == 'Devices':
+ if splitTopic[4] == 'Actuators':
+ if self.deviceActuatorCallback == None:
+ self.Helpers.logger.info("** Device Actuator Callback Required (deviceActuatorCallback)")
+ else:
+ self.deviceActuatorCallback(msg.topic, msg.payload)
+ elif splitTopic[4]=='Commands':
+ if self.deviceCommandsCallback == None:
+ self.Helpers.logger.info("** Device Commands Callback Required (deviceCommandsCallback)")
+ else:
+ self.deviceCommandsCallback(msg.topic,msg.payload)
+ elif splitTopic[4]=='Life':
+ if self.deviceLifeCallback == None:
+ self.Helpers.logger.info("** Device Life Callback Required (deviceLifeCallback)")
+ else:
+ self.deviceLifeCallback(msg.topic, msg.payload)
+ elif splitTopic[4]=='NFC':
+ if self.deviceNfcCallback == None:
+ self.Helpers.logger.info("** Device NFC Callback Required (deviceNfcCallback)")
+ else:
+ self.deviceNfcCallback(msg.topic, msg.payload)
+ elif splitTopic[4] == 'Status':
+ if self.deviceStatusCallback == None:
+ self.Helpers.logger.info("** Device Status Callback Required (deviceStatusCallback)")
+ else:
+ self.deviceStatusCallback(msg.topic, msg.payload)
+ elif splitTopic[4]=='Sensors':
+ if self.deviceSensorCallback == None:
+ self.Helpers.logger.info("** Device Sensors Callback Required (deviceSensorCallback)")
+ else:
+ self.deviceSensorCallback(msg.topic,msg.payload)
+ elif splitTopic[4]=='Notifications':
+ if self.deviceNotificationsCallback == None:
+ self.Helpers.logger.info("** Device Notifications Callback Required (deviceNotificationsCallback)")
+ else:
+ self.deviceNotificationsCallback(msg.topic,msg.payload)
+ elif splitTopic[4]=='Cameras':
+ if self.deviceCameraCallback == None:
+ self.Helpers.logger.info("** Device Camera Callback Required (cameraCallback)")
+ else:
+ self.deviceCameraCallback(msg.topic,msg.payload)
+
+ def appChannelPub(self, channel, application, data):
+
+ applicationChannel = '%s/Applications/%s/%s' % (self.confs['lid'], application, channel)
+ self.mqttClient.publish(applicationChannel,json.dumps(data))
+ self.Helpers.logger.info("Published to Application "+channel+" Channel")
+
+ def appChannelSub(self, application, channelID, qos=0):
+
+ if application == "#":
+ applicationChannel = '%s/Applications/#' % (self.confs['lid'])
+ self.mqttClient.subscribe(applicationChannel, qos=qos)
+ self.Helpers.logger.info("-- Subscribed to all Application Channels")
+ return True
+ else:
+ applicationChannel = '%s/Applications/%s/%s' % (self.confs['lid'], application, channelID)
+ self.mqttClient.subscribe(applicationChannel, qos=qos)
+ self.Helpers.logger.info("-- Subscribed to Application " + channelID + " Channel")
+ return True
+
+ def appDeviceChannelPub(self, channel, zone, device, data):
+
+ deviceChannel = '%s/Devices/%s/%s/%s' % (self.confs['lid'], zone, device, channel)
+ self.mqttClient.publish(deviceChannel, json.dumps(data))
+ self.Helpers.logger.info("-- Published to Device "+channel+" Channel")
+
+ def appDeviceChannelSub(self, zone, device, channel, qos=0):
+
+ if zone == None:
+ print("** Zone ID (zoneID) is required!")
+ return False
+ elif device == None:
+ print("** Device ID (device) is required!")
+ return False
+ elif channel == None:
+ print("** Channel ID (channel) is required!")
+ return False
+ else:
+ if device == "#":
+ deviceChannel = '%s/Devices/#' % (self.confs['lid'])
+ self.mqttClient.subscribe(deviceChannel, qos=qos)
+ self.Helpers.logger.info("-- Subscribed to all devices")
+ else:
+ deviceChannel = '%s/Devices/%s/%s/%s' % (self.confs['lid'], zone, device, channel)
+ self.mqttClient.subscribe(deviceChannel, qos=qos)
+ self.Helpers.logger.info("-- Subscribed to Device "+channel+" Channel")
+
+ return True
+
+ def on_publish(self, client, obj, mid):
+ self.Helpers.logger.info("Published: "+str(mid))
+
+ def on_log(self, client, obj, level, string):
+
+ print(string)
+
+ def appDisconnect(self):
+ self.appStatusPub("OFFLINE")
+ self.mqttClient.disconnect()
+ self.mqttClient.loop_stop()
+
+class Device():
+ """ iotJumpWay Class
+
+ The iotJumpWay Class provides the EMAR device with it's IoT functionality.
+ """
+
+ def __init__(self, configs):
+ """ Initializes the class. """
+
+ self.Helpers = Helpers("iotJumpWay")
+ self.confs = configs
+
+ self.Helpers.logger.info("Initiating Local iotJumpWay Device.")
+
+ if self.confs['host'] == None:
+ raise ConfigurationException("** Host (host) property is required")
+ elif self.confs['port'] == None:
+ raise ConfigurationException("** Port (port) property is required")
+ elif self.confs['lid'] == None:
+ raise ConfigurationException("** Location ID (lid) property is required")
+ elif self.confs['zid'] == None:
+ raise ConfigurationException("** Zone ID (zid) property is required")
+ elif self.confs['did'] == None:
+ raise ConfigurationException("** Device ID (did) property is required")
+ elif self.confs['dn'] == None:
+ raise ConfigurationException("** Device Name (dn) property is required")
+ elif self.confs['un'] == None:
+ raise ConfigurationException("** MQTT UserName (un) property is required")
+ elif self.confs['pw'] == None:
+ raise ConfigurationException("** MQTT Password (pw) property is required")
+
+ self.mqttClient = None
+ self.mqttTLS = "/etc/ssl/certs/DST_Root_CA_X3.pem"
+ self.mqttHost = self.confs['host']
+ self.mqttPort = self.confs['port']
+
+ self.commandsCallback = None
+
+ self.Helpers.logger.info("Local iotJumpWay Device Initiated.")
+
+ def connect(self):
+
+ self.Helpers.logger.info("Initiating Local iotJumpWay Device Connection.")
+
+ self.mqttClient = mqtt.Client(client_id=self.confs['dn'], clean_session=True)
+ deviceStatusTopic = '%s/Device/%s/%s/Status' % (
+ self.confs['lid'], self.confs['zid'], self.confs['did'])
+ self.mqttClient.will_set(deviceStatusTopic, "OFFLINE", 0, False)
+ self.mqttClient.tls_set(self.mqttTLS, certfile=None, keyfile=None)
+ self.mqttClient.on_connect = self.on_connect
+ self.mqttClient.on_message = self.on_message
+ self.mqttClient.on_publish = self.on_publish
+ self.mqttClient.on_subscribe = self.on_subscribe
+ self.mqttClient.username_pw_set(
+ str(self.confs['un']), str(self.confs['pw']))
+ self.mqttClient.connect(self.mqttHost, self.mqttPort, 10)
+ self.mqttClient.loop_start()
+
+ self.Helpers.logger.info("Local iotJumpWay Device Connection Initiated.")
+
+ def on_connect(self, client, obj, flags, rc):
+
+ self.Helpers.logger.info("Local iotJumpWay Device Connection Successful.")
+ self.Helpers.logger.info("rc: " + str(rc))
+
+ self.statusPub("ONLINE")
+
+ def on_subscribe(self, client, obj, mid, granted_qos):
+
+ self.Helpers.logger.info("Local iotJumpWay Subscription: "+str(mid))
+
+ def on_message(self, client, obj, msg):
+
+ self.Helpers.logger.info("Local iotJumpWay Message Received")
+ splitTopic=msg.topic.split("/")
+
+ if splitTopic[1]=='Devices':
+ if splitTopic[4]=='Commands':
+ if self.commandsCallback == None:
+ print("** Device Commands Callback Required (commandsCallback)")
+ else:
+ self.commandsCallback(msg.topic, msg.payload)
+
+ def statusPub(self, data):
+
+ deviceStatusTopic = '%s/Devices/%s/%s/Status' % (self.confs['lid'], self.confs['zid'], self.confs['did'])
+ self.mqttClient.publish(deviceStatusTopic, data)
+ self.Helpers.logger.info("Published to Device Status " + deviceStatusTopic)
+
+ def channelPub(self, channel, data):
+
+ deviceChannel = '%s/Devices/%s/%s/%s' % (self.confs['lid'], self.confs['zid'], self.confs['did'], channel)
+ self.mqttClient.publish(deviceChannel, json.dumps(data))
+
+ def channelSub(self, channel, qos=0):
+
+ if channel == None:
+ self.Helpers.logger.info("** Channel (channel) is required!")
+ return False
+ else:
+ deviceChannel = '%s/Devices/%s/%s/%s' % (self.confs['lid'], self.confs['zid'], self.confs['did'], channel)
+ self.mqttClient.subscribe(deviceChannel, qos=qos)
+ self.Helpers.logger.info("-- Subscribed to Device "+channel+" Channel")
+
+ def on_publish(self, client, obj, mid):
+ self.Helpers.logger.info("-- Published to Device channel")
+
+ def on_log(self, client, obj, level, string):
+
+ print(string)
+
+ def disconnect(self):
+ self.statusPub("OFFLINE")
+ self.mqttClient.disconnect()
+ self.mqttClient.loop_stop()
diff --git a/Classes/MongoDB.py b/Classes/MongoDB.py
index 9086f6e..f6b9f0c 100644
--- a/Classes/MongoDB.py
+++ b/Classes/MongoDB.py
@@ -1,7 +1,8 @@
######################################################################################################
#
-# Organization: Peter Moss Leukemia AI Research
+# Organization: Asociacion De Investigacion En Inteligencia Artificial Para La Leucemia Peter Moss
# Repository: HIAS: Hospital Intelligent Automation System
+# Module: MongoDB
#
# Author: Adam Milton-Barker (AdamMiltonBarker.com)
#
@@ -34,21 +35,115 @@ def __init__(self):
def startMongoDB(self):
""" Connects to MongoDB database. """
- connection = MongoClient(self.Helpers.confs["iotJumpWay"]["ip"])
- self.mongoConn = connection[self.Helpers.confs["iotJumpWay"]["mdb"]]
- self.mongoConn.authenticate(self.Helpers.confs["iotJumpWay"]["mdbu"],
- self.Helpers.confs["iotJumpWay"]["mdbp"])
+ connection = MongoClient(self.Helpers.confs["iotJumpWay"]["databases"]["mongo"]["ip"])
+ self.mongoConn = connection[self.Helpers.confs["iotJumpWay"]["databases"]["mongo"]["db"]]
+ self.mongoConn.authenticate(self.Helpers.confs["iotJumpWay"]["databases"]["mongo"]["dbu"],
+ self.Helpers.confs["iotJumpWay"]["databases"]["mongo"]["dbp"])
+ self.agentsCollection = self.mongoConn.Agents
+ self.locationsCollection = self.mongoConn.Locations
+ self.zonesCollection = self.mongoConn.Zones
+ self.devicesCollection = self.mongoConn.Devices
+ self.applicationsCollection = self.mongoConn.Applications
+ self.usersCollection = self.mongoConn.Users
+ self.patientsCollection = self.mongoConn.Patients
+ self.staffCollection = self.mongoConn.Staff
+ self.thingsCollection = self.mongoConn.Things
+ self.modelsCollection = self.mongoConn.Models
self.Helpers.logger.info("Mongo connection started")
- def insertData(self, collection, doc):
+ def getData(self, collection, limit, category=None, values=None):
+ """ Connects to MongoDB database. """
+
+ query = {}
+
+ if category is not None:
+ query = {"category.value.0": category}
+
+ if values is not None:
+ valuesArr = values.split(",")
+ for value in valuesArr:
+ pair = value.split("|")
+ query.update({pair[0]: pair[1]})
+
+ try:
+ entities = list(collection.find(query, {'_id': False}).limit(limit))
+ self.Helpers.logger.info("Mongo data found OK")
+ return entities
+ except:
+ e = sys.exc_info()
+ self.Helpers.logger.info("Mongo data find FAILED!")
+ self.Helpers.logger.info(str(e))
+ return False
+
+ def getDataById(self, collection, _id, attrs):
+ """ Connects to MongoDB database. """
+
+ fields = {'_id': False}
+ if attrs is not None:
+ attribs = attrs.split(",")
+ for attr in attribs:
+ fields.update({attr: True})
+
+ try:
+ entity = list(collection.find({'id': _id}, fields))
+ self.Helpers.logger.info("Mongo data found OK")
+ return entity
+ except:
+ e = sys.exc_info()
+ self.Helpers.logger.info("Mongo data find FAILED!")
+ self.Helpers.logger.info(str(e))
+ return False
+
+ def insertData(self, collection, doc, typeof):
""" Connects to MongoDB database. """
try:
_id = collection.insert(doc)
self.Helpers.logger.info("Mongo data inserted OK")
+ if typeof is "Device":
+ self.locationsCollection.find_one_and_update(
+ {"id": doc.lid.entity},
+ {'$inc': {'devices.value': 1}}
+ )
+ self.zonesCollection.find_one_and_update(
+ {"id": doc.zid.entity},
+ {'$inc': {'devices.value': 1}}
+ )
+ if typeof is "Application":
+ self.locationsCollection.find_one_and_update(
+ {"id": doc.lid.entity},
+ {'$inc': {'applications.value': 1}}
+ )
+ self.Helpers.logger.info("Mongo data update OK")
return _id
except:
e = sys.exc_info()
self.Helpers.logger.info("Mongo data inserted FAILED!")
self.Helpers.logger.info(str(e))
return False
+
+ def updateData(self, _id, collection, doc):
+ """ Connects to MongoDB database. """
+
+ try:
+ collection.update_one({"id" : _id}, {"$set": doc});
+ self.Helpers.logger.info("Mongo data update OK")
+ return True
+ except:
+ e = sys.exc_info()
+ self.Helpers.logger.info("Mongo data update FAILED!")
+ self.Helpers.logger.info(str(e))
+ return False
+
+ def deleteData(self, _id, collection):
+ """ Connects to MongoDB database. """
+
+ try:
+ collection.delete_one({"id": _id});
+ self.Helpers.logger.info("Mongo data update OK")
+ return True
+ except:
+ e = sys.exc_info()
+ self.Helpers.logger.info("Mongo data update FAILED!")
+ self.Helpers.logger.info(str(e))
+ return False
diff --git a/Classes/MySQL.py b/Classes/MySQL.py
deleted file mode 100644
index fd0f794..0000000
--- a/Classes/MySQL.py
+++ /dev/null
@@ -1,333 +0,0 @@
-######################################################################################################
-#
-# Organization: Peter Moss Leukemia AI Research
-# Repository: HIAS: Hospital Intelligent Automation System
-#
-# Author: Adam Milton-Barker (AdamMiltonBarker.com)
-#
-# Title: MySQL Class
-# Description: MySQL functions for the Hospital Intelligent Automation System.
-# License: MIT License
-# Last Modified: 2020-09-20
-#
-######################################################################################################
-
-import bcrypt
-import MySQLdb
-import sys
-import time
-
-from datetime import datetime
-from datetime import timedelta
-
-from Classes.Helpers import Helpers
-
-
-class MySQL():
- """ MySQL Class
-
- MySQL functions for the Hospital Intelligent Automation System.
- """
-
- def __init__(self):
- """ Initializes the class. """
-
- self.Helpers = Helpers("MySQL")
- self.Helpers.logger.info("MySQL Class initialization complete.")
-
- def startMySQL(self):
- """ Connects to MySQL database. """
-
- self.mysqlConn = MySQLdb.connect(host=self.Helpers.confs["iotJumpWay"]["ip"],
- user=self.Helpers.confs["iotJumpWay"]["dbuser"],
- passwd=self.Helpers.confs["iotJumpWay"]["dbpass"],
- db=self.Helpers.confs["iotJumpWay"]["dbname"])
- self.Helpers.logger.info("MySQL connection started")
-
- def getApplication(self, app):
- """ Get application details """
-
- try:
- cur = self.mysqlConn.cursor()
- cur.execute("""
- SELECT *
- FROM mqtta
- WHERE id=%s
- """, (int(app),))
- appDetails = cur.fetchone()
- cur.close()
- self.Helpers.logger.info("App details select OK!")
- return appDetails
- except:
- e = sys.exc_info()
- self.Helpers.logger.info("App details select failed!")
- self.Helpers.logger.info(str(e))
- return ""
-
- def updateApplicationStatus(self, payload, splitTopic):
- """ Updates the status of an application """
-
- try:
- cur = self.mysqlConn.cursor()
- cur.execute("""
- UPDATE mqtta
- SET status=%s
- WHERE id=%s
- """, (str(payload), splitTopic[2]))
- self.mysqlConn.commit()
- cur.close()
- self.Helpers.logger.info("Mysql Application status updated OK")
- except:
- e = sys.exc_info()
- self.mysqlConn.rollback()
- self.Helpers.logger.info("Mysql Application status update FAILED!")
- self.Helpers.logger.info(str(e))
-
- def updateApplication(self, typeof, data, splitTopic):
- """ Updates an application """
-
- try:
- cur = self.mysqlConn.cursor()
- cur.execute("""
- UPDATE mqtta
- SET cpu=%s,
- mem=%s,
- hdd=%s,
- tempr=%s,
- lt=%s,
- lg=%s
- WHERE id=%s
- """, (data["CPU"], data["Memory"], data["Diskspace"], data["Temperature"], data["Latitude"], data["Longitude"], splitTopic[2]))
- self.mysqlConn.commit()
- cur.close()
- self.Helpers.logger.info("Mysql " + typeof + " application updated OK")
- except:
- e = sys.exc_info()
- self.mysqlConn.rollback()
- self.Helpers.logger.info("Mysql " + typeof + " application updated FAILED ")
- self.Helpers.logger.info(str(e))
-
- def getDevice(self, device):
- """ Get application details """
-
- try:
- cur = self.mysqlConn.cursor()
- cur.execute("""
- SELECT *
- FROM mqttld
- WHERE id=%s
- """, (int(device),))
- dvcDetails = cur.fetchone()
- cur.close()
- self.Helpers.logger.info("Device details select OK!")
- return dvcDetails
- except:
- e = sys.exc_info()
- self.Helpers.logger.info("Device details select failed!")
- self.Helpers.logger.info(str(e))
- return ""
-
- def updateDeviceStatus(self, payload, device):
- """ Updates the status of a device """
-
- try:
- cur = self.mysqlConn.cursor()
- cur.execute("""
- UPDATE mqttld
- SET status=%s
- WHERE id=%s
- """, (str(payload), device))
- self.mysqlConn.commit()
- cur.close()
- self.Helpers.logger.info("Mysql Device status updated OK")
- except:
- e = sys.exc_info()
- self.mysqlConn.rollback()
- self.Helpers.logger.info("Mysql Device status update FAILED")
- self.Helpers.logger.info(str(e))
-
- def updateDevice(self, typeof, data, device):
- """ Updates a device """
-
- try:
- cur = self.mysqlConn.cursor()
- cur.execute("""
- UPDATE mqttld
- SET cpu=%s,
- mem=%s,
- hdd=%s,
- tempr=%s,
- lt=%s,
- lg=%s
- WHERE id=%s
- """, (data["CPU"], data["Memory"], data["Diskspace"], data["Temperature"], data["Latitude"], data["Longitude"], device))
- self.mysqlConn.commit()
- cur.close()
- self.Helpers.logger.info("Mysql " + typeof + " device updated OK")
- except:
- e = sys.exc_info()
- self.mysqlConn.rollback()
- self.Helpers.logger.info("Mysql " + typeof + " device update FAILED!")
- self.Helpers.logger.info(str(e))
-
- def getNLU(self, splitTopic):
- """ Get NLU device """
-
- try:
- cur = self.mysqlConn.cursor()
- cur.execute("""
- SELECT genisysainlu.did
- FROM genisysainlu
- INNER JOIN mqttld
- ON genisysainlu.did = mqttld.id
- WHERE mqttld.zid = %s
- && mqttld.status=%s
- """, (splitTopic[2], "ONLINE"))
- nlu = cur.fetchone()
- cur.close()
- self.Helpers.logger.info("Camera NLU details: " + str(nlu))
- return nlu
- except:
- e = sys.exc_info()
- self.Helpers.logger.info("Camera NLU details select failed!")
- self.Helpers.logger.info(str(e))
- return ""
- pass
-
- def updateUserLocation(self, splitTopic, data):
- """ Get NLU device """
-
- try:
- cur = self.mysqlConn.cursor()
- cur.execute("""
- UPDATE users
- SET cz=%s,
- czt=%s
- WHERE id=%s
- """, (splitTopic[2], time.time(), int(data["Value"])))
- self.mysqlConn.commit()
- cur.close()
- self.Helpers.logger.info("Mysql user location data updated OK")
- except:
- e = sys.exc_info()
- self.mysqlConn.rollback()
- self.Helpers.logger.info("Mysql user location update FAILED")
- self.Helpers.logger.info(str(e))
-
- def getUser(self, data):
- """ Get user details """
-
- cTime = datetime.now()
- hb = cTime - timedelta(hours=1)
- hbe = int(hb.timestamp())
-
- try:
- cur = self.mysqlConn.cursor()
- cur.execute("""
- SELECT users.name,
- users.aid,
- mqtta.status
- FROM users
- INNER JOIN mqtta
- ON users.aid = mqtta.id
- WHERE users.id=%s
- && (users.welcomed = 0 || users.welcomed <= %s)
- """, (int(data["Value"]), hbe))
- userDetails = cur.fetchone()
- cur.close()
- self.Helpers.logger.info("User details: " + str(userDetails))
- return userDetails
- except:
- e = sys.exc_info()
- self.Helpers.logger.info("User details select failed ")
- self.Helpers.logger.info(str(e))
- return ""
-
- def getUserNFC(self, uid):
- """ Checks user NFC UID """
-
- try:
- cur = self.mysqlConn.cursor()
- cur.execute("""
- SELECT nfc
- FROM users
- WHERE users.nfc=%s
- """, (uid,))
- uuid = cur.fetchone()
- cur.close()
- if uuid[0] is not None:
- self.Helpers.logger.info("NFC UID OK!")
- return True
- else:
- self.Helpers.logger.info("NFC UID Not Authorized!")
- return False
- except:
- e = sys.exc_info()
- self.Helpers.logger.info("NFC UID select failed ")
- self.Helpers.logger.info(str(e))
- return ""
-
- def updateUser(self, data):
- """ Get user details """
-
- try:
- cur = self.mysqlConn.cursor()
- cur.execute("""
- UPDATE users
- SET welcomed=%s
- WHERE id=%s
- """, (time.time(), int(data["Value"])))
- self.mysqlConn.commit()
- cur.close()
- self.Helpers.logger.info("Mysql user welcome updated OK")
- except:
- e = sys.exc_info()
- self.mysqlConn.rollback()
- self.Helpers.logger.info("Mysql user welcome updated FAILED!")
- self.Helpers.logger.info(str(e))
-
- def insertDataTransaction(self, aid, did, action, thash):
- """ Get user details """
-
- try:
- cur = self.mysqlConn.cursor()
- cur.execute("""
- INSERT INTO transactions (aid, did, action, hash, time)
- VALUES (%s, %s, %s, %s, %s)
- """, (aid, did, action, thash, time.time()))
- self.mysqlConn.commit()
- hashid = cur.lastrowid
- self.Helpers.logger.info("Transaction stored in database!")
-
- cur = self.mysqlConn.cursor()
- cur.execute("""
- INSERT INTO history (taid, tdid, action, hash, time)
- VALUES (%s, %s, %s, %s, %s)
- """, (aid, did, action, hashid, time.time()))
- self.mysqlConn.commit()
- cur.close()
- self.Helpers.logger.info("History stored in database!")
- except:
- e = sys.exc_info()
- self.mysqlConn.rollback()
- self.Helpers.logger.info("Transaction history FAILED!")
- self.Helpers.logger.info(str(e))
-
- def getContracts(self):
- """ Get all smart contracts """
-
- try:
- cur = self.mysqlConn.cursor()
- cur.execute("""
- SELECT *
- FROM contracts
- """)
- contracts = cur.fetchall()
- cur.close()
- self.Helpers.logger.info("Got contracts: " + str(len(contracts)))
- return contracts
- except:
- e = sys.exc_info()
- self.Helpers.logger.info("Contracts select failed ")
- self.Helpers.logger.info(str(e))
- return ""
diff --git a/Classes/TassAI.py b/Classes/TassAI.py
index 8fde093..0ca4d80 100644
--- a/Classes/TassAI.py
+++ b/Classes/TassAI.py
@@ -1,7 +1,8 @@
######################################################################################################
#
-# Organization: Peter Moss Leukemia AI Research
-# Repository: HIAS: Hospital Intelligent Automation System
+# Organization: Asociacion De Investigacion En Inteligencia Artificial Para La Leucemia Peter Moss
+# Repository: HIAS: Hospital Intelligent Automation System
+# Project: TassAI
#
# Author: Adam Milton-Barker (AdamMiltonBarker.com)
#
@@ -37,7 +38,7 @@ def __init__(self):
self.Helpers = Helpers("TassAI", False)
self.qs = 16
- self.context = InferenceContext([self.Helpers.confs["TassAI"]["runas"], self.Helpers.confs["TassAI"]["runas"], self.Helpers.confs["TassAI"]["runas"]], "", "", "")
+ self.context = InferenceContext([self.Helpers.confs["iotJumpWay"]["MQTT"]["TassAI"]["runas"], self.Helpers.confs["iotJumpWay"]["MQTT"]["TassAI"]["runas"], self.Helpers.confs["iotJumpWay"]["MQTT"]["TassAI"]["runas"]], "", "", "")
self.Helpers.logger.info("TassAI Helper Class initialization complete.")
@@ -45,30 +46,30 @@ def load_models(self):
""" Loads all models. """
face_detector_net = self.load_model(
- self.Helpers.confs["TassAI"]["detection"])
+ self.Helpers.confs["iotJumpWay"]["MQTT"]["TassAI"]["detection"])
face_detector_net.reshape({"data": [1, 3, 384, 672]})
landmarks_net = self.load_model(
- self.Helpers.confs["TassAI"]["landmarks"])
+ self.Helpers.confs["iotJumpWay"]["MQTT"]["TassAI"]["landmarks"])
face_reid_net = self.load_model(
- self.Helpers.confs["TassAI"]["reidentification"])
+ self.Helpers.confs["iotJumpWay"]["MQTT"]["TassAI"]["reidentification"])
self.face_detector = FaceDetector(face_detector_net,
- confidence_threshold=0.6,
- roi_scale_factor=1.15)
+ confidence_threshold=0.6,
+ roi_scale_factor=1.15)
self.landmarks_detector = LandmarksDetector(landmarks_net)
self.face_identifier = FaceIdentifier(face_reid_net,
- match_threshold=0.3,
- match_algo='HUNGARIAN')
+ match_threshold=0.3,
+ match_algo='HUNGARIAN')
- self.face_detector.deploy(self.Helpers.confs["TassAI"]["runas"], self.context)
- self.landmarks_detector.deploy(self.Helpers.confs["TassAI"]["runas"], self.context,
+ self.face_detector.deploy(self.Helpers.confs["iotJumpWay"]["MQTT"]["TassAI"]["runas"], self.context)
+ self.landmarks_detector.deploy(self.Helpers.confs["iotJumpWay"]["MQTT"]["TassAI"]["runas"], self.context,
queue_size=self.qs)
- self.face_identifier.deploy(self.Helpers.confs["TassAI"]["runas"], self.context,
- queue_size=self.qs)
+ self.face_identifier.deploy(self.Helpers.confs["iotJumpWay"]["MQTT"]["TassAI"]["runas"], self.context,
+ queue_size=self.qs)
self.Helpers.logger.info("Models loaded")
@@ -87,7 +88,7 @@ def load_model(self, model_path):
def load_known(self):
""" Loads known data. """
- self.faces_database = FacesDatabase(self.Helpers.confs["TassAI"]["data"], self.face_identifier,
+ self.faces_database = FacesDatabase(self.Helpers.confs["iotJumpWay"]["MQTT"]["TassAI"]["data"], self.face_identifier,
self.landmarks_detector, self.face_detector, True)
self.face_identifier.set_faces_database(self.faces_database)
self.Helpers.logger.info("Database is built, registered %s identities" %
@@ -154,8 +155,8 @@ def draw_detection_roi(self, frame, roi, identity):
if identity.id != FaceIdentifier.UNKNOWN_ID:
text += ' %.2f%%' % (100.0 * (1 - identity.distance))
self.draw_text_with_background(frame, text,
- roi.position - line_height * 0.5,
- font, scale=text_scale)
+ roi.position - line_height * 0.5,
+ font, scale=text_scale)
return frame, label
diff --git a/Classes/iotJumpWay.py b/Classes/iotJumpWay.py
deleted file mode 100644
index 7d5e5d1..0000000
--- a/Classes/iotJumpWay.py
+++ /dev/null
@@ -1,331 +0,0 @@
-######################################################################################################
-#
-# Organization: Peter Moss Leukemia AI Research
-# Repository: HIAS: Hospital Intelligent Automation System
-#
-# Author: Adam Milton-Barker (AdamMiltonBarker.com)
-# Contributors:
-# Title: iotJumpWay Class
-# Description: The iotJumpWay Class provides the Hospital Intelligent Automation System with it's
-# IoT functionality.
-# License: MIT License
-# Last Modified: 2020-06-04
-#
-######################################################################################################
-
-import inspect, json, os
-
-import paho.mqtt.client as mqtt
-
-from Classes.Helpers import Helpers
-
-class Application():
- """ iotJumpWay Class
-
- The iotJumpWay Class provides the Hospital Intelligent Automation System with
- it's IoT functionality.
- """
-
- def __init__(self, configs):
- """ Initializes the class. """
-
- self.Helpers = Helpers("iotJumpWay")
- self.confs = configs
-
- self.Helpers.logger.info("Initiating Local iotJumpWay Application.")
-
- if self.confs['host'] == None:
- raise ConfigurationException("** Host (host) property is required")
- elif self.confs['port'] == None:
- raise ConfigurationException("** Port (port) property is required")
- elif self.confs['lid'] == None:
- raise ConfigurationException("** Location ID (lid) property is required")
- elif self.confs['aid'] == None:
- raise ConfigurationException("** Application ID (aid) property is required")
- elif self.confs['an'] == None:
- raise ConfigurationException("** Application Name (an) property is required")
- elif self.confs['un'] == None:
- raise ConfigurationException("** MQTT UserName (un) property is required")
- elif self.confs['pw'] == None:
- raise ConfigurationException("** MQTT Password (pw) property is required")
-
- self.mqttClient = None
- self.mqttTLS = "/etc/ssl/certs/DST_Root_CA_X3.pem"
- self.mqttHost = self.confs['host']
- self.mqttPort = self.confs['port']
-
- self.appCommandsCallback = None
- self.appSensorCallback = None
- self.appStatusCallback = None
- self.appTriggerCallback = None
- self.appLifeCallback = None
- self.deviceCameraCallback = None
- self.deviceCommandsCallback = None
- self.deviceLifeCallback = None
- self.deviceNfcCallback = None
- self.deviceSensorCallback = None
- self.deviceStatusCallback = None
- self.deviceTriggerCallback = None
-
- self.Helpers.logger.info("JumpWayMQTT Application Initiated.")
-
- def connect(self):
-
- self.Helpers.logger.info("Initiating Local iotJumpWay Application Connection.")
-
- self.mqttClient = mqtt.Client(client_id = self.confs['an'], clean_session = True)
- applicationStatusTopic = '%s/Applications/%s/Status' % (self.confs['lid'], self.confs['aid'])
- self.mqttClient.will_set(applicationStatusTopic, "OFFLINE", 0, False)
- self.mqttClient.tls_set(self.mqttTLS, certfile=None, keyfile=None)
- self.mqttClient.on_connect = self.on_connect
- self.mqttClient.on_message = self.on_message
- self.mqttClient.on_publish = self.on_publish
- self.mqttClient.on_subscribe = self.on_subscribe
- self.mqttClient.username_pw_set(str(self.confs['un']), str(self.confs['pw']))
- self.mqttClient.connect(self.mqttHost, self.mqttPort, 10)
- self.mqttClient.loop_start()
-
- self.Helpers.logger.info("Local iotJumpWay Application Connection Initiated.")
-
- def on_connect(self, client, obj, flags, rc):
-
- self.Helpers.logger.info("Local iotJumpWay Application Connection Successful.")
- self.Helpers.logger.info("rc: " + str(rc))
-
- self.appStatusPub("ONLINE")
-
- def appStatusPub(self, data):
-
- deviceStatusTopic = '%s/Applications/%s/Status' % (self.confs['lid'], self.confs['aid'])
- self.mqttClient.publish(deviceStatusTopic, data)
- self.Helpers.logger.info("Published to Application Status " + deviceStatusTopic)
-
- def on_subscribe(self, client, obj, mid, granted_qos):
-
- self.Helpers.logger.info("JumpWayMQTT Subscription: "+str(self.confs['an']))
-
- def on_message(self, client, obj, msg):
-
- self.Helpers.logger.info("JumpWayMQTT Message Received")
- splitTopic=msg.topic.split("/")
-
- if splitTopic[1]=='Applications':
- if splitTopic[3]=='Status':
- if self.appStatusCallback == None:
- self.Helpers.logger.info("** Application Status Callback Required (appStatusCallback)")
- else:
- self.appStatusCallback(msg.topic,msg.payload)
- elif splitTopic[3]=='Command':
- if self.cameraCallback == None:
- self.Helpers.logger.info("** Application Camera Callback Required (cameraCallback)")
- else:
- self.cameraCallback(msg.topic,msg.payload)
- elif splitTopic[3]=='Life':
- if self.appLifeCallback == None:
- self.Helpers.logger.info("** Application Life Callback Required (appLifeCallback)")
- else:
- self.appLifeCallback(msg.topic,msg.payload)
- elif splitTopic[1] == 'Devices':
- if splitTopic[4] == 'Actuators':
- if self.deviceActuatorCallback == None:
- self.Helpers.logger.info("** Device Actuator Callback Required (deviceActuatorCallback)")
- else:
- self.deviceActuatorCallback(msg.topic, msg.payload)
- elif splitTopic[4]=='Commands':
- if self.deviceCommandsCallback == None:
- self.Helpers.logger.info("** Device Commands Callback Required (deviceCommandsCallback)")
- else:
- self.deviceCommandsCallback(msg.topic,msg.payload)
- elif splitTopic[4]=='Life':
- if self.deviceLifeCallback == None:
- self.Helpers.logger.info("** Device Life Callback Required (deviceLifeCallback)")
- else:
- self.deviceLifeCallback(msg.topic, msg.payload)
- elif splitTopic[4]=='NFC':
- if self.deviceNfcCallback == None:
- self.Helpers.logger.info("** Device NFC Callback Required (deviceNfcCallback)")
- else:
- self.deviceNfcCallback(msg.topic, msg.payload)
- elif splitTopic[4] == 'Status':
- if self.deviceStatusCallback == None:
- self.Helpers.logger.info("** Device Status Callback Required (deviceStatusCallback)")
- else:
- self.deviceStatusCallback(msg.topic, msg.payload)
- elif splitTopic[4]=='Sensors':
- if self.deviceSensorCallback == None:
- self.Helpers.logger.info("** Device Sensors Callback Required (deviceSensorCallback)")
- else:
- self.deviceSensorCallback(msg.topic,msg.payload)
- elif splitTopic[4]=='Notifications':
- if self.deviceNotificationsCallback == None:
- self.Helpers.logger.info("** Device Notifications Callback Required (deviceNotificationsCallback)")
- else:
- self.deviceNotificationsCallback(msg.topic,msg.payload)
- elif splitTopic[4]=='Cameras':
- if self.deviceCameraCallback == None:
- self.Helpers.logger.info("** Device Camera Callback Required (cameraCallback)")
- else:
- self.deviceCameraCallback(msg.topic,msg.payload)
-
- def appChannelPub(self, channel, application, data):
-
- applicationChannel = '%s/Applications/%s/%s' % (self.confs['lid'], application, channel)
- self.mqttClient.publish(applicationChannel,json.dumps(data))
- print("Published to Application "+channel+" Channel")
-
- def appChannelSub(self, application, channelID, qos=0):
-
- if application == "#":
- applicationChannel = '%s/Applications/#' % (self.confs['lid'])
- self.mqttClient.subscribe(applicationChannel, qos=qos)
- self.Helpers.logger.info("-- Subscribed to all Application Channels")
- return True
- else:
- applicationChannel = '%s/Applications/%s/%s' % (self.confs['lid'], application, channelID)
- self.mqttClient.subscribe(applicationChannel, qos=qos)
- self.Helpers.logger.info("-- Subscribed to Application " + channelID + " Channel")
- return True
-
- def appDeviceChannelPub(self, channel, zone, device, data):
-
- deviceChannel = '%s/Devices/%s/%s/%s' % (self.confs['lid'], zone, device, channel)
- self.mqttClient.publish(deviceChannel, json.dumps(data))
- self.Helpers.logger.info("-- Published to Device "+channel+" Channel")
-
- def appDeviceChannelSub(self, zone, device, channel, qos=0):
-
- if zone == None:
- print("** Zone ID (zoneID) is required!")
- return False
- elif device == None:
- print("** Device ID (device) is required!")
- return False
- elif channel == None:
- print("** Channel ID (channel) is required!")
- return False
- else:
- if device == "#":
- deviceChannel = '%s/Devices/#' % (self.confs['lid'])
- self.mqttClient.subscribe(deviceChannel, qos=qos)
- self.Helpers.logger.info("-- Subscribed to all devices")
- else:
- deviceChannel = '%s/Devices/%s/%s/%s' % (self.confs['lid'], zone, device, channel)
- self.mqttClient.subscribe(deviceChannel, qos=qos)
- self.Helpers.logger.info("-- Subscribed to Device "+channel+" Channel")
-
- return True
-
- def on_publish(self, client, obj, mid):
-
- print("-- Published: "+str(mid))
-
- def on_log(self, client, obj, level, string):
-
- print(string)
-
- def appDisconnect(self):
- self.appStatusPub("OFFLINE")
- self.mqttClient.disconnect()
- self.mqttClient.loop_stop()
-
-class Device():
- """ iotJumpWay Class
-
- The iotJumpWay Class provides the EMAR device with it's IoT functionality.
- """
-
- def __init__(self):
- """ Initializes the class. """
-
- self.Helpers = Helpers("iotJumpWay")
-
- self.Helpers.logger.info("Initiating Local iotJumpWay Device.")
-
- self.mqttClient = None
- self.mqttTLS = "/etc/ssl/certs/DST_Root_CA_X3.pem"
- self.mqttHost = self.Helpers.confs["iotJumpWay"]['host']
- self.mqttPort = self.Helpers.confs["iotJumpWay"]['port']
-
- self.commandsCallback = None
-
- self.Helpers.logger.info("JumpWayMQTT Device Initiated.")
-
- def connect(self):
-
- self.Helpers.logger.info("Initiating Local iotJumpWay Device Connection.")
-
- self.mqttClient = mqtt.Client(client_id = self.Helpers.confs["iotJumpWay"]['dn'], clean_session = True)
- deviceStatusTopic = '%s/Device/%s/%s/Status' % (self.Helpers.confs["iotJumpWay"]['lid'], self.Helpers.confs["iotJumpWay"]['zid'], self.Helpers.confs["iotJumpWay"]['did'])
- self.mqttClient.will_set(deviceStatusTopic, "OFFLINE", 0, False)
- self.mqttClient.tls_set(self.mqttTLS, certfile=None, keyfile=None)
- self.mqttClient.on_connect = self.on_connect
- self.mqttClient.on_message = self.on_message
- self.mqttClient.on_publish = self.on_publish
- self.mqttClient.on_subscribe = self.on_subscribe
- self.mqttClient.username_pw_set(str(self.Helpers.confs["iotJumpWay"]['gun']), str(self.Helpers.confs["iotJumpWay"]['gpw']))
- self.mqttClient.connect(self.mqttHost, self.mqttPort, 10)
- self.mqttClient.loop_start()
-
- self.Helpers.logger.info("Local iotJumpWay Device Connection Initiated.")
-
- def on_connect(self, client, obj, flags, rc):
-
- self.Helpers.logger.info("Local iotJumpWay Device Connection Successful.")
- self.Helpers.logger.info("rc: " + str(rc))
-
- self.statusPub("ONLINE")
-
- def on_subscribe(self, client, obj, mid, granted_qos):
-
- self.Helpers.logger.info("JumpWayMQTT Subscription: "+str(mid))
-
- def on_message(self, client, obj, msg):
-
- print("JumpWayMQTT Message Received")
- splitTopic=msg.topic.split("/")
-
- if splitTopic[1]=='Devices':
- if splitTopic[4]=='Commands':
- if self.commandsCallback == None:
- print("** Device Commands Callback Required (commandsCallback)")
- else:
- self.commandsCallback(msg.topic, msg.payload)
- elif splitTopic[4]=='Triggers':
- if self.triggersCallback == None:
- print("** Device Notifications Callback Required (deviceNotificationsCallback)")
- else:
- self.triggersCallback(msg.topic, msg.payload)
-
- def statusPub(self, data):
-
- deviceStatusTopic = '%s/Devices/%s/%s/Status' % (self.Helpers.confs["iotJumpWay"]['lid'], self.Helpers.confs["iotJumpWay"]['zid'], self.Helpers.confs["iotJumpWay"]['did'])
- self.mqttClient.publish(deviceStatusTopic, data)
- self.Helpers.logger.info("Published to Device Status " + deviceStatusTopic)
-
- def channelPub(self, channel, data):
-
- deviceChannel = '%s/Devices/%s/%s/%s' % (self.Helpers.confs["iotJumpWay"]['lid'], self.Helpers.confs["iotJumpWay"]['zid'], self.Helpers.confs["iotJumpWay"]['did'], channel)
- self.mqttClient.publish(deviceChannel, json.dumps(data))
-
- def channelSub(self, channel, qos=0):
-
- if channel == None:
- self.Helpers.logger.info("** Channel (channel) is required!")
- return False
- else:
- deviceChannel = '%s/Devices/%s/%s/%s' % (self.Helpers.confs["iotJumpWay"]['lid'], self.Helpers.confs["iotJumpWay"]['zid'], self.Helpers.confs["iotJumpWay"]['did'], channel)
- self.mqttClient.subscribe(deviceChannel, qos=qos)
- self.Helpers.logger.info("-- Subscribed to Device "+channel+" Channel")
-
- def on_publish(self, client, obj, mid):
-
- self.Helpers.logger.info("-- Published to Device channel")
-
- def on_log(self, client, obj, level, string):
-
- print(string)
-
- def disconnect(self):
- self.statusPub("OFFLINE")
- self.mqttClient.disconnect()
- self.mqttClient.loop_stop()
diff --git a/Context/Agents.py b/Context/Agents.py
new file mode 100644
index 0000000..8cc825f
--- /dev/null
+++ b/Context/Agents.py
@@ -0,0 +1,121 @@
+#!/usr/bin/env python3
+######################################################################################################
+#
+# Organization: Peter Moss Leukemia AI Research
+# Repository: HIAS: Hospital Intelligent Automation System
+#
+# Author: Adam Milton-Barker (AdamMiltonBarker.com)
+#
+# Title: HIAS HDSI Context Broker
+# Description: The HIAS HDSI Context Broker handles contextual data for all iotJumpWay
+# devices/applications and IoT Agents. The Context Broker uses the HDSI (HIAS
+# Data Services Interface) API V1, based on Open Mobile Alliance's NGSI V2.
+# License: MIT License
+# Last Modified: 2020-10-18
+#
+######################################################################################################
+
+import json
+import jsonpickle
+import os
+import sys
+
+from bson import json_util, ObjectId
+from flask import Response
+
+from Classes.Helpers import Helpers
+
+
+class Agents():
+ """ Agents Class
+
+ Handles IoT Agent functionality for the HIAS HDSI Context Broker.
+ """
+
+ def __init__(self, mongoConnection):
+ """ Initializes the class. """
+
+ self.Helpers = Helpers("Agents")
+ self.MongoDB = mongoConnection
+ self.Helpers.logger.info("Agents Class initialization complete.")
+
+ def createAgent(self, data):
+ """ Creates a new NDSI IoT Agent """
+
+ _id = self.MongoDB.insertData(
+ self.MongoDB.applicationsCollection, data, data["type"])
+
+ resp = {
+ "Response": "OK",
+ "ID": str(_id),
+ "Agent": json.loads(json_util.dumps(data))
+ }
+
+ if str(_id) is not False:
+ return self.respond(201, resp, "v1/agents/" + data["id"])
+ else:
+ return self.respond(400, {
+ "Response": "Failed",
+ "Error": "BadRequest",
+ "Description": "Entity storage failed!"
+ })
+
+ def getAgents(self, limit=0):
+ """ Gets all NDSI IoT Agents """
+
+ agents = self.MongoDB.getData(self.MongoDB.applicationsCollection, limit, "IoT Agent")
+
+ if not agents:
+ return self.respond(404, {
+ "Response": "Failed",
+ "Error": "NotFound",
+ "Description": "No agents exist!"
+ })
+ else:
+ resp = {
+ "Response": "OK",
+ "Data": json.loads(json_util.dumps(agents))
+ }
+ return self.respond(200, resp)
+
+ def getAgent(self, _id, attrs):
+ """ Gets a specific NDSI IoT Agent """
+
+ agent = self.MongoDB.getDataById(
+ self.MongoDB.applicationsCollection, _id, attrs)
+
+ if not agent:
+ return self.respond(404, {
+ "Response": "Failed",
+ "Error": "NotFound",
+ "Description": "Agent does not exist!"
+ })
+ else:
+ resp = {
+ "Response": "OK",
+ "Data": json.loads(json_util.dumps(agent[0]))
+ }
+ return self.respond(200, resp)
+
+ def updateAgent(self, _id, data):
+ """ Updates an NDSI IoT Agent """
+
+ updated = self.MongoDB.updateData(
+ _id, self.MongoDB.applicationsCollection, data)
+
+ if updated is True:
+ return self.respond(200, {
+ "Response": "OK"
+ })
+ else:
+ return self.respond(400, {
+ "Response": "OK",
+ "Error": "BadRequest",
+ "Description": "Agent update failed!"
+ })
+
+ def respond(self, responseCode, response, location=None):
+ """ Builds the request repsonse """
+
+ return Response(response=json.dumps(response, indent=4), status=responseCode,
+ mimetype="application/json")
diff --git a/Context/Broker.py b/Context/Broker.py
new file mode 100644
index 0000000..c53cbfc
--- /dev/null
+++ b/Context/Broker.py
@@ -0,0 +1,366 @@
+#!/usr/bin/env python3
+######################################################################################################
+#
+# Organization: Peter Moss Leukemia AI Research
+# Repository: HIAS: Hospital Intelligent Automation System
+#
+# Author: Adam Milton-Barker (AdamMiltonBarker.com)
+#
+# Title: HIAS HDSI Context Broker
+# Description: The HIAS HDSI Context Broker handles contextual data for all iotJumpWay
+# devices/applications and IoT Agents. The Context Broker uses the HDSI (HIAS
+# Data Services Interface) API V1, based on Open Mobile Alliance's NGSI V2.
+# License: MIT License
+# Last Modified: 2020-10-18
+#
+######################################################################################################
+
+import json
+import jsonpickle
+import psutil
+import requests
+import os
+import signal
+import sys
+import threading
+
+sys.path.insert(0, os.path.abspath(
+ os.path.join(os.path.dirname(__file__), '..')))
+
+from bson import json_util, ObjectId
+from flask import Flask, request, Response
+from threading import Thread
+
+from Classes.Helpers import Helpers
+from Classes.MongoDB import MongoDB
+from Classes.MQTT import Application
+
+from Agents import Agents
+from Entities import Entities
+
+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)
+
+
+app = Flask(__name__)
+ContextBroker = ContextBroker()
+
+@app.route('/about', methods=['GET'])
+def about():
+ """ Responds to GET requests sent to the /v1/about API endpoint. """
+
+ return ContextBroker.respond(200, {
+ "Response": "OK",
+ "Data": ContextBroker.getBroker()
+ })
+
+@app.route('/entities', methods=['POST'])
+def entitiesPost():
+ """ Responds to POST requests sent to the /v1/entities API endpoint. """
+
+ if request.headers["Content-Type"] == "application/json":
+ query = request.json
+ if query["id"] is None:
+ return ContextBroker.Entities.respond(400, {
+ "Response": "Failed",
+ "Error": "BadRequest",
+ "Description": "Entity ID required!"
+ })
+ return ContextBroker.Entities.createEntity(query)
+ else:
+ return ContextBroker.Entities.respond(405, {
+ "Response": "Failed",
+ "Error": "MethodNotAlowed",
+ "Description": "Method not allowed!"
+ })
+
+@app.route('/entities', methods=['GET'])
+def entitiesGet():
+ """ Responds to GET requests sent to the /v1/entities API endpoint. """
+
+ if request.args.get('type') is None:
+ return ContextBroker.Entities.respond(400, {
+ "Response": "Failed",
+ "Error": "BadRequest",
+ "Description": "Entity type required!"
+ })
+ if request.args.get('limit') is None:
+ limit = 0;
+ else:
+ limit = int(request.args.get('limit'))
+ if request.args.get('values') is None:
+ values = None
+ else:
+ values = request.args.get('values')
+ return ContextBroker.Entities.getEntities(request.args.get('type'),
+ limit, request.args.get('category'), values)
+
+@app.route('/entities/<_id>', methods=['GET'])
+def entityGet(_id):
+ """ Responds to GET requests sent to the /v1/entities/<_id> API endpoint. """
+
+ if request.args.get('type') is None:
+ return ContextBroker.Entities.respond(400, {
+ "Response": "Failed",
+ "Error": "BadRequest",
+ "Description": "Entity type required!"
+ })
+ if request.args.get('attrs') is None:
+ attrs = None
+ else:
+ attrs = request.args.get('attrs')
+ return ContextBroker.Entities.getEntity(request.args.get('type'), _id, attrs)
+
+@app.route('/entities/<_id>/attrs', methods=['PATCH'])
+def entitiesUpdate(_id):
+ """ Responds to PATCH requests sent to the /v1/entities/<_id>/attrs API endpoint. """
+
+ if request.headers["Content-Type"] == "application/json":
+ query = request.json
+ if request.args.get('type') is None:
+ return ContextBroker.Entities.respond(400, {
+ "Response": "Failed",
+ "Error": "BadRequest",
+ "Description": "Entity ID required!"
+ })
+ return ContextBroker.Entities.updateEntity(_id, request.args.get('type'), query)
+ else:
+ return ContextBroker.Entities.respond(405, {
+ "Response": "Failed",
+ "Error": "MethodNotAlowed",
+ "Description": "Method not allowed!"
+ })
+
+@app.route('/entities/<_id>', methods=['DELETE'])
+def entityDelete(_id):
+ """ Responds to DELETE requests sent to the /v1/entities/<_id> API endpoint. """
+
+ if _id is None:
+ return ContextBroker.Entities.respond(400, {
+ "Response": "Failed",
+ "Error": "BadRequest",
+ "Description": "Entity ID required!"
+ })
+ if request.args.get('type') is None:
+ return ContextBroker.Entities.respond(400, {
+ "Response": "Failed",
+ "Error": "BadRequest",
+ "Description": "Entity type required!"
+ })
+ return ContextBroker.Entities.deleteEntity(request.args.get('type'), _id)
+
+@app.route('/agents', methods=['POST'])
+def agentsPost():
+ """ Responds to POST requests sent to the /v1/agents API endpoint. """
+
+ if request.headers["Content-Type"] == "application/json":
+ query = request.json
+ if query["id"] is None:
+ return ContextBroker.Agents.respond(400, {
+ "Response": "Failed",
+ "Error": "BadRequest",
+ "Description": "Agent ID required!"
+ })
+ return ContextBroker.Agents.createAgent(query)
+ else:
+ return ContextBroker.Agents.respond(405, {
+ "Response": "Failed",
+ "Error": "MethodNotAlowed",
+ "Description": "Method not allowed!"
+ })
+
+@app.route('/agents', methods=['GET'])
+def agentsGet():
+ """ Responds to GET requests sent to the /v1/agents API endpoint. """
+
+ if request.args.get('limit') is None:
+ limit = 0;
+ else:
+ limit = int(request.args.get('limit'))
+ return ContextBroker.Agents.getAgents(limit)
+
+@app.route('/agents/<_id>', methods=['GET'])
+def agentGet(_id):
+ """ Responds to GET requests sent to the /v1/agents/<_id> API endpoint. """
+
+ if request.args.get('attrs') is None:
+ attrs = None
+ else:
+ attrs = request.args.get('attrs')
+ return ContextBroker.Agents.getAgent(_id, attrs)
+
+@app.route('/agents/<_id>/attrs', methods=['PATCH'])
+def agentUpdate(_id):
+ """ Responds to PATCH requests sent to the /v1/agents/<_id>/attrs API endpoint. """
+
+ if request.headers["Content-Type"] == "application/json":
+ data = request.json
+ return ContextBroker.Agents.updateAgent(_id, data)
+ else:
+ return ContextBroker.Agents.respond(405, {
+ "Response": "Failed",
+ "Error": "MethodNotAlowed",
+ "Description": "Method not allowed!"
+ })
+
+@app.route('/agents/<_id>', methods=['DELETE'])
+def agentDelete(_id):
+ """ Responds to DELETE requests sent to the /v1/agents/<_id> API endpoint. """
+
+ if _id is None:
+ return ContextBroker.Agents.respond(400, {
+ "Response": "Failed",
+ "Error": "BadRequest",
+ "Description": "Agent ID required!"
+ })
+ return ContextBroker.Agents.deleteAgent(_id)
+
+def main():
+ signal.signal(signal.SIGINT, ContextBroker.signal_handler)
+ signal.signal(signal.SIGTERM, ContextBroker.signal_handler)
+
+ ContextBroker.mongoDbConnection()
+ ContextBroker.iotConnection()
+ ContextBroker.configureBroker()
+
+ Thread(target=ContextBroker.life, args=(), daemon=True).start()
+
+ app.run(host=ContextBroker.Helpers.confs["iotJumpWay"]["ip"],
+ port=ContextBroker.Helpers.confs["iotJumpWay"]["ContextBroker"]["port"])
+
+if __name__ == "__main__":
+ main()
diff --git a/Context/Entities.py b/Context/Entities.py
new file mode 100644
index 0000000..1cb1850
--- /dev/null
+++ b/Context/Entities.py
@@ -0,0 +1,249 @@
+#!/usr/bin/env python3
+######################################################################################################
+#
+# Organization: Peter Moss Leukemia AI Research
+# Repository: HIAS: Hospital Intelligent Automation System
+#
+# Author: Adam Milton-Barker (AdamMiltonBarker.com)
+#
+# Title: HIAS HDSI Context Broker
+# Description: The HIAS HDSI Context Broker handles contextual data for all iotJumpWay
+# devices/applications and IoT Agents. The Context Broker uses the HDSI (HIAS
+# Data Services Interface) API V1, based on Open Mobile Alliance's NGSI V2.
+# License: MIT License
+# Last Modified: 2020-10-18
+#
+######################################################################################################
+
+import json
+import jsonpickle
+import os
+import sys
+
+from bson import json_util, ObjectId
+from flask import Response
+
+from Classes.Helpers import Helpers
+
+
+class Entities():
+ """ Entities Class
+
+ Handles Entity functionality for the HIAS HDSI Context Broker.
+ """
+
+ def __init__(self, mongoConnection):
+ """ Initializes the class. """
+
+ self.Helpers = Helpers("Entities")
+ self.MongoDB = mongoConnection
+ self.Helpers.logger.info("Entities Class initialization complete.")
+
+ def createEntity(self, data):
+ """ Creates a new NDSI Entity """
+
+ if data["type"] == "Location":
+ collection = self.MongoDB.locationsCollection
+ elif data["type"] == "Zone":
+ collection = self.MongoDB.zonesCollection
+ elif data["type"] == "Device":
+ collection = self.MongoDB.devicesCollection
+ elif data["type"] == "Application":
+ collection = self.MongoDB.applicationsCollection
+ elif data["type"] == "Patient":
+ collection = self.MongoDB.patientsCollection
+ elif data["type"] == "Staff":
+ collection = self.MongoDB.staffCollection
+ elif data["type"] == "Thing":
+ collection = self.MongoDB.thingsCollection
+ elif data["type"] == "Model":
+ collection = self.MongoDB.modelsCollection
+ else:
+ return self.respond(400, {
+ "Response": "Failed",
+ "Error": "BadRequest",
+ "Description": "Entity type not supported!"
+ })
+
+ _id = self.MongoDB.insertData(collection, data, data["type"])
+
+ resp = {
+ "Response": "OK",
+ "ID": str(_id),
+ "Entity": json.loads(json_util.dumps(data))
+ }
+
+ if str(_id) is not False:
+ return self.respond(201, resp, "v1/entities/" + data["id"] + "?type=" + data["type"])
+ else:
+ return self.respond(400, {
+ "Response": "Failed",
+ "Error": "BadRequest",
+ "Description": "Entity storage failed!"
+ })
+
+ def getEntities(self, typeof, limit=0, category=None, values=None):
+ """ Gets all NDSI Entities """
+
+ if typeof == "Location":
+ collection = self.MongoDB.locationsCollection
+ elif typeof == "Zone":
+ collection = self.MongoDB.zonesCollection
+ elif typeof == "Device":
+ collection = self.MongoDB.devicesCollection
+ elif typeof == "Application":
+ collection = self.MongoDB.applicationsCollection
+ elif typeof == "Patient":
+ collection = self.MongoDB.patientsCollection
+ elif typeof == "Staff":
+ collection = self.MongoDB.staffCollection
+ elif typeof == "Thing":
+ collection = self.MongoDB.thingsCollection
+ elif typeof == "Model":
+ collection = self.MongoDB.modelsCollection
+ else:
+ return self.respond(400, {
+ "Response": "Failed",
+ "Error": "BadRequest",
+ "Description": "Entity type not supported!"
+ })
+
+ entities = self.MongoDB.getData(collection, limit, category, values)
+
+ if not entities:
+ return self.respond(404, {
+ "Response": "Failed",
+ "Error": "NotFound",
+ "Description": "No entities exist for this type!"
+ })
+ else:
+ resp = {
+ "Response": "OK",
+ "Data": json.loads(json_util.dumps(entities))
+ }
+ return self.respond(200, resp)
+
+ def getEntity(self, typeof, _id, attrs):
+ """ Gets a specific NDSI Entity """
+
+ if typeof == "Location":
+ collection = self.MongoDB.locationsCollection
+ elif typeof == "Zone":
+ collection = self.MongoDB.zonesCollection
+ elif typeof == "Device":
+ collection = self.MongoDB.devicesCollection
+ elif typeof == "Application":
+ collection = self.MongoDB.applicationsCollection
+ elif typeof == "Patient":
+ collection = self.MongoDB.patientsCollection
+ elif typeof == "Staff":
+ collection = self.MongoDB.staffCollection
+ elif typeof == "Thing":
+ collection = self.MongoDB.thingsCollection
+ elif typeof == "Model":
+ collection = self.MongoDB.modelsCollection
+ else:
+ return self.respond(400, {
+ "Response": "Failed",
+ "Error": "BadRequest",
+ "Description": "Entity type not supported!"
+ })
+
+ entity = self.MongoDB.getDataById(collection, _id, attrs)
+
+ if not entity:
+ return self.respond(404, {
+ "Response": "Failed",
+ "Error": "NotFound",
+ "Description": "Entity does not exist!"
+ })
+ else:
+ resp = {
+ "Response": "OK",
+ "Data": json.loads(json_util.dumps(entity[0]))
+ }
+ return self.respond(200, resp)
+
+ def updateEntity(self, _id, typeof, data):
+ """ Updates an NDSI Entity """
+
+ if typeof == "Location":
+ collection = self.MongoDB.locationsCollection
+ elif typeof == "Zone":
+ collection = self.MongoDB.zonesCollection
+ elif typeof == "Device":
+ collection = self.MongoDB.devicesCollection
+ elif typeof == "Application":
+ collection = self.MongoDB.applicationsCollection
+ elif typeof == "Patient":
+ collection = self.MongoDB.patientsCollection
+ elif typeof == "Staff":
+ collection = self.MongoDB.staffCollection
+ elif typeof == "Thing":
+ collection = self.MongoDB.thingsCollection
+ elif typeof == "Model":
+ collection = self.MongoDB.modelsCollection
+ else:
+ return self.respond(400, {
+ "Response": "Failed",
+ "Error": "BadRequest",
+ "Description": "Entity type not supported!"
+ })
+
+ updated = self.MongoDB.updateData(_id, collection, data)
+
+ if updated is True:
+ return self.respond(200, {
+ "Response": "OK"
+ })
+ else:
+ return self.respond(400, {
+ "Response": "OK",
+ "Error": "BadRequest",
+ "Description": "Entity update failed!"
+ })
+
+ def deleteEntity(self, typeof, _id):
+ """ Deletes an NDSI Entity """
+
+ if typeof == "Location":
+ collection = self.MongoDB.locationsCollection
+ elif typeof == "Zone":
+ collection = self.MongoDB.zonesCollection
+ elif typeof == "Device":
+ collection = self.MongoDB.devicesCollection
+ elif typeof == "Application":
+ collection = self.MongoDB.applicationsCollection
+ elif typeof == "Patient":
+ collection = self.MongoDB.patientsCollection
+ elif typeof == "Staff":
+ collection = self.MongoDB.staffCollection
+ elif typeof == "Thing":
+ collection = self.MongoDB.thingsCollection
+ elif typeof == "Model":
+ collection = self.MongoDB.modelsCollection
+ else:
+ return self.respond(400, {
+ "Response": "Failed",
+ "Error": "BadRequest",
+ "Description": "Entity type not supported!"
+ })
+
+ updated = self.MongoDB.deleteData(_id, collection)
+
+ if updated is True:
+ return self.respond(200, {
+ "Response": "OK"
+ })
+ else:
+ return self.respond(400, {
+ "Response": "OK",
+ "Error": "BadRequest",
+ "Description": "Entity update failed!"
+ })
+
+ def respond(self, responseCode, response, location=None):
+ """ Builds the request repsonse """
+
+ return Response(response=json.dumps(response, indent=4), status=responseCode,
+ mimetype="application/json")
diff --git a/Documentation/Installation.md b/Documentation/Installation.md
index 34119ce..9c12be8 100644
--- a/Documentation/Installation.md
+++ b/Documentation/Installation.md
@@ -6,7 +6,6 @@
# Table Of Contents
- [Introduction](#introduction)
-- [Required Hardware](#required-hardware)
- [Prerequisites](#prerequisites)
- [Ubuntu Server 18.04.4 LTS](#ubuntu-server-18044-lts)
- [VirtualBox](#virtualbox)
@@ -31,17 +30,18 @@
- [phpMyAdmin](#phpmyadmin)
- [Mongo Database](#mongo-database)
- [SSL Security](#ssl-security)
- - [File Server](#file-server)
- [Private Ethereum Blockchain](#private-ethereum-blockchain)
- [Deploy Smart Contracts With Geth](#deploy-smart-contracts-with-geth)
- - [iotJumpWay Broker](#iotjumpway-broker)
- - [iotJumpWay Location and Applications](#iotjumpway-location-and-applications)
+ - [iotJumpWay MQTT Broker](#iotjumpway-mqtt-broker)
+ - [iotJumpWay AMQP Broker](#iotjumpway-amqp-broker)
+ - [iotJumpWay Location and Applications](#iotjumpway-location-and-applications)
- [Create Admin User](#create-admin-user)
+ - [HIAS Server Services](#hias-server-services)
+ - [File Server](#file-server)
+ - [Finalize Server Settings](#finalize-server-settings)
- [TassAI (Computer Vision)](#tassai-computer-vision)
- [OpenVINO 2020.3](openvino-20203)
- [Install COVID-19 Data Analysis System](#install-covid-19-data-analysis-system)
- - [HIAS Server Services](#hias-server-services)
- - [Finalize Server Settings](#finalize-server-settings)
- [Login To Your Server UI](#login-to-server-ui)
- [HIAS IoT Network](hias-iot-network)
- [Contributing](#contributing)
@@ -55,17 +55,6 @@ The following guide will take you through setting up and installing the [Hospit
-# Required Hardware
-For this tutorial I am using a [UP2 AI Vision Devkit](https://up-board.org/upkits/up-squared-ai-vision-kit/ "UP2 AI Vision Devkit") and a 1.5TB hard-drive for the core server hardware, but you can use any linux machine and hard-drive. For real-world usage in medical centers and hospitals it is suggested to use a device with more resources.
-
-![Required Hardware](../Media/Images/HIAS-Hardware.png)
-
-- 1 x Linux machine (Server)
-- 1 x 1TB (Or more) HDD
-- 1 x Webcam
-
-
-
# Prerequisites
Before you can continue with this tutorial. Please ensure you have completed all of the following prerequisites.
@@ -352,9 +341,12 @@ if [ "$cmsg" = "Y" -o "$cmsg" = "y" ]; then
sudo ufw allow 22
sudo ufw allow 80
sudo ufw allow 443
+ sudo ufw allow 3524
+ sudo ufw allow 5671
sudo ufw allow 8883
sudo ufw allow 8545
sudo ufw allow 9001
+ sudo ufw allow 15671
sudo ufw allow 27017
sudo ufw allow 30303/udp
sudo ufw allow 30303/tcp
@@ -370,72 +362,6 @@ else
exit 1
fi
```
-You should see the following:
-```
-? This script will install UFW Firewall on your HIAS Server. Are you ready (y/n)? y
-Installing UFW
-Reading package lists... Done
-Building dependency tree
-Reading state information... Done
-ufw is already the newest version (0.36-0ubuntu0.18.04.1).
-ufw set to manually installed.
-0 upgraded, 0 newly installed, 0 to remove and 18 not upgraded.
-Testing UFW
-Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
-Firewall is active and enabled on system startup
-Firewall stopped and disabled on system startup
-HIAS Server opening default ports
-Rules updated
-Rules updated (v6)
-Rules updated
-Rules updated (v6)
-Rules updated
-Rules updated (v6)
-Rules updated
-Rules updated (v6)
-Rules updated
-Rules updated (v6)
-Rules updated
-Rules updated (v6)
-Rules updated
-Rules updated (v6)
-Rules updated
-Rules updated (v6)
-Rules updated
-Rules updated (v6)
-Rules updated
-Rules updated (v6)
-Enabling UFW
-Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
-Firewall is active and enabled on system startup
-Checking UFW
-Status: active
-
-To Action From
--- ------ ----
-22 ALLOW Anywhere
-80 ALLOW Anywhere
-443 ALLOW Anywhere
-8883 ALLOW Anywhere
-8545 ALLOW Anywhere
-9001 ALLOW Anywhere
-27017 ALLOW Anywhere
-30303/udp ALLOW Anywhere
-30303/tcp ALLOW Anywhere
-OpenSSH ALLOW Anywhere
-22 (v6) ALLOW Anywhere (v6)
-80 (v6) ALLOW Anywhere (v6)
-443 (v6) ALLOW Anywhere (v6)
-8883 (v6) ALLOW Anywhere (v6)
-8545 (v6) ALLOW Anywhere (v6)
-9001 (v6) ALLOW Anywhere (v6)
-27017 (v6) ALLOW Anywhere (v6)
-30303/udp (v6) ALLOW Anywhere (v6)
-30303/tcp (v6) ALLOW Anywhere (v6)
-OpenSSH (v6) ALLOW Anywhere (v6)
-
-Installed UFW
-```
**Shell Script** [UFW.sh](../Scripts/Installation/Shell/UFW.sh "UFW.sh")
### Fail2Ban
@@ -472,16 +398,6 @@ else
exit 1
fi
```
-You should see the following:
-```
-Shutdown successful
-Server ready
-```
-```
-Status
-|- Number of jail: 1
-`- Jail list: sshd
-```
**Shell Script** [Fail2Ban.sh](../Scripts/Installation/Shell/Fail2Ban.sh "Fail2Ban.sh")
@@ -507,10 +423,8 @@ if [ "$cmsg" = "Y" -o "$cmsg" = "y" ]; then
sudo usermod -a -G www-data $USER
echo ""
read -p "? Please provide the full domain name of your server, including subdomain: " domain
- read -p "? Please provide the IP of your HIAS server: " ip
if [ "$domain" != "" ]; then
sudo sed -i -- "s/server_name _;/server_name $domain;/g" /etc/nginx/sites-available/default
- sudo sed -i -- "s/HiasServerIp/$ip;/g" /etc/nginx/sites-available/default
sudo nginx -t
sudo systemctl reload nginx
echo "- Installed NGINX";
@@ -524,20 +438,19 @@ else
exit 1
fi
```
-- Installs Nginx
-- Makes a copy of the default Nginx configuration named default.backup
-- Makes the **var** directory on the mounted hard-drive.
-- Copies the HIAS files structure to the var directory from the cloned repository.
-- Changes the server name to your domain name.
-- Changes the server IP to your IP.
-- Checks the NGINX confirguration.
-- Reloads NGINX
-
You can check the Nginx logs by using the following command:
```
cat /var/log/nginx/error.log
```
+You can edit the configuration for the NGINX server using the following command:
+```
+sudo nano /etc/nginx/sites-available/default
+```
+You can reload the NGINX service using the following command:
+```
+sudo systemctl reload nginx
+```
**Shell Script** [NGINX.sh](../Scripts/Installation/Shell/NGINX.sh "NGINX.sh")
@@ -590,13 +503,15 @@ if [ "$cmsg" = "Y" -o "$cmsg" = "y" ]; then
echo "- Installing PHP"
sudo apt-get install php-fpm php-mysql
sudo sed -i -- 's/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/g' /etc/php/7.2/fpm/php.ini
+ sudo sed -i -- 's/upload_max_filesize = 20M/upload_max_filesize = 100M/g' /etc/php/7.2/fpm/php.ini
+ sudo sed -i -- 's/post_max_size = 20M/post_max_size = 100M/g' /etc/php/7.2/fpm/php.ini
sudo systemctl restart php7.2-fpm
read -p "? Please provide the full domain name of your server, including subdomain: " domain
read -p "? Please provide the IP of your server: " ip
if [ "$domain" != "" ]; then
sudo cp Root/etc/nginx/sites-available/default /etc/nginx/sites-available/default
sudo sed -i -- "s#root /var/www/html;#root /fserver/var/www/html;#g" /etc/nginx/sites-available/default
- sudo sed -i -- "s/YourSubdomain.YourDomain.TLD/$domain/g" /etc/nginx/sites-available/default
+ sudo sed -i -- "s/YourHiasDomainName/$domain/g" /etc/nginx/sites-available/default
sudo sed -i -- "s/HiasServerIp/$ip/g" /etc/nginx/sites-available/default
sudo nginx -t
sudo systemctl reload nginx
@@ -612,13 +527,6 @@ else
exit 1
fi
```
-You should see:
-```
-nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
-nginx: configuration file /etc/nginx/nginx.conf test is successful
-- You can now view your PHP configuration at https://www.YourDomain.com/info
-- Installed PHP
-```
If you now visit the info page your website ie: https://www.YourDomain.com/info you should see the PHP configuration of your server.
![PHP config](../Media/Images/php.png)
@@ -643,6 +551,10 @@ bash Scripts/Installation/Shell/MySQL.sh
```
The contents of the above file as follows:
```
+FMSG="- MySQL installation terminated"
+
+read -p "? This script will install MySQL on your HIAS Server. Are you ready (y/n)? " cmsg
+
if [ "$cmsg" = "Y" -o "$cmsg" = "y" ]; then
echo "- Installing MySQL"
echo "! Make sure you keep note of all passwords etc you create."
@@ -660,21 +572,20 @@ if [ "$cmsg" = "Y" -o "$cmsg" = "y" ]; then
sudo mysql -uroot -p$rpassword -e "SELECT host, user from mysql.user";
read -p "! Enter a new application database user: " adbusername
read -p "! Enter a new application database password: " adbpassword
- sudo mysql -uroot -p$rpassword -e "GRANT SELECT, INSERT, DELETE ON *.* TO $adbusername@localhost IDENTIFIED BY '$adbpassword'";
+ sudo mysql -uroot -p$rpassword -e "GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO $adbusername@localhost IDENTIFIED BY '$adbpassword'";
sudo mysql -uroot -p$rpassword -e "SELECT host, user from mysql.user";
read -p "! Enter a new database name: " dbname
sudo mysql -uroot -p$rpassword -e "CREATE DATABASE $dbname";
sudo mysql -uroot -p$rpassword -e 'show databases;'
sudo mysql -uroot -p$rpassword -e "use $dbname;"
sudo mysql -uroot -p$rpassword $dbname < Scripts/Installation/SQL.sql;
- sudo sed -i "s/\"dbname\":.*/\"dbname\": \"$dbname\",/g" "confs.json"
- sudo sed -i "s/\"dbuser\":.*/\"dbuser\": \"$adbusername\",/g" "confs.json"
- sudo sed -i "s/\"dbpass\":.*/\"dbpass\": \"${adbpassword//&/\\&}\"/g" "confs.json"
sudo sed -i "s/\"dbname\":.*/\"dbname\": \"$dbname\",/g" "/fserver/var/www/Classes/Core/confs.json"
sudo sed -i "s/\"dbusername\":.*/\"dbusername\": \"$adbusername\",/g" "/fserver/var/www/Classes/Core/confs.json"
- sudo sed -i "s/\"dbpassword\":.*/\"dbpassword\": \"${adbpassword//&/\\&}\",/g" "/fserver/var/www/Classes/Core/confs.json"
- read -p "! Enter a new encryption key, this key should be 32 characters: " ekey
- sudo sed -i "s/\"key\":.*/\"key\": \"$ekey\"/g" "/fserver/var/www/Classes/Core/confs.json"
+ escaped=$(printf '%s\n' "$adbpassword" | sed -e 's/[\/&]/\\&/g');
+ sudo sed -i "s/\"dbpassword\":.*/\"dbpassword\": \"$escaped\",/g" "/fserver/var/www/Classes/Core/confs.json"
+ read -p "! Enter a new encryption key, this key should be 32 characters an NO special characters: " ekey
+ escaped=$(printf '%s\n' "$ekey" | sed -e 's/[\/&]/\\&/g');
+ sudo sed -i "s/\"key\":.*/\"key\": \"$escaped\"/g" "/fserver/var/www/Classes/Core/confs.json"
echo "! Updated MySql configuration."
echo "! Moving MySql to hard-drive."
sudo systemctl stop mysql
@@ -689,6 +600,7 @@ if [ "$cmsg" = "Y" -o "$cmsg" = "y" ]; then
sudo rm -Rf /var/lib/mysql
sudo systemctl start mysql
sudo systemctl status mysql
+ sudo systemctl reload nginx
echo "! Moved MySql to hard-drive."
exit 0
else
@@ -738,7 +650,7 @@ To run this installation file use the following command:
bash Scripts/Installation/Shell/MongoDB.sh
```
-**If the text editors open before the mongodb, you will need to close them and manually start the mongo console using the command mongo**
+**If the text editors open before the mongodb, you will need to close them and manually start the mongo console using the command mongo, the continue the installation by running each install file individually**
The contents of the above file as follows:
```
@@ -749,26 +661,29 @@ read -p "? This script will install MongoDB on your HIAS Server. Are you ready (
if [ "$cmsg" = "Y" -o "$cmsg" = "y" ]; then
echo "- Installing MongoDB"
wget -qO - https://www.mongodb.org/static/pgp/server-4.2.asc | sudo apt-key add -
- sudo apt-get install gnupg
+ sudo apt install gnupg
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.2 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.2.list
- sudo apt-get update
- sudo apt-get install -y mongodb-org
- sudo apt-get install php-mongodb
+ sudo apt update
+ sudo apt install -y mongodb-org
+ sudo apt install php-mongodb
+ pip3 install pymongo
sudo systemctl enable mongod.service
sudo systemctl start mongod
sudo systemctl status mongod
+ sudo systemctl restart php7.2-fpm
read -p "! The MongoDB console will now open, you will need to follow the steps in the Mongo Database section of the installation file to create your database credentials. Are you ready (y/n)? " cmsg
if [ "$cmsg" = "Y" -o "$cmsg" = "y" ]; then
mongo
read -p "! Enter your MongoDB database name: " dbn
read -p "! Enter your MongoDB database username: " dbu
read -p "! Enter your MongoDB database password: " dbp
- sudo sed -i "s/\"mdb\":.*/\"mdb\": \"$dbn\",/g" "confs.json"
- sudo sed -i "s/\"mdbu\":.*/\"mdbu\": \"$dbu\",/g" "confs.json"
- sudo sed -i "s/\"mdbp\":.*/\"mdbp\": \"${dbp//&/\\&}\",/g" "confs.json"
+ escaped=$(printf '%s\n' "$dbp" | sed -e 's/[\/&]/\\&/g');
+ sudo sed -i "s/\"db\":.*/\"db\": \"$dbn\",/g" "confs.json"
+ sudo sed -i "s/\"dbu\":.*/\"dbu\": \"$dbu\",/g" "confs.json"
+ sudo sed -i "s/\"dbp\":.*/\"dbp\": \"$escaped\"/g" "confs.json"
sudo sed -i "s/\"mdbname\":.*/\"mdbname\": \"$dbn\",/g" "/fserver/var/www/Classes/Core/confs.json"
sudo sed -i "s/\"mdbusername\":.*/\"mdbusername\": \"$dbu\",/g" "/fserver/var/www/Classes/Core/confs.json"
- sudo sed -i "s/\"mdbpassword\":.*/\"mdbpassword\": \"${dbn//&/\\&}\",/g" "/fserver/var/www/Classes/Core/confs.json"
+ sudo sed -i "s/\"mdbpassword\":.*/\"mdbpassword\": \"$escaped\",/g" "/fserver/var/www/Classes/Core/confs.json"
echo "- Installed MongoDB and configured database";
exit 0
else
@@ -780,20 +695,6 @@ else
exit 1
fi
```
-You should see the following:
-```
-Created symlink /etc/systemd/system/multi-user.target.wants/mongod.service → /lib/systemd/system/mongod.service.
-● mongod.service - MongoDB Database Server
- Loaded: loaded (/lib/systemd/system/mongod.service; enabled; vendor preset: enabled)
- Active: active (running) since Sat 2020-10-10 11:53:16 UTC; 32ms ago
- Docs: https://docs.mongodb.org/manual
- Main PID: 20213 (mongod)
- CGroup: /system.slice/mongod.service
- └─20213 /usr/bin/mongod --config /etc/mongod.conf
-
-Oct 10 11:53:16 hiasssl systemd[1]: Started MongoDB Database Server.
-```
-
When the mongo client opens during installation, you need to follow these steps:
- Create an admin database and user, replacing **username** and **password** with your desired username and password.
@@ -828,7 +729,7 @@ db.createUser(
)
```
-**Shell Script** [phpMyAdmin.sh](../Scripts/Installation/Shell/phpMyAdmin.sh "phpMyAdmin.sh")
+**Shell Script** [MongoDB.sh](../Scripts/Installation/Shell/MongoDB.sh "MongoDB.sh")
### SSL Security
@@ -865,113 +766,6 @@ nginx: configuration file /etc/nginx/nginx.conf test is successful
```
**Shell Script** [SSL.sh](../Scripts/Installation/Shell/SSL.sh "SSL.sh")
-### File Server
-We will use Samba to create a private network file share.
-
-To run this installation file use the following command:
-```
-sh Scripts/Installation/Shell/Samba.sh
-```
-The contents of the above file as follows:
-```
-read -p "? This script will install Samba on your HIAS Server. Are you ready (y/n)? " cmsg
-
-if [ "$cmsg" = "Y" -o "$cmsg" = "y" ]; then
- echo "Installing Samba"
- sudo apt install samba
- sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.backup
- sudo sed -i -- "s/; bind interfaces only = yes/bind interfaces only = yes/g" /etc/samba/smb.conf
- testparm
- sudo systemctl restart smbd
- sudo systemctl status smbd
- echo "Creating Samba directory"
- sudo mkdir -p /fserver/samba
- sudo chgrp sambashare /fserver/samba
- echo "Creating Samba admins group & directory"
- sudo groupadd sambashare
- sudo groupadd smbadmins
- sudo mkdir -p /fserver/samba/smbadmins
- sudo chgrp smbadmins /fserver/samba/smbadmins
- sudo chmod -R 770 /fserver/samba/smbadmins
- echo "Creating Samba admin user"
- read -p "! Enter a new Samba username for your admin account: " sauser
- echo "$sauser"
- sudo useradd -M -d /fserver/samba/users -s /usr/sbin/nologin -G sambashare,smbadmins "$sauser"
- sudo smbpasswd -a "$sauser"
- sudo smbpasswd -e "$sauser"
- sudo mkdir /fserver/samba/users
- sudo chown "$sauser":sambashare /fserver/samba/users
- sudo chmod 2770 /fserver/samba/users
- echo "Creating Samba user"
- read -p "! Enter a new Samba username for yourself: " suser
- sudo useradd -M -d /fserver/samba/"$suser" -s /usr/sbin/nologin -G sambashare "$suser"
- sudo mkdir -p /fserver/samba/"$suser"
- sudo chown "$suser":sambashare /fserver/samba/"$suser"
- sudo chmod 2770 /fserver/samba/"$suser"
- sudo smbpasswd -a "$suser"
- sudo smbpasswd -e "$suser"
- echo "Finalizing Samba admin settings"
- echo "" | sudo tee -a /etc/samba/smb.conf
- echo "[users]" | sudo tee -a /etc/samba/smb.conf
- echo " path = /fserver/samba/users" | sudo tee -a /etc/samba/smb.conf
- echo " browseable = yes" | sudo tee -a /etc/samba/smb.conf
- echo " read only = no" | sudo tee -a /etc/samba/smb.conf
- echo " force create mode = 0660" | sudo tee -a /etc/samba/smb.conf
- echo " force directory mode = 2770" | sudo tee -a /etc/samba/smb.conf
- echo " valid users = @sambashare @smbadmins" | sudo tee -a /etc/samba/smb.conf
- echo "" | sudo tee -a /etc/samba/smb.conf
- echo "[smbadmins]" | sudo tee -a /etc/samba/smb.conf
- echo " path = /fserver/samba/smbadmins" | sudo tee -a /etc/samba/smb.conf
- echo " browseable = no" | sudo tee -a /etc/samba/smb.conf
- echo " read only = no" | sudo tee -a /etc/samba/smb.conf
- echo " force create mode = 0660" | sudo tee -a /etc/samba/smb.conf
- echo " force directory mode = 2770" | sudo tee -a /etc/samba/smb.conf
- echo " valid users = @smbadmins" | sudo tee -a /etc/samba/smb.conf
- echo "Finalizing Samba user settings"
- echo "" | sudo tee -a /etc/samba/smb.conf
- echo "[$suser]" | sudo tee -a /etc/samba/smb.conf
- echo " path = /fserver/samba/$suser" | sudo tee -a /etc/samba/smb.conf
- echo " browseable = no" | sudo tee -a /etc/samba/smb.conf
- echo " read only = no" | sudo tee -a /etc/samba/smb.conf
- echo " force create mode = 0660" | sudo tee -a /etc/samba/smb.conf
- echo " force directory mode = 2770" | sudo tee -a /etc/samba/smb.conf
- echo " valid users = $suser @smbadmins" | sudo tee -a /etc/samba/smb.conf
- echo "Reloading Samba and checking status"
- sudo systemctl restart smbd
- sudo systemctl status smbd
- echo "Installed Samba"
- exit 0
-else
- echo "- Samba installation terminated";
- exit 1
-fi
-```
-You should see the following:
-```
-Reloading Samba and checking status
-● smbd.service - Samba SMB Daemon
- Loaded: loaded (/lib/systemd/system/smbd.service; enabled; vendor preset: enabled)
- Active: active (running) since Sat 2020-10-10 11:58:32 UTC; 17ms ago
- Docs: man:smbd(8)
- man:samba(7)
- man:smb.conf(5)
- Main PID: 21845 (smbd)
- Status: "smbd: ready to serve connections..."
- Tasks: 4 (limit: 4915)
- CGroup: /system.slice/smbd.service
- ├─21845 /usr/sbin/smbd --foreground --no-process-group
- ├─21869 /usr/sbin/smbd --foreground --no-process-group
- ├─21870 /usr/sbin/smbd --foreground --no-process-group
- └─21874 /usr/sbin/smbd --foreground --no-process-group
-
-Oct 10 11:58:31 hiasssl systemd[1]: Stopped Samba SMB Daemon.
-Oct 10 11:58:31 hiasssl systemd[1]: Starting Samba SMB Daemon...
-Oct 10 11:58:32 hiasssl systemd[1]: Started Samba SMB Daemon.
-Installed Samba
-```
-
-**Shell Script** [Samba.sh](../Scripts/Installation/Shell/Samba.sh "Samba.sh")
-
### Private Ethereum Blockchain
We will use Ethereum to set up a private Blockchain for the HIAS network. During the installation, the geth console will open, you need to follow the [Deploy Smart Contracts With Geth](#deploy-smart-contracts-with-geth) instructions below.
@@ -992,11 +786,13 @@ if [ "$cmsg" = "Y" -o "$cmsg" = "y" ]; then
sudo apt-get update
sudo apt-get install ethereum
sudo cp -a Root/fserver/ethereum/ /fserver/
- echo "- You will now create the first of the 3 required HIAS Blockchain accounts. Follow the instructions given to create the account for your core HIAS Blockchain user. Make sure you save the information given to you and keep it safe. You will need this information for configuring your HIAS Blockchain and if you lose these details you will have to create a new installation."
+ echo "- You will now create the first of the 4 required HIAS Blockchain accounts. Follow the instructions given to create the account for your core HIAS Blockchain user. Make sure you save the information given to you and keep it safe. You will need this information for configuring your HIAS Blockchain and if you lose these details you will have to create a new installation."
+ geth account new --datadir /fserver/ethereum/HIAS
+ echo "- You will now create the second of the 4 required HIAS Blockchain accounts. Follow the instructions given to create the account for your iotJumpWay MQTT HIAS Blockchain user. Make sure you save the information given to you and keep it safe. You will need this information for configuring your HIAS Blockchain and if you lose these details you will have to create a new installation."
geth account new --datadir /fserver/ethereum/HIAS
- echo "- You will now create the second of the 3 required HIAS Blockchain accounts. Follow the instructions given to create the account for your iotJumpWay HIAS Blockchain user. Make sure you save the information given to you and keep it safe. You will need this information for configuring your HIAS Blockchain and if you lose these details you will have to create a new installation."
+ echo "- You will now create the third of the 4 required HIAS Blockchain accounts. Follow the instructions given to create the account for your iotJumpWay AMQP HIAS Blockchain user. Make sure you save the information given to you and keep it safe. You will need this information for configuring your HIAS Blockchain and if you lose these details you will have to create a new installation."
geth account new --datadir /fserver/ethereum/HIAS
- echo "- You will now create the third of the 3 required HIAS Blockchain accounts. Follow the instructions given to create the account for your personal HIAS Blockchain user. Make sure you save the information given to you and keep it safe. You will need this information for configuring your HIAS Blockchain and if you lose these details you will have to create a new installation."
+ echo "- You will now create the fourth of the 4 required HIAS Blockchain accounts. Follow the instructions given to create the account for your personal HIAS Blockchain user. Make sure you save the information given to you and keep it safe. You will need this information for configuring your HIAS Blockchain and if you lose these details you will have to create a new installation."
geth account new --datadir /fserver/ethereum/HIAS
echo "- You will now install Solidity and configure/compile the HIAS Blockhain Smart Contracts."
sudo apt-get install solc
@@ -1024,11 +820,13 @@ if [ "$cmsg" = "Y" -o "$cmsg" = "y" ]; then
read -p "! Enter your HIAS Blockchain user account address: " haddress
read -p "! Enter your HIAS Blockchain user account password: " hpass
sudo sed -i 's/\"haddress\":.*/\"haddress\": \"'$haddress'\",/g' "confs.json"
- sudo sed -i 's/\"hpass\":.*/\"hpass\": \"'${hpass//&/\\&}'\",/g' "confs.json"
- read -p "! Enter your iotJumpWay HIAS Blockchain user account address: " iaddress
- read -p "! Enter your iotJumpWay HIAS Blockchain user account password: " ipass
+ escaped=$(printf '%s\n' "$hpass" | sed -e 's/[\/&]/\\&/g');
+ sudo sed -i 's/\"hpass\":.*/\"hpass\": \"'$escaped'\",/g' "confs.json"
+ read -p "! Enter your iotJumpWay MQTT HIAS Blockchain user account address: " iaddress
+ read -p "! Enter your iotJumpWay MQTT HIAS Blockchain user account password: " ipass
sudo sed -i 's/\"iaddress\":.*/\"iaddress\": \"'$iaddress'\",/g' "confs.json"
- sudo sed -i 's/\"ipass\":.*/\"ipass\": \"'${ipass//&/\\&}'\",/g' "confs.json"
+ escaped=$(printf '%s\n' "$ipass" | sed -e 's/[\/&]/\\&/g');
+ sudo sed -i 's/\"ipass\":.*/\"ipass\": \"'$escaped'\",/g' "confs.json"
read -p "! Enter your personal HIAS Blockchain user account address: " paddress
echo "- Now you will update the Genesis file."
read -p "! Enter your HIAS Blockchain chain ID: " chainid
@@ -1058,9 +856,9 @@ if [ "$cmsg" = "Y" -o "$cmsg" = "y" ]; then
sudo sed -i 's/\"authContract\":.*/\"authContract\": \"'$hcaddress'\",/g' "confs.json"
sudo sed -i 's/\"iotContract\":.*/\"iotContract\": \"'$icaddress'\",/g' "confs.json"
sudo sed -i 's/\"patientsContract\":.*/\"patientsContract\": \"'$pcaddress'\"/g' "confs.json"
- php Scripts/Installation/PHP/Blockchain.php "Contract" "$hcaddress" "HIAS" "$haddress" "$hctransaction" "$habi"
- php Scripts/Installation/PHP/Blockchain.php "Contract" "$icaddress" "HIAS" "$haddress" "$ictransaction" "$iabi"
- php Scripts/Installation/PHP/Blockchain.php "Contract" "$pcaddress" "HIAS" "$haddress" "$pctransaction" "$pabi"
+ php Scripts/Installation/PHP/Blockchain.php "Contract" "$hcaddress" "HIAS Permissions & Registrations" "$haddress" "$hctransaction" "$habi"
+ php Scripts/Installation/PHP/Blockchain.php "Contract" "$icaddress" "iotJumpWay Data Integrity" "$haddress" "$ictransaction" "$iabi"
+ php Scripts/Installation/PHP/Blockchain.php "Contract" "$pcaddress" "Patients" "$haddress" "$pctransaction" "$pabi"
php Scripts/Installation/PHP/Blockchain.php "Config"
echo "- Now you will install composer and the web3 PHP and Python libraries."
pip3 install web3
@@ -1105,7 +903,7 @@ First deploy the HIAS Smart Contract. Note that **0x** in the hbin variable is c
var habi = ContentsOfHIAS.abi
var hbin = "0xContentsOfHIAS.bin"
var haddress = "YourHiasBlockchainAddress"
- var hpass = "hiasssl"
+ var hpass = "YourHiasBlockchainPassword"
personal.unlockAccount(haddress, hpass, 1200)
var newContract = eth.contract(habi)
var deploy = {from:haddress, data:hbin, gas: 5000000 }
@@ -1181,18 +979,17 @@ You now need to log directly into your HIAS server and start the HIAS Blockchain
geth --mine --http --networkid $chainid -datadir /fserver/ethereum/HIAS --http.addr $ip --http.corsdomain "*" --miner.etherbase $haddress --http.api "eth,net,web3,personal" --allow-insecure-unlock console
miner.start()
```
-This needs to be running at all times which is why you logged directly into your HIAS device, if you do not have your Blockchain running, you will not be able to log in to the HIAS UI, if the Blockchain goes down, you will be logged out instantly. Now you can go back to your remote terminal to continue the installation.
-### iotJumpWay Broker
-We will use the [iotJumpWay](https://www.iotjumpway.com/developers/getting-started "iotJumpWay") open source broker for this project. Originally the iotJumpWay was a device built on a Rapsberry Pi that powered my home IoT network locally. In 2015/16 I turned the device into an a Platform as a Service, PaaS, and in 2016 I made the platform free to developers.
+This needs to be running at all times which is why you logged directly into your HIAS device, if you do not have your Blockchain running, you will not be able to log in to the HIAS UI, if the Blockchain goes down, you will be logged out instantly. Now you can go back to your remote terminal to continue the installation.
-For this project I am including a system based on the iotJumpWay PaaS that includes the iotJumpWay locations, zones, devices and applications functionality. This means that all of the machine to machine communication happens locally, and all data is stored locally, never leaving the server.
+**Shell Script** [Blockchain.sh](../Scripts/Installation/Shell/Blockchain.sh "Blockchain.sh")
-Now install the required MQTT software for our local iotJumpWay broker.
+### iotJumpWay MQTT Broker
+Now install the required MQTT software for our local iotJumpWay MQTT broker.
To run this installation file use the following command:
```
-bash Scripts/Installation/Shell/iotJumpWay.sh
+bash Scripts/Installation/Shell/MqttBroker.sh
```
The contents of the above file as follows:
```
@@ -1208,17 +1005,20 @@ if [ "$cmsg" = "Y" -o "$cmsg" = "y" ]; then
sudo apt install libcurl4-openssl-dev
sudo apt install perl-doc uuid-dev bsdutils gcc g++ git make dialog libssl-dev libc-ares-dev libcurl4-openssl-dev libmysqlclient-dev libwrap0 libwrap0-dev libwebsockets-dev uthash-dev
pip3 install paho-mqtt
+ pip3 install jsonpickle
+ pip3 install flask
read -p "! Enter your HIAS domain name: " domain
- read -p "! Enter your server login user: " user
+ read -p "! Enter your HIAS IP: " ip
sudo mkdir -p /fserver/libraries/mosquitto
- sudo mkdir -p /fserver/libraries/mosquitto/certs
+ sudo mkdir -p /fserver/certs
sudo mkdir -p /fserver/var/log/mosquitto
sudo touch /fserver/var/log/mosquitto/mosquitto.log
- sudo chown -R $user:$user /fserver/var/log/mosquitto/mosquitto.log
- sudo cp /etc/letsencrypt/live/$domain/fullchain.pem /fserver/libraries/mosquitto/certs/
- sudo cp /etc/letsencrypt/live/$domain/cert.pem /fserver/libraries/mosquitto/certs/
- sudo cp /etc/letsencrypt/live/$domain/privkey.pem /fserver/libraries/mosquitto/certs/
- sudo chown -R $user:$user /fserver/libraries/mosquitto -R
+ sudo chown -R $USER:$USER /fserver/var/log/mosquitto/mosquitto.log
+ sudo cp /etc/letsencrypt/live/$domain/fullchain.pem /fserver/certs/
+ sudo cp /etc/letsencrypt/live/$domain/cert.pem /fserver/certs/
+ sudo cp /etc/letsencrypt/live/$domain/privkey.pem /fserver/certs/
+ sudo chown -R $USER:$USER /fserver/libraries/mosquitto
+ sudo chmod -R 775 /fserver/certs
cd /fserver/libraries/mosquitto
wget http://mosquitto.org/files/source/mosquitto-1.5.5.tar.gz
tar -xvzf mosquitto-1.5.5.tar.gz
@@ -1242,15 +1042,15 @@ if [ "$cmsg" = "Y" -o "$cmsg" = "y" ]; then
echo "listener 8883" | sudo tee -a /etc/mosquitto/mosquitto.conf
echo "protocol mqtt" | sudo tee -a /etc/mosquitto/mosquitto.conf
echo "tls_version tlsv1.2" | sudo tee -a /etc/mosquitto/mosquitto.conf
- echo "cafile /fserver/libraries/mosquitto/certs/fullchain.pem" | sudo tee -a /etc/mosquitto/mosquitto.conf
- echo "certfile /fserver/libraries/mosquitto/certs/cert.pem" | sudo tee -a /etc/mosquitto/mosquitto.conf
- echo "keyfile /fserver/libraries/mosquitto/certs/privkey.pem" | sudo tee -a /etc/mosquitto/mosquitto.conf
+ echo "cafile /fserver/certs/fullchain.pem" | sudo tee -a /etc/mosquitto/mosquitto.conf
+ echo "certfile /fserver/certs/cert.pem" | sudo tee -a /etc/mosquitto/mosquitto.conf
+ echo "keyfile /fserver/certs/privkey.pem" | sudo tee -a /etc/mosquitto/mosquitto.conf
echo "require_certificate false" | sudo tee -a /etc/mosquitto/mosquitto.conf
echo "listener 9001" | sudo tee -a /etc/mosquitto/mosquitto.conf
echo "protocol websockets" | sudo tee -a /etc/mosquitto/mosquitto.conf
- echo "cafile /fserver/libraries/mosquitto/certs/fullchain.pem" | sudo tee -a /etc/mosquitto/mosquitto.conf
- echo "certfile /fserver/libraries/mosquitto/certs/cert.pem" | sudo tee -a /etc/mosquitto/mosquitto.conf
- echo "keyfile /fserver/libraries/mosquitto/certs/privkey.pem" | sudo tee -a /etc/mosquitto/mosquitto.conf
+ echo "cafile /fserver/certs/fullchain.pem" | sudo tee -a /etc/mosquitto/mosquitto.conf
+ echo "certfile /fserver/certs/cert.pem" | sudo tee -a /etc/mosquitto/mosquitto.conf
+ echo "keyfile /fserver/certs/privkey.pem" | sudo tee -a /etc/mosquitto/mosquitto.conf
cd ../
sudo git clone https://github.com/jpmens/mosquitto-auth-plug.git
cd mosquitto-auth-plug
@@ -1268,12 +1068,13 @@ if [ "$cmsg" = "Y" -o "$cmsg" = "y" ]; then
read -p "! Enter your server user password: " sdup
echo "auth_opt_dbname $sdn" | sudo tee -a /etc/mosquitto/mosquitto.conf
echo "auth_opt_user $sdu" | sudo tee -a /etc/mosquitto/mosquitto.conf
- echo "auth_opt_pass ${sdup//&/\\&}" | sudo tee -a /etc/mosquitto/mosquitto.conf
+ echo "auth_opt_pass ${sdup}" | sudo tee -a /etc/mosquitto/mosquitto.conf
echo "auth_opt_userquery SELECT pw FROM mqttu WHERE uname = '%s'" | sudo tee -a /etc/mosquitto/mosquitto.conf
echo "auth_opt_superquery SELECT COUNT(*) FROM mqttu WHERE uname = '%s' AND super = 1" | sudo tee -a /etc/mosquitto/mosquitto.conf
echo "auth_opt_aclquery SELECT topic FROM mqttua WHERE (username = '%s') AND (rw >= %d)" | sudo tee -a /etc/mosquitto/mosquitto.conf
cd ~/HIAS
sudo sed -i "s/\"host\":.*/\"host\": \"$domain\",/g" "confs.json"
+ sudo sed -i -- "s/YourHiasIP/$ip/g" "confs.json"
sudo sed -i "s/host:.*/host: \"$domain\",/g" "/fserver/var/www/html/iotJumpWay/Classes/iotJumpWay.js"
sudo touch /lib/systemd/system/mosquitto.service
echo "[Unit]" | sudo tee -a /lib/systemd/system/mosquitto.service
@@ -1283,21 +1084,22 @@ if [ "$cmsg" = "Y" -o "$cmsg" = "y" ]; then
echo "Wants=network.target" | sudo tee -a /lib/systemd/system/mosquitto.service
echo "" | sudo tee -a /lib/systemd/system/mosquitto.service
echo "[Service]" | sudo tee -a /lib/systemd/system/mosquitto.service
- echo "User=$user" | sudo tee -a /lib/systemd/system/mosquitto.service
+ echo "User=$USER" | sudo tee -a /lib/systemd/system/mosquitto.service
echo "ExecStart=/usr/local/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf" | sudo tee -a /lib/systemd/system/mosquitto.service
echo "ExecReload=/bin/kill -HUP $MAINPID" | sudo tee -a /lib/systemd/system/mosquitto.service
echo "Restart=on-failure" | sudo tee -a /lib/systemd/system/mosquitto.service
echo "" | sudo tee -a /lib/systemd/system/mosquitto.service
echo "[Install]" | sudo tee -a /lib/systemd/system/mosquitto.service
echo "WantedBy=multi-user.target" | sudo tee -a /lib/systemd/system/mosquitto.service
- sudo sed -i -- "s/ExecStart=\/usr\/bin\/certbot -q renew/ExecStart=\/usr\/bin\/certbot -q renew --deploy-hook \"\/home\/$user\/HIAS\/Scripts\/System\/Certbot.sh\"/g" /lib/systemd/system/certbot.service
- sudo sed -i -- "s/user:user/$user:$user/g" Scripts/System/Certbot.sh
+ sudo sed -i -- "s/ExecStart=\/usr\/bin\/certbot -q renew/ExecStart=\/usr\/bin\/certbot -q renew --deploy-hook \"\/home\/$USER\/HIAS\/Scripts\/System\/Certbot.sh\"/g" /lib/systemd/system/certbot.service
+ sudo sed -i -- "s/user:user/$USER:$USER/g" Scripts/System/Certbot.sh
chmod u+x Scripts/System/Certbot.sh
sudo systemctl daemon-reload
sudo systemctl enable mosquitto.service
sudo systemctl start mosquitto.service
sudo systemctl status mosquitto.service
sudo systemctl restart certbot.service
+ sudo systemctl status certbot.service
echo "- Installed iotJumpWay!";
exit 0
else
@@ -1305,30 +1107,109 @@ else
exit 1
fi
```
-You should see the following output:
+
+**Shell Script** [MqttBroker.sh](../Scripts/Installation/Shell/MqttBroker.sh "MqttBroker.sh")
+
+### iotJumpWay AMQP Broker
+Now install the required AMQP software for our local iotJumpWay MQTT broker.
+
+To run this installation file use the following command:
+```
+bash Scripts/Installation/Shell/AmqpBroker.sh
```
-● mosquitto.service - Mosquitto MQTT Broker
- Loaded: loaded (/lib/systemd/system/mosquitto.service; enabled; vendor preset: enabled)
- Active: active (running) since Sat 2020-10-10 21:12:24 UTC; 1h 30min ago
- Docs: man:mosquitto.conf(5)
- man:mosquitto(8)
- Main PID: 10189 (mosquitto)
- Tasks: 1 (limit: 4915)
- CGroup: /system.slice/mosquitto.service
- └─10189 /usr/local/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf
+The contents of the above file as follows:
+```
+read -p "? This script will install the iotJumpWay AMQP broker on your HIAS Server. Are you ready (y/n)? " cmsg
-Oct 10 21:12:24 hiasssl systemd[1]: Started Mosquitto MQTT Broker.
-Oct 10 21:12:24 hiasssl mosquitto[10189]: 1602364344: |-- *** auth-plug: startup
-Oct 10 21:12:24 hiasssl mosquitto[10189]: 1602364344: |-- ** Configured order: mysql
-Oct 10 21:12:24 hiasssl mosquitto[10189]: 1602364344: |-- }}}} MYSQL
+if [ "$cmsg" = "Y" -o "$cmsg" = "y" ]; then
+ echo "- Installing iotJumpWay AMQP Broker...."
+ sudo tee /etc/apt/sources.list.d/bintray.rabbitmq.list <<-EOF
+ deb https://dl.bintray.com/rabbitmq-erlang/debian bionic erlang
+ deb https://dl.bintray.com/rabbitmq/debian bionic main
+ EOF
+ sudo apt-get update -y
+ sudo apt-get install -y rabbitmq-server
+ sudo touch /etc/rabbitmq/rabbitmq.config
+ pip3 install pika
+ sudo wget https://dl.bintray.com/rabbitmq/community-plugins/rabbitmq_auth_backend_http-3.6.x-61ed0a93.ez -P /usr/lib/rabbitmq/lib/rabbitmq_server-3.6.10/plugins
+ sudo wget http://www.rabbitmq.com/releases/plugins/v2.4.1/mochiweb-2.4.1.ez -P /usr/lib/rabbitmq/lib/rabbitmq_server-3.6.10/plugins
+ sudo rabbitmq-plugins enable rabbitmq_auth_backend_http
+ sudo rabbitmq-plugins enable rabbitmq_management
+ pip3 install gevent
+ sudo touch /etc/rabbitmq/rabbitmq.config
+ read -p "? Enter your HIAS server URL (Without https://): " domain
+ echo "%% -*- mode: erlang -*-" | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo "%% ----------------------------------------------------------------------------" | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo "%% Classic RabbitMQ configuration format example." | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo "%% This format should be considered DEPRECATED." | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo "%%" | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo "%% Users of RabbitMQ 3.7.x" | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo "%% or later should prefer the new style format (rabbitmq.conf)" | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo "%% in combination with an advanced.config file (as needed)." | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo "%%" | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo "%% Related doc guide: https://www.rabbitmq.com/configure.html. See" | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo "%% https://rabbitmq.com/documentation.html for documentation ToC." | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo "%% ----------------------------------------------------------------------------" | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo "[" | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " {rabbit," | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " [" | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " {tcp_listeners, []}," | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " {ssl_listeners, [5671]}," | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " {ssl_options, [{cacertfile,\"/fserver/certs/fullchain.pem\"}," | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " {certfile,\"/fserver/certs/cert.pem\"}," | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " {keyfile,\"/fserver/certs/privkey.pem\"}," | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " {verify,verify_peer}," | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " {fail_if_no_peer_cert,false}," | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " {versions,['tlsv1.2']}," | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " {server_name_indication, \"$domain\"}]}," | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " {auth_backends, [rabbit_auth_backend_http]}]}," | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " {rabbitmq_auth_backend_http," | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " [{http_method, post}," | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " {user_path, \"https://$domain/iotJumpWay/AMQP/API/User\"}," | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " {vhost_path, \"https://$domain/iotJumpWay/AMQP/API/Vhost\"}," | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " {resource_path, \"https://$domain/iotJumpWay/AMQP/API/Resource\"}," | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " {topic_path, \"https://$domain/iotJumpWay/AMQP/API/Topic\"}" | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " ]}," | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " {rabbitmq_management," | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " [" | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " {listener, [{port, 15671}," | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " {ssl, true}," | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " {ssl_opts, [{cacertfile, \"/fserver/certs/fullchain.pem\"}," | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " {certfile, \"/fserver/certs/cert.pem\"}," | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " {keyfile, \"/fserver/certs/privkey.pem\"}," | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " {verify, verify_peer}," | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " {fail_if_no_peer_cert, false}," | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " {client_renegotiation, false}," | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " {secure_renegotiate, true}," | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " {honor_ecc_order, true}," | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " {honor_cipher_order, true}," | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " {versions,['tlsv1.1', 'tlsv1.2']}," | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " {ciphers, [\"ECDHE-ECDSA-AES256-GCM-SHA384\"," | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " \"ECDHE-RSA-AES256-GCM-SHA384\"," | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " \"ECDH-ECDSA-AES256-GCM-SHA384\"," | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " \"ECDH-RSA-AES256-GCM-SHA384\"," | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " \"ECDH-RSA-AES256-SHA384\"," | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " \"DHE-RSA-AES256-GCM-SHA384\"" | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " ]}" | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " ]}" | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " ]}" | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo " ]}" | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ echo "]." | sudo tee -a /etc/rabbitmq/rabbitmq.config
+ sudo systemctl restart rabbitmq-server
+ echo "- Installed iotJumpWay AMQP Broker!";
+ exit 0
+else
+ echo "- iotJumpWay AMQP Broker installation terminated!";
+ exit 1
+fi
```
-**Shell Script** [iotJumpWay.sh](../Scripts/Installation/Shell/iotJumpWay.sh "iotJumpWay.sh")
+**Shell Script** [AmqpBroker.sh](../Scripts/Installation/Shell/AmqpBroker.sh "AmqpBroker.sh")
-#### iotJumpWay Location and Applications
+### iotJumpWay Location and Applications
Now setup the local iotJumpWay location and application. To run this installation file use the following command:
```
-bash Scripts/Installation/Shell/iotJumpWayLocation.sh
+bash Scripts/Installation/Shell/iotJumpWay.sh
```
The contents of the above file as follows:
```
@@ -1339,25 +1220,47 @@ if [ "$cmsg" = "Y" -o "$cmsg" = "y" ]; then
sudo apt install apache2-utils
sudo mkdir -p /etc/nginx/security
sudo touch /etc/nginx/security/htpasswd
- sudo chmod -R 777 /etc/nginx/security
+ sudo chown -R $USER:$USER /etc/nginx/security
read -p "! Enter your default location name. This field represents the physical location that your server is installed in, ie: Home, Office, Hospital, Center etc: " location
read -p "! Enter your full domain name including https://: " domain
read -p "! Enter your HIAS Blockchain user address: " haddress
read -p "! Enter your HIAS Blockchain user pass: " hpass
+ read -p "! Enter your HIAS iotJumpWay MQTT Blockchain user address: " iaddress
+ read -p "! Enter your HIAS iotJumpWay AMQP Blockchain user address: " aaddress
read -p "! Enter the IP of your HIAS Server: " ip
read -p "! Enter the MAC address of your HIAS Server: " mac
- read -p "! Enter your HIAS iotJumpWay Blockchain user address: " iaddress
- php Scripts/Installation/PHP/Location.php "$location" "HIAS" "$haddress" "$hpass" "$ip" "$mac" "iotJumpWay" "$iaddress" "$domain"
- read -p "! Enter your iotJumpWay Application Location ID (1): " lid
- read -p "! Enter your iotJumpWay Application Application ID: " aid
- read -p "! Enter your iotJumpWay Application Application name: " an
- read -p "! Enter your iotJumpWay Application Application MQTT username: " un
- read -p "! Enter your iotJumpWay Application Application MQTT password: " pw
- sudo sed -i "s/\"lid\":.*/\"lid\": \"$lid\",/g" "confs.json"
- sudo sed -i "s/\"paid\":.*/\"paid\": \"$aid\",/g" "confs.json"
- sudo sed -i "s/\"pan\":.*/\"pan\": \"$an\",/g" "confs.json"
- sudo sed -i "s/\"pun\":.*/\"pun\": \"$un\",/g" "confs.json"
- sudo sed -i "s/\"ppw\":.*/\"ppw\": \"${pw//&/\\&}\",/g" "confs.json"
+ php Scripts/Installation/PHP/Location.php "$location" "Context Broker" "$haddress" "$hpass" "$ip" "$mac" "MQTT IoT Agent" "$iaddress" "AMQP IoT Agent" "$aaddress" "$domain"
+ read -p "! Enter your HIAS Location Identifier (1): " lid
+ read -p "! Enter your Context Broker Application Public Key: " haid
+ read -p "! Enter your Context Broker Application name: " han
+ read -p "! Enter your Context Broker Application MQTT username: " hun
+ read -p "! Enter your Context Broker Application MQTT password: " hpw
+ read -p "! Enter your iotJumpWay MQTT Application Public Key: " iaid
+ read -p "! Enter your iotJumpWay MQTT Application Private Key: " iapk
+ read -p "! Enter your iotJumpWay MQTT Application name: " ian
+ read -p "! Enter your iotJumpWay MQTT Application MQTT username: " iun
+ read -p "! Enter your iotJumpWay MQTT Application MQTT password: " ipw
+ read -p "! Enter your iotJumpWay AMQP Application Public Key: " aaid
+ read -p "! Enter your iotJumpWay AMQP Application MQTT username: " aun
+ read -p "! Enter your iotJumpWay AMQP Application MQTT password: " apw
+ hpw=$(printf '%s\n' "$hpw" | sed -e 's/[\/&]/\\&/g');
+ ipw=$(printf '%s\n' "$ipw" | sed -e 's/[\/&]/\\&/g');
+ apw=$(printf '%s\n' "$apw" | sed -e 's/[\/&]/\\&/g');
+ iapk=$(printf '%s\n' "$iapk" | sed -e 's/[\/&]/\\&/g');
+ sudo sed -i -- "s/YourIotJumpWayLocationID/$lid/g" "confs.json"
+ sudo sed -i -- "s/YourIotJumpWayApplicationIdentifier/$iaid/g" "confs.json"
+ sudo sed -i -- "s/YourIotJumpWayApplicationAuthKey/$iapk/g" "confs.json"
+ sudo sed -i -- "s/YourContextBrokerApplicationID/$haid/g" "confs.json"
+ sudo sed -i -- "s/YourContextBrokerApplicationName/$han/g" "confs.json"
+ sudo sed -i -- "s/YourContextBrokerApplicationMqttUsername/$hun/g" "confs.json"
+ sudo sed -i -- "s/YourContextBrokerApplicationMqttPassword/$hpw/g" "confs.json"
+ sudo sed -i -- "s/YourIotJumpWayApplicationID/$iaid/g" "confs.json"
+ sudo sed -i -- "s/YourIotJumpWayApplicationName/$ian/g" "confs.json"
+ sudo sed -i -- "s/YourIotJumpWayApplicationUsername/$iun/g" "confs.json"
+ sudo sed -i -- "s/YourIotJumpWayApplicationPassword/$ipw/g" "confs.json"
+ sudo sed -i -- "s/YourAmqpApplicationIdentifier/$aaid/g" "confs.json"
+ sudo sed -i -- "s/YourAmqpApplicationUsername/$aun/g" "confs.json"
+ sudo sed -i -- "s/YourAmqpApplicationPasword/$apw/g" "confs.json"
echo "- Installed iotJumpWay location and applications!";
exit 0
else
@@ -1365,38 +1268,9 @@ else
exit 1
fi
```
-You should see similar to the following:
-```
-! Location, Laptop has been created with ID 1!
- HIAS Blockchain deposit ok!
-HIAS Blockchain register application complete! You were rewarded for this action! Your balance is now: 100000000000000000000000000000000000000000000000000000001739 HIAS Ether!
- HIAS Blockchain deposit ok!
-HIAS Blockchain register authorized complete! You were rewarded for this action! Your balance is now: 100000000000000000000000000000000000000000000000000000001739 HIAS Ether!
-!! NOTE THESE CREDENTIALS AND KEEP THEM IN A SAFE PLACE !!
-! Application, HIAS, has been created with ID 1!
-!! Your application public key is: ########-####-####-####-############ !
-!! Your application private key is: ############################
-!! Your application MQTT username is: ########-####-####-####-########
-!! Your application MQTT password is: ################
- HIAS Blockchain deposit ok!
-HIAS Blockchain register application complete! You were rewarded for this action! Your balance is now: 100000000000000000000000000000000000000000000000000000001741 HIAS Ether!
- HIAS Blockchain deposit ok!
-HIAS Blockchain register authorized complete! You were rewarded for this action! Your balance is now: 100000000000000000000000000000000000000000000000000000001741 HIAS Ether!
-!! NOTE THESE CREDENTIALS AND KEEP THEM IN A SAFE PLACE !!
-! Application, iotJumpWay, has been created with ID 2!
-!! Your application public key is: ########-####-####-####-############ !
-!! Your application private key is: ############################
-!! Your application MQTT username is: ########-####-####-####-############
-!! Your application MQTT password is: ################
-! Enter your iotJumpWay Application Location ID (1): 1
-! Enter your iotJumpWay Application Application ID: 2
-! Enter your iotJumpWay Application Application name: iotJumpWay
-! Enter your iotJumpWay Application Application MQTT username: ########-####-####-####-############
-! Enter your iotJumpWay Application Application MQTT password: ################
-- Installed iotJumpWay location and applications!
-```
-
-**Shell Script** [iotJumpWayLocation.sh](../Scripts/Installation/Shell/iotJumpWayLocation.sh "iotJumpWayLocation.sh")
+You will be provided with your credentials for your core iotJumpWay applications. You must keep these credentials safe.
+
+**Shell Script** [iotJumpWay.sh](../Scripts/Installation/Shell/iotJumpWay.sh "iotJumpWay.sh")
### Create Admin User
Now you should create your admin user that you will use to access the network, UI and the network TassAI streams. The following command executes a PHP script to add your chosen username as an admin user in the system.
@@ -1425,42 +1299,52 @@ if [ "$cmsg" = "Y" -o "$cmsg" = "y" ]; then
read -p "! Enter your desired username (No spaces or special characters): " username
read -p "! Enter your personal HIAS Blockchain account address: " paddress
read -p "! Enter your personal HIAS Blockchain account password: " ppass
+ read -p "! Enter your HIAS Location Identfier: " identifier
read -p "! Enter local IP address of the device that the application will run on (IE: 192.168.1.98): " ip
read -p "! Enter MAC address of the device that the application will run on: " mac
sudo touch /etc/nginx/security/patients
sudo touch /etc/nginx/security/beds
- sudo chmod -R 777 /etc/nginx/security
- php Scripts/Installation/PHP/Admin.php "$name" "$email" "$username" "$paddress" "$ppass" "$ip" "$mac" "$domain" "$haddress" "$hpass"
- read -p "! Enter your new HIAS username: " username
- read -p "! Enter your new HIAS password: " password
- sudo sed -i 's/\"user\":.*/\"user\": \"'$username'\",/g' "confs.json"
- sudo sed -i "s/\"pass\":.*/\"pass\": \"${password//&/\\&}\",/g" "confs.json"
+ sudo chown -R $USER:$USER /etc/nginx/security
+ php Scripts/Installation/PHP/Admin.php "$name" "$email" "$username" "$paddress" "$ppass" "$ip" "$mac" "$domain" "$haddress" "$hpass" "$identifier"
+ echo "Your account has been set up!";
else
echo "- HIAS Server admin user creation terminated";
exit
fi
```
-You should see something similar to the following:
-```
-!! NOTE THESE CREDENTIALS AND KEEP THEM IN A SAFE PLACE !!
-! Admin user, AdamMiltonBarker, has been created with ID 1 !!
-!! Your username is: ################## !!
-!! Your password is: ################## !!
-!! THESE CREDENTIALS ARE ALSO USED FOR THE TASS STREAM AUTHENTICATION POP UP YOU WILL FACE WHEN YOU FIRST LOGIN !!
- HIAS Blockchain deposit ok!
-Register user completed! You were rewarded for this action! Your balance is now: 100000000000000000000000000000000000000000000000000000001803 HIAS Ether!
- HIAS Blockchain deposit ok!
-iotJumpWay register authorized You were rewarded for this action! Your balance is now: 100000000000000000000000000000000000000000000000000000001803 HIAS Ether!
-!! NOTE THESE CREDENTIALS AND KEEP THEM IN A SAFE PLACE !!
-! Application, Adam Milton-Barker, has been created with ID 3!
-!! Your application public key is: ##########-####-####-####-############!
-!! Your application private key is: ########################
-!! Your application MQTT username is: ############-####-####-####-########
-!! Your application MQTT password is: ################
-```
+You will be provided with your credentials. You must keep these credentials safe.
**Shell Script** [Admin.sh](../Scripts/Installation/Shell/Admin.sh "Admin.sh")
+
+### Finalize Server Settings
+Now you need to finalize your server settings, to do this you need your server URL, IE: https://www.YourDomain.com, you will need to register free [Google Maps](https://developers.google.com/maps/documentation/javascript/get-api-key "Google Maps") and [Google Recaptcha](https://www.google.com/recaptcha "Google Recaptcha") site/secret keys, and you will need to provide your default latitude and longitude settings. The latitude and longitude settings will be used for the default coordinates for Google Maps in HIAS, they must be correct.
+
+To run this installation file use the following command:
+```
+bash Scripts/Installation/Shell/Finalize.sh
+```
+The contents of the above file as follows:
+```
+read -p "? This script will finish the configuration of your HIAS Server. You will need your server URL, and your Google Recapthca site & secret keys. Are you ready (y/n)? " cmsg
+
+if [ "$cmsg" = "Y" -o "$cmsg" = "y" ]; then
+ read -p "! Enter your server URL. IE: https://www.YourDomain.com. This should match the domain used in the NGINX configuration: " domain
+ read -p "! Enter your site Recaptcha key: " pub
+ read -p "! Enter your secret Recaptcha key: " prv
+ read -p "! Enter your Google Maps key: " gmaps
+ read -p "! Enter your default latitude: " lat
+ read -p "! Enter your default longitude: " lng
+ read -p "! Enter the application ID for your iotJumpWay application: " app
+ php Scripts/Installation/PHP/Finalize.php "$domain" "$pub" "$prv" "$gmaps" "$lat" "$lng" "$app"
+else
+ echo "- Server database finalization terminated";
+ exit
+fi
+```
+
+**Shell Script** [Finalize.sh](../Scripts/Installation/Shell/Finalize.sh "Finalize.sh")
+
### TassAI (Computer Vision)
We will use the [HIAS TassAI](https://github.com/LeukemiaAiResearch/TassAI "HIAS TassAI") Facial Recognition Security System API to provide the ability for HIAS device and applications to carry out remote facial recognition requests using HTTP requests.
@@ -1486,21 +1370,29 @@ if [ "$cmsg" = "Y" -o "$cmsg" = "y" ]; then
read -p "! Enter your HIAS Blockchain user pass: " hpass
read -p "! Enter your HIAS public key: " user
read -p "! Enter your HIAS private key: " pass
+ read -p "! Enter your HIAS iotJumpWay Location ID: " lid
+ read -p "! Enter your HIAS iotJumpWay Location Entity: " lie
read -p "! Enter your zone name (No spaces or special characters). This field represents the zone that this device is installed in, ie: Office, Study, Lounge, Kitchen etc: " zone
read -p "! Enter local IP address of the HIAS Server device (IE: 192.168.1.98): " ip
read -p "! Enter MAC address of HIAS Server device: " mac
- php Scripts/Installation/PHP/TassAI.php "$zone" "$ip" "$mac" "$domain" "$user" "$pass" "$haddress" "$hpass"
+ php Scripts/Installation/PHP/TassAI.php "$lid" "$lie" "$zone" "$ip" "$mac" "$domain" "$user" "$pass" "$haddress" "$hpass"
read -p "! Enter your TassAI Device Zone ID: " zid
read -p "! Enter your TassAI Device ID: " did
- read -p "! Enter your TassAI Device name: " dn
- read -p "! Enter your TassAI Device MQTT username: " gun
- read -p "! Enter your TassAI Device MQTT password: " gpw
- sudo sed -i "s/\"zid\":.*/\"zid\": \"$zid\",/g" "confs.json"
- sudo sed -i "s/\"did\":.*/\"did\": \"$did\",/g" "confs.json"
- sudo sed -i "s/\"dn\":.*/\"dn\": \"$dn\",/g" "confs.json"
- sudo sed -i "s/\"gun\":.*/\"gun\": \"$gun\",/g" "confs.json"
- sudo sed -i "s/\"gpw\":.*/\"gpw\": \"${gpw//&/\\&}\",/g" "confs.json"
- sudo sed -i "s/YourCameraApiIP/$ip/g" "confs.json"
+ read -p "! Enter your TassAI Device MQTT username: " un
+ read -p "! Enter your TassAI Device MQTT password: " pw
+ sudo sed -i -- "s/YourTassAIZoneID/$zid/g" "confs.json"
+ sudo sed -i -- "s/YourTassAIDeviceID/$did/g" "confs.json"
+ sudo sed -i -- "s/YourTassAIMqttUsername/$un/g" "confs.json"
+ sudo sed -i -- "s/YourTassAIMqttPassword/$pw/g" "confs.json"
+ cd ~/
+ tar -xvzf l_openvino_toolkit_p_2020.3.194.tgz
+ cd l_openvino_toolkit_p_2020.3.194
+ sudo ./install.sh
+ cd /opt/intel/openvino/deployment_tools/model_optimizer/install_prerequisites
+ sudo ./install_prerequisites.sh
+ echo "# OpenVINO" | tee -a ~/.bashrc
+ echo "source /opt/intel/openvino/bin/setupvars.sh" | tee -a ~/.bashrc
+ source ~/.bashrc
wget https://download.01.org/opencv/2020/openvinotoolkit/2020.3/open_model_zoo/models_bin/1/face-detection-retail-0004/FP16/face-detection-retail-0004.bin -P /fserver/models/TassAI/
wget https://download.01.org/opencv/2020/openvinotoolkit/2020.3/open_model_zoo/models_bin/1/face-detection-retail-0004/FP16/face-detection-retail-0004.xml -P /fserver/models/TassAI/
wget https://download.01.org/opencv/2020/openvinotoolkit/2020.3/open_model_zoo/models_bin/1/face-reidentification-retail-0095/FP16/face-reidentification-retail-0095.bin -P /fserver/models/TassAI/
@@ -1514,55 +1406,10 @@ else
exit 1
fi
```
-You should see similar to the following:
-
-```
-! Zone, Remote, has been created with ID 1 !
-!! NOTE THESE CREDENTIALS AND KEEP THEM IN A SAFE PLACE !!
-! Device, Server Security API, has been created with ID 1 !
-!! Your device public key is: ########-####-####-####-######## !!
-!! Your device private key is: #################### !!
-!! Your device MQTT username is: ########-####-####-####-######## !!
-!! Your device MQTT password is: ############ !!
-! Enter your TassAI Device Zone ID: 1
-! Enter your TassAI Device ID: 1
-! Enter your TassAI Device name: Server Security API
-! Enter your TassAI Device MQTT username: ########-####-####-####-########
-! Enter your TassAI Device MQTT password: ############
-- TassAI iotJumpWay device installation complete!
-```
+You will be provided your credentials for this device, you should keep them safe.
**Shell Script** [TassAI.sh](../Scripts/Installation/Shell/TassAI.sh "TassAI.sh")
-### Install COVID-19 Data Analysis System
-Now you will install your COVID-19 Data Analysis System. This system collects data from the COVID-19 API, an free API that provides statistical data for COVID-19 cases, deaths and recoveries. Data is sourced from Johns Hopkins CSSE.
-
-First of all you need to download the full dataset which contains all the COVID-19 data since data started to be recorded.
-
-To run this installation file use the following command:
-```
-sh Scripts/Installation/Shell/COVID19.sh
-```
-The contents of the above file as follows:
-```
-read -p "? This script will install the COVID-19 data analysis system on your HIAS Server. Are you ready (y/n)? " cmsg
-
-if [ "$cmsg" = "Y" -o "$cmsg" = "y" ]; then
- echo "Installing COVID-19 data analysis system"
- sudo chmod -R 777 /fserver/var/www/html/Data-Analysis/COVID-19/Data/
- php Scripts/Installation/PHP/COVID19.php
- echo "Installed COVID-19 data analysis system"
- exit 0
-else
- echo "- COVID-19 data analysis system installation terminated";
- exit 1
-fi
-```
-
-You can update the system with the latest data by going to **Data Analysis -> COVID-19 -> Dashboard** and clicking on the refresh button. This will pull all data since the last time you refreshed.
-
-**Shell Script** [COVID19.sh](../Scripts/Installation/Shell/COVID19.sh "COVID19.sh")
-
### HIAS Server Services
Now you will set up services that will automatically run the iotJumpWay listener, the smart contract replenishment program, and the facial recognition API.
@@ -1578,22 +1425,48 @@ read -p "? This script will install the system services on your HIAS Server. Are
if [ "$cmsg" = "Y" -o "$cmsg" = "y" ]; then
echo "- Installing Services"
- pip3 install psutil
- read -p "! Enter the username you use to login to your device: " username
- sudo touch /lib/systemd/system/iotJumpWay.service
- chmod u+x Scripts/System/iotJumpWay.sh
- echo "[Unit]" | sudo tee -a /lib/systemd/system/iotJumpWay.service
- echo "Description=iotJumpWay Service" | sudo tee -a /lib/systemd/system/iotJumpWay.service
- echo "After=multi-user.target" | sudo tee -a /lib/systemd/system/iotJumpWay.service
- echo "" | sudo tee -a /lib/systemd/system/iotJumpWay.service
- echo "[Service]" | sudo tee -a /lib/systemd/system/iotJumpWay.service
- echo "User=$username" | sudo tee -a /lib/systemd/system/iotJumpWay.service
- echo "Type=simple" | sudo tee -a /lib/systemd/system/iotJumpWay.service
- echo "ExecStart=/home/$username/HIAS/Scripts/System/iotJumpWay.sh" | sudo tee -a /lib/systemd/system/iotJumpWay.service
- echo "" | sudo tee -a /lib/systemd/system/iotJumpWay.service
- echo "[Install]" | sudo tee -a /lib/systemd/system/iotJumpWay.service
- echo "WantedBy=multi-user.target" | sudo tee -a /lib/systemd/system/iotJumpWay.service
- sudo sed -i -- "s#YourUser#$username#g" Scripts/System/Security.sh
+ sudo touch /lib/systemd/system/ContextBroker.service
+ echo "[Unit]" | sudo tee -a /lib/systemd/system/ContextBroker.service
+ echo "Description=iotJumpWay Context Broker Service" | sudo tee -a /lib/systemd/system/ContextBroker.service
+ echo "After=multi-user.target" | sudo tee -a /lib/systemd/system/ContextBroker.service
+ echo "" | sudo tee -a /lib/systemd/system/ContextBroker.service
+ echo "[Service]" | sudo tee -a /lib/systemd/system/ContextBroker.service
+ echo "User=$USER" | sudo tee -a /lib/systemd/system/ContextBroker.service
+ echo "Type=simple" | sudo tee -a /lib/systemd/system/ContextBroker.service
+ echo "ExecStart=/usr/bin/python3 /home/$USER/HIAS/Context/Broker.py" | sudo tee -a /lib/systemd/system/ContextBroker.service
+ echo "" | sudo tee -a /lib/systemd/system/ContextBroker.service
+ echo "[Install]" | sudo tee -a /lib/systemd/system/ContextBroker.service
+ echo "WantedBy=multi-user.target" | sudo tee -a /lib/systemd/system/ContextBroker.service
+ echo "" | sudo tee -a /lib/systemd/system/ContextBroker.service
+
+ sudo touch /lib/systemd/system/MQTT.service
+ echo "[Unit]" | sudo tee -a /lib/systemd/system/MQTT.service
+ echo "Description=iotJumpWay MQTT Service" | sudo tee -a /lib/systemd/system/MQTT.service
+ echo "After=multi-user.target" | sudo tee -a /lib/systemd/system/MQTT.service
+ echo "" | sudo tee -a /lib/systemd/system/MQTT.service
+ echo "[Service]" | sudo tee -a /lib/systemd/system/MQTT.service
+ echo "User=$USER" | sudo tee -a /lib/systemd/system/MQTT.service
+ echo "Type=simple" | sudo tee -a /lib/systemd/system/MQTT.service
+ echo "ExecStart=/usr/bin/python3 /home/$USER/HIAS/Agents/MQTT.py" | sudo tee -a /lib/systemd/system/MQTT.service
+ echo "" | sudo tee -a /lib/systemd/system/MQTT.service
+ echo "[Install]" | sudo tee -a /lib/systemd/system/MQTT.service
+ echo "WantedBy=multi-user.target" | sudo tee -a /lib/systemd/system/MQTT.service
+ echo "" | sudo tee -a /lib/systemd/system/MQTT.service
+
+ sudo touch /lib/systemd/system/AMQP.service
+ echo "[Unit]" | sudo tee -a /lib/systemd/system/AMQP.service
+ echo "Description=iotJumpWay AMQP Service" | sudo tee -a /lib/systemd/system/AMQP.service
+ echo "After=multi-user.target" | sudo tee -a /lib/systemd/system/AMQP.service
+ echo "" | sudo tee -a /lib/systemd/system/AMQP.service
+ echo "[Service]" | sudo tee -a /lib/systemd/system/AMQP.service
+ echo "User=$USER" | sudo tee -a /lib/systemd/system/AMQP.service
+ echo "Type=simple" | sudo tee -a /lib/systemd/system/AMQP.service
+ echo "ExecStart=/usr/bin/python3 /home/$USER/HIAS/Agents/AMQP.py" | sudo tee -a /lib/systemd/system/AMQP.service
+ echo "" | sudo tee -a /lib/systemd/system/AMQP.service
+ echo "[Install]" | sudo tee -a /lib/systemd/system/AMQP.service
+ echo "WantedBy=multi-user.target" | sudo tee -a /lib/systemd/system/AMQP.service
+ echo "" | sudo tee -a /lib/systemd/system/AMQP.service
+
chmod u+x Scripts/System/Security.sh
sudo touch /lib/systemd/system/Security.service
echo "[Unit]" | sudo tee -a /lib/systemd/system/Security.service
@@ -1601,31 +1474,39 @@ if [ "$cmsg" = "Y" -o "$cmsg" = "y" ]; then
echo "After=multi-user.target" | sudo tee -a /lib/systemd/system/Security.service
echo "" | sudo tee -a /lib/systemd/system/Security.service
echo "[Service]" | sudo tee -a /lib/systemd/system/Security.service
- echo "User=$username" | sudo tee -a /lib/systemd/system/Security.service
+ echo "User=$USER" | sudo tee -a /lib/systemd/system/Security.service
echo "Type=simple" | sudo tee -a /lib/systemd/system/Security.service
- echo "ExecStart=/home/$username/HIAS/Scripts/System/Security.sh" | sudo tee -a /lib/systemd/system/Security.service
+ echo "ExecStart=/home/$USER/HIAS/Scripts/System/Security.sh" | sudo tee -a /lib/systemd/system/Security.service
echo "" | sudo tee -a /lib/systemd/system/Security.service
echo "[Install]" | sudo tee -a /lib/systemd/system/Security.service
echo "WantedBy=multi-user.target" | sudo tee -a /lib/systemd/system/Security.service
+ echo "" | sudo tee -a /lib/systemd/system/Security.service
+
sudo touch /lib/systemd/system/Replenish.service
- chmod u+x Scripts/System/Replenish.sh
echo "[Unit]" | sudo tee -a /lib/systemd/system/Replenish.service
echo "Description=Replenish Service" | sudo tee -a /lib/systemd/system/Replenish.service
echo "After=multi-user.target" | sudo tee -a /lib/systemd/system/Replenish.service
echo "" | sudo tee -a /lib/systemd/system/Replenish.service
echo "[Service]" | sudo tee -a /lib/systemd/system/Replenish.service
- echo "User=$username" | sudo tee -a /lib/systemd/system/Replenish.service
+ echo "User=$USER" | sudo tee -a /lib/systemd/system/Replenish.service
echo "Type=simple" | sudo tee -a /lib/systemd/system/Replenish.service
- echo "ExecStart=/home/$username/HIAS/Scripts/System/Replenish.sh" | sudo tee -a /lib/systemd/system/Replenish.service
+ echo "ExecStart=/usr/bin/python3 /home/$USER/HIAS/Services/Replenish.py" | sudo tee -a /lib/systemd/system/Replenish.service
echo "" | sudo tee -a /lib/systemd/system/Replenish.service
echo "[Install]" | sudo tee -a /lib/systemd/system/Replenish.service
echo "WantedBy=multi-user.target" | sudo tee -a /lib/systemd/system/Replenish.service
- sudo systemctl enable iotJumpWay.service
- sudo systemctl start iotJumpWay.service
+ echo "" | sudo tee -a /lib/systemd/system/Replenish.service
+
+ sudo systemctl enable ContextBroker.service
+ sudo systemctl start ContextBroker.service
+ sudo systemctl enable MQTT.service
+ sudo systemctl start MQTT.service
+ sudo systemctl enable AMQP.service
+ sudo systemctl start AMQP.service
sudo systemctl enable Security.service
sudo systemctl start Security.service
sudo systemctl enable Replenish.service
sudo systemctl start Replenish.service
+
echo "- Installed services!";
exit 0
else
@@ -1633,16 +1514,25 @@ else
exit 1
fi
```
-
**Shell Script** [Services.sh](../Scripts/Installation/Shell/Services.sh "Services.sh")
Your services will now load every time your server boots up. To manage the services you can use:
```
-sudo systemctl restart iotJumpWay.service
-sudo systemctl start iotJumpWay.service
-sudo systemctl stop iotJumpWay.service
-sudo systemctl status iotJumpWay.service
+sudo systemctl restart ContextBroker.service
+sudo systemctl start ContextBroker.service
+sudo systemctl stop ContextBroker.service
+sudo systemctl status ContextBroker.service
+
+sudo systemctl restart MQTT.service
+sudo systemctl start MQTT.service
+sudo systemctl stop MQTT.service
+sudo systemctl status MQTT.service
+
+sudo systemctl restart AMQP.service
+sudo systemctl start AMQP.service
+sudo systemctl stop AMQP.service
+sudo systemctl status AMQP.service
sudo systemctl restart Security.service
sudo systemctl start Security.service
@@ -1655,40 +1545,125 @@ sudo systemctl stop Replenish.service
sudo systemctl status Replenish.service
```
-### Finalize Server Settings
-Now you need to finalize your server settings, to do this you need your server URL, IE: https://www.YourDomain.com, you will need to register free [Google Maps](https://developers.google.com/maps/documentation/javascript/get-api-key "Google Maps") and [Google Recaptcha](https://www.google.com/recaptcha "Google Recaptcha") site/secret keys, and you will need to provide your default latitude and longitude settings. The latitude and longitude settings will be used for the default coordinates for Google Maps in HIAS, they must be correct.
+### File Server
+We will use Samba to create a private network file share.
To run this installation file use the following command:
```
-bash Scripts/Installation/Shell/Finalize.sh
+sh Scripts/Installation/Shell/Samba.sh
```
The contents of the above file as follows:
```
-read -p "? This script will finish the configuration of your HIAS Server. You will need your server URL, and your Google Recapthca site & secret keys. Are you ready (y/n)? " cmsg
+read -p "? This script will install Samba on your HIAS Server. Are you ready (y/n)? " cmsg
if [ "$cmsg" = "Y" -o "$cmsg" = "y" ]; then
- read -p "! Enter your server URL. IE: https://www.YourDomain.com. This should match the domain used in the NGINX configuration: " domain
- read -p "! Enter your site Recaptcha key: " pub
- read -p "! Enter your secret Recaptcha key: " prv
- read -p "! Enter your Google Maps key: " gmaps
- read -p "! Enter your default latitude: " lat
- read -p "! Enter your default longitude: " lng
- read -p "! Enter the application ID for your iotJumpWay application: " app
- php Scripts/Installation/PHP/Finalize.php "$domain" "$pub" "$prv" "$gmaps" "$lat" "$lng" "$app"
+ echo "Installing Samba"
+ sudo apt install samba
+ sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.backup
+ sudo sed -i -- "s/; bind interfaces only = yes/bind interfaces only = yes/g" /etc/samba/smb.conf
+ testparm
+ sudo systemctl restart smbd
+ sudo systemctl status smbd
+ echo "Creating Samba directory"
+ sudo mkdir -p /fserver/samba
+ sudo chgrp sambashare /fserver/samba
+ echo "Creating Samba admins group & directory"
+ sudo groupadd sambashare
+ sudo groupadd smbadmins
+ sudo mkdir -p /fserver/samba/smbadmins
+ sudo chgrp smbadmins /fserver/samba/smbadmins
+ sudo chmod -R 770 /fserver/samba/smbadmins
+ echo "Creating Samba admin user"
+ read -p "! Enter a new Samba username for your admin account: " sauser
+ echo "$sauser"
+ sudo useradd -M -d /fserver/samba/users -s /usr/sbin/nologin -G sambashare,smbadmins "$sauser"
+ sudo smbpasswd -a "$sauser"
+ sudo smbpasswd -e "$sauser"
+ sudo mkdir /fserver/samba/users
+ sudo chown "$sauser":sambashare /fserver/samba/users
+ sudo chmod 2770 /fserver/samba/users
+ echo "Creating Samba user"
+ read -p "! Enter a new Samba username for yourself: " suser
+ sudo useradd -M -d /fserver/samba/"$suser" -s /usr/sbin/nologin -G sambashare "$suser"
+ sudo mkdir -p /fserver/samba/"$suser"
+ sudo chown "$suser":sambashare /fserver/samba/"$suser"
+ sudo chmod 2770 /fserver/samba/"$suser"
+ sudo smbpasswd -a "$suser"
+ sudo smbpasswd -e "$suser"
+ echo "Finalizing Samba admin settings"
+ echo "" | sudo tee -a /etc/samba/smb.conf
+ echo "[users]" | sudo tee -a /etc/samba/smb.conf
+ echo " path = /fserver/samba/users" | sudo tee -a /etc/samba/smb.conf
+ echo " browseable = yes" | sudo tee -a /etc/samba/smb.conf
+ echo " read only = no" | sudo tee -a /etc/samba/smb.conf
+ echo " force create mode = 0660" | sudo tee -a /etc/samba/smb.conf
+ echo " force directory mode = 2770" | sudo tee -a /etc/samba/smb.conf
+ echo " valid users = @sambashare @smbadmins" | sudo tee -a /etc/samba/smb.conf
+ echo "" | sudo tee -a /etc/samba/smb.conf
+ echo "[smbadmins]" | sudo tee -a /etc/samba/smb.conf
+ echo " path = /fserver/samba/smbadmins" | sudo tee -a /etc/samba/smb.conf
+ echo " browseable = no" | sudo tee -a /etc/samba/smb.conf
+ echo " read only = no" | sudo tee -a /etc/samba/smb.conf
+ echo " force create mode = 0660" | sudo tee -a /etc/samba/smb.conf
+ echo " force directory mode = 2770" | sudo tee -a /etc/samba/smb.conf
+ echo " valid users = @smbadmins" | sudo tee -a /etc/samba/smb.conf
+ echo "Finalizing Samba user settings"
+ echo "" | sudo tee -a /etc/samba/smb.conf
+ echo "[$suser]" | sudo tee -a /etc/samba/smb.conf
+ echo " path = /fserver/samba/$suser" | sudo tee -a /etc/samba/smb.conf
+ echo " browseable = no" | sudo tee -a /etc/samba/smb.conf
+ echo " read only = no" | sudo tee -a /etc/samba/smb.conf
+ echo " force create mode = 0660" | sudo tee -a /etc/samba/smb.conf
+ echo " force directory mode = 2770" | sudo tee -a /etc/samba/smb.conf
+ echo " valid users = $suser @smbadmins" | sudo tee -a /etc/samba/smb.conf
+ echo "Reloading Samba and checking status"
+ sudo systemctl restart smbd
+ sudo systemctl status smbd
+ echo "Installed Samba"
+ exit 0
else
- echo "- Server database finalization terminated";
- exit
+ echo "- Samba installation terminated";
+ exit 1
fi
```
-**Shell Script** [Finalize.sh](../Scripts/Installation/Shell/Finalize.sh "Finalize.sh")
+**Shell Script** [Samba.sh](../Scripts/Installation/Shell/Samba.sh "Samba.sh")
+
+### Install COVID-19 Data Analysis System
+Now you will install your COVID-19 Data Analysis System. This system collects data from the COVID-19 API, an free API that provides statistical data for COVID-19 cases, deaths and recoveries. Data is sourced from Johns Hopkins CSSE.
+
+First of all you need to download the full dataset which contains all the COVID-19 data since data started to be recorded.
+
+To run this installation file use the following command:
+```
+sh Scripts/Installation/Shell/COVID19.sh
+```
+The contents of the above file as follows:
+```
+read -p "? This script will install the COVID-19 data analysis system on your HIAS Server. Are you ready (y/n)? " cmsg
+
+if [ "$cmsg" = "Y" -o "$cmsg" = "y" ]; then
+ echo "Installing COVID-19 data analysis system"
+ sudo chmod -R 777 /fserver/var/www/html/Data-Analysis/COVID-19/Data/
+ php Scripts/Installation/PHP/COVID19.php
+ echo "Installed COVID-19 data analysis system"
+ exit 0
+else
+ echo "- COVID-19 data analysis system installation terminated";
+ exit 1
+fi
+```
+
+You can update the system with the latest data by going to **Data Analysis -> COVID-19 -> Dashboard** and clicking on the refresh button. This will pull all data since the last time you refreshed.
+
+**Shell Script** [COVID19.sh](../Scripts/Installation/Shell/COVID19.sh "COVID19.sh")
# Login To Your Server UI
![Login To Your Server UI](../Media/Images/UI.png)
-Congratulations, you have the basics of the server installed!! Visit your domain name and you should see the above page. You can then login with your username and password you created earlier.
+Congratulations, you have the basics of the server installed!! Ensure that your Blockchain and the Context Broker & MQTT IoT Agent services are running, then you can visit your domain name and you should see the above page. You can then login with your username and password you created earlier.
![HIAS Dashboard](../Media/Images/dashboard.png)
diff --git a/Media/Images/HDSI-AI-Model-Schemas.jpg b/Media/Images/HDSI-AI-Model-Schemas.jpg
new file mode 100644
index 0000000..b59038b
Binary files /dev/null and b/Media/Images/HDSI-AI-Model-Schemas.jpg differ
diff --git a/Media/Images/HDSI-Context-Broker.jpg b/Media/Images/HDSI-Context-Broker.jpg
new file mode 100644
index 0000000..e88354d
Binary files /dev/null and b/Media/Images/HDSI-Context-Broker.jpg differ
diff --git a/Media/Images/HDSI-IoT-Agents.jpg b/Media/Images/HDSI-IoT-Agents.jpg
new file mode 100644
index 0000000..0c3e86a
Binary files /dev/null and b/Media/Images/HDSI-IoT-Agents.jpg differ
diff --git a/Media/Images/HIAS-IoT-Applications-Edit.png b/Media/Images/HIAS-IoT-Applications-Edit.png
index 8d57c85..c94023f 100644
Binary files a/Media/Images/HIAS-IoT-Applications-Edit.png and b/Media/Images/HIAS-IoT-Applications-Edit.png differ
diff --git a/Media/Images/HIAS-IoT-Applications.png b/Media/Images/HIAS-IoT-Applications.png
index 97d1b05..ade4145 100644
Binary files a/Media/Images/HIAS-IoT-Applications.png and b/Media/Images/HIAS-IoT-Applications.png differ
diff --git a/Media/Images/HIAS-IoT-Dashboard.png b/Media/Images/HIAS-IoT-Dashboard.png
index 6bd1432..e44a3c1 100644
Binary files a/Media/Images/HIAS-IoT-Dashboard.png and b/Media/Images/HIAS-IoT-Dashboard.png differ
diff --git a/Media/Images/HIAS-IoT-Data.png b/Media/Images/HIAS-IoT-Data.png
index 9a2abc7..2d9540f 100644
Binary files a/Media/Images/HIAS-IoT-Data.png and b/Media/Images/HIAS-IoT-Data.png differ
diff --git a/Media/Images/HIAS-IoT-Devices-Edit.png b/Media/Images/HIAS-IoT-Devices-Edit.png
index 9fa8493..4425265 100644
Binary files a/Media/Images/HIAS-IoT-Devices-Edit.png and b/Media/Images/HIAS-IoT-Devices-Edit.png differ
diff --git a/Media/Images/HIAS-IoT-Devices.png b/Media/Images/HIAS-IoT-Devices.png
index c7c8c70..b765b8d 100644
Binary files a/Media/Images/HIAS-IoT-Devices.png and b/Media/Images/HIAS-IoT-Devices.png differ
diff --git a/Media/Images/HIAS-IoT-Sensors.png b/Media/Images/HIAS-IoT-Sensors.png
index d251aba..5cc6853 100644
Binary files a/Media/Images/HIAS-IoT-Sensors.png and b/Media/Images/HIAS-IoT-Sensors.png differ
diff --git a/Media/Images/HIAS-IoT-Zones-Edit.png b/Media/Images/HIAS-IoT-Zones-Edit.png
index 28ad347..b0a30bd 100644
Binary files a/Media/Images/HIAS-IoT-Zones-Edit.png and b/Media/Images/HIAS-IoT-Zones-Edit.png differ
diff --git a/Media/Images/HIAS-IoT-Zones.png b/Media/Images/HIAS-IoT-Zones.png
index 97445bb..40e5cd8 100644
Binary files a/Media/Images/HIAS-IoT-Zones.png and b/Media/Images/HIAS-IoT-Zones.png differ
diff --git a/Media/Images/HIAS-NLU.jpg b/Media/Images/HIAS-NLU.jpg
index a291df6..a921900 100644
Binary files a/Media/Images/HIAS-NLU.jpg and b/Media/Images/HIAS-NLU.jpg differ
diff --git a/Media/Images/HIAS-Network.png b/Media/Images/HIAS-Network.png
index e477728..91cbba2 100644
Binary files a/Media/Images/HIAS-Network.png and b/Media/Images/HIAS-Network.png differ
diff --git a/README.md b/README.md
index 1bbb0c2..8cc7c21 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
## HIAS - Hospital Intelligent Automation System
[![HIAS - Hospital Intelligent Automation System](Media/Images/HIAS-Hospital-Intelligent-Automation-System.png)](https://github.com/LeukemiaAiResearch/HIAS)
-[![VERSION](https://img.shields.io/badge/VERSION-1.0.2-blue.svg)](https://github.com/LeukemiaAiResearch/HIAS/tree/1.0.2) [![DEV BRANCH](https://img.shields.io/badge/DEV%20BRANCH-1.1.0-blue.svg)](https://github.com/LeukemiaAiResearch/HIAS/tree/1.1.0) [![Contributions Welcome!](https://img.shields.io/badge/Contributions-Welcome-lightgrey.svg)](CONTRIBUTING.md) [![Issues](https://img.shields.io/badge/Issues-Welcome-lightgrey.svg)](issues) [![LICENSE](https://img.shields.io/badge/LICENSE-MIT-blue.svg)](LICENSE)
+[![VERSION](https://img.shields.io/badge/VERSION-2.0.0-blue.svg)](https://github.com/LeukemiaAiResearch/HIAS/tree/2.0.0) [![DEV BRANCH](https://img.shields.io/badge/DEV%20BRANCH-2.1.0-blue.svg)](https://github.com/LeukemiaAiResearch/HIAS/tree/1.1.0) [![Contributions Welcome!](https://img.shields.io/badge/Contributions-Welcome-lightgrey.svg)](CONTRIBUTING.md) [![Issues](https://img.shields.io/badge/Issues-Welcome-lightgrey.svg)](issues) [![LICENSE](https://img.shields.io/badge/LICENSE-MIT-blue.svg)](LICENSE)
@@ -10,25 +10,29 @@
- [Introduction](#introduction)
- [Key Features](#key-features)
-- [HIAS Hardware](#hias-hardware)
- [HIAS Network](#hias-network)
- [HIAS UI](#hias-ui)
- [HIAS Blockchain](#hias-blockchain)
-- [HIAS IoT](#hias-iot)
+- [HIAS Data Systems Interface](#hias-data-systems-interface)
+ - [HDSI IoT Agents](#hdsi-iot-agents)
+ - [MQTT](#mqtt)
+ - [AQMP](#aqmp)
+- [HIAS iotJumpWay Network](#hias-iotjumpway-network)
+ - [HIAS IoT Data Smart Contract](#hias-iot-data-smart-contract)
- [HIAS IoT Zones](#hias-iot-zones)
- [HIAS IoT Devices](#hias-iot-devices)
- [HIAS IoT Sensors/Actuators](#hias-iot-sensorsactuators)
- [HIAS IoT Applications](#hias-iot-applications)
- [HIAS IoT Data](#hias-iot-data)
- - [HIAS IoT Data Smart Contract](#hias-iot-data-smart-contract)
+- [HIAS Artificial Intelligence](#hias-artificial-intelligence)
+ - [HDSI AI Model Schemas](#hdsi-ai-model-schemas)
+ - [HIAS Acute Lymphoblastic Leukemia Detection System (CNN)](#hias-acute-lymphoblastic-leukemia-detection-system-cnn)
+ - [HIAS COVID-19 Detection System (CNN)](#hias-covid-19-detection-system-cnn)
+ - [HIAS Facial Recognition API](#hias-facial-recognition-api)
+ - [HIAS Natural Language Understanding Engines](#hias-natural-language-understanding-engines)
- [Installation](#installation)
-- [HIAS Detection Systems](#hias-detection-systems)
- - [Acute Lymphoblastic Leukemia Detection System (CNN)](#acute-lymphoblastic-leukemia-detection-system-cnn)
- - [COVID-19 Detection System (CNN)](#covid-19-detection-system-cnn)
- [HIAS Data Analysis](#hias-data-analysis)
- [HIAS COVID-19 Data Analysis](#hias-covid-19-data-analysis)
-- [HIAS Facial Recognition API](#hias-facial-recognition-api)
-- [HIAS Natural Language Understanding Engines](#hias-natural-language-understanding-engines)
- [EMAR / EMAR Mini](#emar--emar-mini)
- [Modular Addons](#modular-addons)
- [Acknowledgement](#acknowledgement)
@@ -59,44 +63,41 @@ __This project is a proof of concept, and is still a work in progress.__
![HIAS Network Map](Media/Images/HIAS-Network.png)
-- **Local Web Server (Complete)**
+- **Local Web Server**
- Locally hosted webserver using NGINX.
-- **High Grade SSL Encryption (Complete)**
+- **High Grade SSL Encryption**
- High grade (A+) encryption for the web server, proxy and network.
-- **Proxy (Complete)**
+- **Proxy**
- Secure access to local devices from the outside world.
-- **Blockchain (Complete)**
- - Private Ethereum blockchain for access permissions, provides data integrity and accountability.
-- **System Database (Complete)**
- - The system MySQL database powers the HIAS UI.
-- **IoT Database (Complete)**
- - The network IoT database is a Mongo database that stores all data from the HIAS network devices and applications.
-- **Local Samba Server (Complete)**
+- **HIAS Blockchain**
+ - Private Ethereum blockchain for access permissions, and providing data integrity & accountability.
+- **HDSI Context Broker**
+ - Context Broker handles contextual data for iotJumpWay IoT Agents, AI Models, Devices, Applications, Staff & Patients.
+- **HDSI IoT Agents**
+ - MQTT, AQMP & CoAP IoT Agents translate and push data coming from iotJumpWay Devices and Applications to the HDSI Context Broker.
+- **System Database**
+ - MySQL database powering the HIAS UI.
+- **IoT Database**
+ - The network IoT database is a Mongo database that stores all data from the HIAS network devices and applications, as well as iotJumpWay IoT Agents, AI Models, Devices, Applications, Staff & Patients contextual data.
+- **Local Samba Server**
- A local Samba file server allowing controlled individual and group access to files on your local network.
-- **Local IoT Broker (Complete)**
+- **Local IoT Broker**
- Local and private MQTT/Websockets broker based on the [iotJumpway Broker](https://github.com/iotJumpway/Broker "iotJumpway Broker").
-- **Server UI (Work In Progress)**
+- **Server UI**
- A control panel to monitor and manage your HIAS network.
-- **Facial Identification Systems (Complete)**
+- **Facial Identification Systems**
- Facial identification systems based on [TassAI](https://github.com/TassAI/ "TassAI").
-- **Natural Language Understanding (NLU) Server (Complete)**
+- **Natural Language Understanding (NLU) Server**
- Natural Language Understanding server based on [GeniSysAI](https://github.com/GeniSysAI/ "GeniSysAI").
-- **COVID Data Analysis System (Complete)**
+- **COVID Data Analysis System**
- A data anaysis system for monitoring the COVID 19 pandemic. This system collects data from the [Johns Hopkins University COVID-19 Daily Reports](https://github.com/CSSEGISandData/COVID-19/) on Github.
-- **AI Detection Systems (Complete)**
+- **AI Detection Systems**
- Detection systems for classsifying Acute Lymphoblastic Leukemia and COVID-19.
-- **HIS/HMS (In Development)**
+- **HIS/HMS**
- Hospital management system providing online tools for managing and running day to day activities and resources for the hospital.
-# HIAS Hardware
-![HIAS UI](Media/Images/HIAS-Hardware.png)
-
-HIAS has been developed on an UP2 and a 1.5TB HDD to show the potential of lower powered devices for building IoT networks. In a real world scenario such as a being used to power a hospital network, it is likely that a device with more resources and storage will be required.
-
-
-
# HIAS Network
![HIAS Network](Media/Images/HIAS-Network-Devices.png)
@@ -112,13 +113,31 @@ The HIAS UI is the central control panel for the server, and all of the modular
# HIAS Blockchain
-![HIAS Blockchain](Media/Images/HIAS-Blockchain.png)
-
The HIAS Blockchain is a private Ethereum blockchain network that provides an immutable history of everything that happens on the HIAS network. Every user/device and application has a HIAS Blockchain address, meaning their actions can be recorded on the blockchain. Smart contracts provide additional security when it comes to verifying permissions, data hashes are stored on the blockchain providing data integrity. and each action made by staff members in the UI is recorded. The HIAS Blockchain network can be extended by installing additional full miner nodes which help to create blocks, seal transaction blocks, and also have a full copy of the entire HIAS Blockchain which remain synchronized.
-# HIAS IoT
+# HIAS Data Systems Interface
+![HIAS Data Systems Interface](Media/Images/HDSI-Context-Broker.jpg)
+
+The HIAS Data Services Interface is a context broker that handles contextual information for the HIAS network. The broker implements the HDSI V1 API and allows easy management of HIAS iotJumpWay IoT Agents, AI Models, Devices, Applications, and HIAS Staff & Patient accounts and their related contextual data. HDSI is based on [Open Mobile Alliance](http://www.openmobilealliance.org/)'s [NGSI](http://www.openmobilealliance.org/release/NGSI/V1_0-20120529-A/OMA-TS-NGSI_Context_Management-V1_0-20120529-A.pdf), and has been customized to meet the requirements of the HIAS network.
+
+All iotJumpWay IoT Agents, AI Models, Devices, Applications, and HIAS Staff & Patient accounts have unique schemas that standardize their information and setup, these schemas are stored in the context broker.
+
+## HDSI IoT Agents
+![HDSI IoT Agents](Media/Images/HDSI-IoT-Agents.jpg)
+
+The HDSI IoT Agents translate and push data sent from iotJumpWay Devices & Applications to the HDSI Context Broker. Each IoT Agent is responsible for it's own communication protocol, or transport. Current supported IoT protocols include HTTP, MQTT, Websockets & AMQP, with a CoAP broker and IoT Agent in development. The IoT Agents listen to data being sent on using their protocol and sends contextual data to the context broker, and historical data is stored in directly in the Mongo database.
+
+### MQTT
+The MQTT (Message Queuing Telemetry Transport) protocol is one of the most well known and popular machine to machine communication protocols. Developed by IBM's Dr. Andy Stanford-Clark, the protocol is a lightweight publish and subscribe protocol designed for constrained devices. MQTT is primary communciation on the HIAS network.
+
+### AMQP
+The AMQP (Advanced Message Queuing Protocol) is another popular machine to machine communication protocol. Although different to MQTT, it has the same function, allowing constrained devices and applications to communicate with each other.
+
+
+
+# HIAS iotJumpWay Network
![HIAS IoT](Media/Images/HIAS-IoT-Dashboard.png)
The HIAS IoT network is powered by a new, fully open-source version of the [iotJumpWay](https://www.iotJumpWay.com "iotJumpWay"). The HIAS iotJumpway dashboard is your control panel for managing all of your network iotJumpWay zones, devices, sensors/actuators and applications.
@@ -167,41 +186,24 @@ The HIAS Blockchain hosts an iotJumpWay smart contract responsible for veryifing
-# Installation
-Installation scripts and tutorials for setting up your HIAS - Hospital Intelligent Automation System & UI are provided. To get started, please follow the installation guides provided below in the order they are given:
-
-| ORDER | GUIDE | INFORMATION | AUTHOR |
-| ----- | ----- | ----------- | ------ |
-| 1 | [Main Installation Guide](Documentation/Installation.md "Main Installation Guide") | Primary installation guide covering most of the information needed to do the core installation | [Adam Milton-Barker](https://www.leukemiaairesearch.com/team/adam-milton-barker "Adam Milton-Barker") |
-
-
+# HIAS Artificial Intelligence
+The HIAS network is made up of multiple open-source AI models, these models are provided through our official Github organization, as well as our research project Githubs. Current models available for the HIAS network include Leukemia and COVID classifiers, facial recognition and natural language understanding.
-# HIAS Detection Systems
-Using AI models on the HIAS network, the UI can be used to classify image based samples for diseases such as COVID-19 and Leukemia.
+## HDSI AI Model Schemas
+![HDSI AI Model Schemas](Media/Images/HDSI-AI-Model-Schemas.jpg)
+The HDSI schemas provide an easy way to manage and use the HIAS AI models. The schemas provide a standardization that allows you to not only use our models, but easily create your own and use them with the HIAS network.
- ## Acute Lymphoblastic Leukemia Detection System (CNN)
+ ## HIAS Acute Lymphoblastic Leukemia Detection System (CNN)
![HIAS COVID-19 Diagnosis (CNN)](Media/Images/HIAS-ALL-Detection-System.png)
The HIAS Acute Lymphoblastic Leukemia Detection System (CNN) used the [oneAPI Acute Lymphoblastic Leukemia Classifier](https://github.com/AMLResearchProject/oneAPI-ALL-Classifier), based on the proposed architecture in the [Acute Leukemia Classification Using Convolution Neural Network In Clinical Decision Support System](https://airccj.org/CSCP/vol7/csit77505.pdf) paper and using the [Acute Lymphoblastic Leukemia Image Database for Image Processing dataset](https://homes.di.unimi.it/scotti/all). The classifier achieves 98% accuracy at detecting Acute Lymphoblastic Leukemia in unseen data.
-## COVID-19 Detection System (CNN)
+## HIAS COVID-19 Detection System (CNN)
![HIAS COVID-19 Diagnosis (CNN)](Media/Images/HIAS-COVID-19-Detection-System.png)
The HIAS COVID-19 Detection System (CNN) system uses the [COVID-19 Tensorflow DenseNet Classifier](https://github.com/COVID-19-AI-Research-Project/AI-Classification/tree/master/Projects/2 "COVID-19 Tensorflow DenseNet Classifier") project, a Tensorflow 2 DenseNet implementation using the [SARS-COV-2 Ct-Scan Dataset](https://www.kaggle.com/plameneduardo/sarscov2-ctscan-dataset "SARS-COV-2 Ct-Scan Dataset") by our collaborators, Plamenlancaster: [Professor Plamen Angelov](https://www.lancaster.ac.uk/lira/people/#d.en.397371) from [Lancaster University](https://www.lancaster.ac.uk/)/ Centre Director @ [Lira](https://www.lancaster.ac.uk/lira/), & his researcher, [Eduardo Soares PhD](https://www.lancaster.ac.uk/sci-tech/about-us/people/eduardo-almeida-soares). The classifier achieves 92% accuracy at detecting COVID-19 in unseen data.
-
-
-# HIAS Data Analysis
-The HIAS network hosts a number of AI models that monitor data from local and external sources to make predictions based on the raw data. You can monitor real-time data using the HIAS UI.
-
-## HIAS COVID-19 Data Analysis
-![HIAS COVID-19 Data Analysis](Media/Images/HIAS-Data-Analysis-COVID-19.png)
-
-Functionality is now available to set up a basic COVID-19 tracker that powers graphs in the HIAS UI. This system pulls data from the [COVID-19 Data Repository by the Center for Systems Science and Engineering (CSSE) at Johns Hopkins University](https://github.com/CSSEGISandData/COVID-19 "COVID-19 Data Repository by the Center for Systems Science and Engineering (CSSE) at Johns Hopkins University") and displays the stats in the UI.
-
-
-
-# HIAS Facial Recognition API
+## HIAS Facial Recognition API
![HIAS Facial Recognition](Media/Images/HIAS-Facial-Recognition.png)
The HIAS facial recognition API is based on [TassAI](https://www.facebook.com/TassAI/ "TassAI"). The API allows for facial identification using authenticated HTTP requests from devices and applications that are authorized to communicate with the HIAS network.
@@ -214,13 +216,34 @@ Multiple TassAI facial recognition devices can be configured. The cameras track
-# HIAS Natural Language Understanding Engines
+## HIAS Natural Language Understanding Engines
![HIAS Natural Language Understanding Engines](Media/Images/HIAS-NLU.jpg)
The HIAS UI allows Natural Language Understanding Engines to be connected to the network. These NLUs can be communicated with via the network allowing applications and devices to have realtime spoken interactions with known and unknown users.
+
+
+# Installation
+Installation scripts and tutorials for setting up your HIAS - Hospital Intelligent Automation System & UI are provided. To get started, please follow the installation guides provided below in the order they are given:
+
+| ORDER | GUIDE | INFORMATION | AUTHOR |
+| ----- | ----- | ----------- | ------ |
+| 1 | [Main Installation Guide](Documentation/Installation.md "Main Installation Guide") | Primary installation guide covering most of the information needed to do the core installation | [Adam Milton-Barker](https://www.leukemiaairesearch.com/team/adam-milton-barker "Adam Milton-Barker") |
+
+
+
+# HIAS Data Analysis
+The HIAS network hosts a number of AI models that monitor data from local and external sources to make predictions based on the raw data. You can monitor real-time data using the HIAS UI.
+
+## HIAS COVID-19 Data Analysis
+![HIAS COVID-19 Data Analysis](Media/Images/HIAS-Data-Analysis-COVID-19.png)
+
+Functionality is now available to set up a basic COVID-19 tracker that powers graphs in the HIAS UI. This system pulls data from the [COVID-19 Data Repository by the Center for Systems Science and Engineering (CSSE) at Johns Hopkins University](https://github.com/CSSEGISandData/COVID-19 "COVID-19 Data Repository by the Center for Systems Science and Engineering (CSSE) at Johns Hopkins University") and displays the stats in the UI.
+
+
+
# EMAR / EMAR Mini
![EMAR](Media/Images/HIAS-Robotics-EMAR.png)
Functionality to update, monitor and control [EMAR](https://github.com/COVID-19-AI-Research-Project/EMAR "EMAR")/[EMAR Mini](https://github.com/COVID-19-AI-Research-Project/EMAR-Mini "EMAR Mini"). These features allow you to create EMAR/EMAR Mini devices, update the settings, monitor the camera streams and send commands to the robotic arm to move it.
diff --git a/Root/etc/nginx/sites-available/default b/Root/etc/nginx/sites-available/default
index 66d5b7d..fd4c6c0 100644
--- a/Root/etc/nginx/sites-available/default
+++ b/Root/etc/nginx/sites-available/default
@@ -1,90 +1,144 @@
server {
- server_name YourSubdomain.YourDomain.TLD;
- root /fserver/var/www/html;
+ root /fserver/var/www/html;
+ server_name YourHiasDomainName;
client_max_body_size 100M;
- location /Blockchain/API/ {
- auth_basic "Restricted";
- auth_basic_user_file /etc/nginx/security/htpasswd;
- proxy_pass http://HiasServerIp:8545/;
- }
-
- location /Security/API/ {
- auth_basic "Restricted";
- auth_basic_user_file /etc/nginx/security/htpasswd;
- proxy_pass http://HiasServerIp:8080/;
- }
-
- location / {
- rewrite ^/Blockchain/Contracts/Create$ /Blockchain/CCreate.php last;
- rewrite ^/Blockchain/Contracts/([0-9]+)/Transaction/([0-9]+)$ /Blockchain/Transaction.php?contract=$1&transaction=$2 last;
- rewrite ^/Blockchain/Contracts/Contract/([0-9]+)$ /Blockchain/Contract.php?contract=$1 last;
- rewrite ^/Data-Analysis/COVID-19/(.+)/([A-Za-z]+)/([A-Za-z]+)$ /Data-Analysis/COVID-19/index.php?country=$1&period=$2&stat=$3 last;
- rewrite ^/Robotics/EMAR/([0-9]+)$ /Robotics/EMAR/Device.php?emar=$1 last;
- rewrite ^/iotJumpWay/Sensors/([0-9]+)$ /iotJumpWay/Sensor.php?sensor=$1 last;
- rewrite ^/iotJumpWay/Sensors/Update$ /iotJumpWay/SensorUpdate.php last;
- rewrite ^/iotJumpWay/Sensors/Upload$ /iotJumpWay/SensorUpload.php last;
- rewrite ^/iotJumpWay/Sensors/Create$ /iotJumpWay/CreateSensor.php last;
- rewrite ^/iotJumpWay/Devices/Create$ /iotJumpWay/CreateDevice.php last;
- rewrite ^/iotJumpWay/([0-9]+)/Zones/([0-9]+)/Devices/([0-9]+)/Transaction/([0-9]+)$ /iotJumpWay/DeviceTransaction.php?location=$1&zone=$2&device=$3&transaction=$4 last;
- rewrite ^/iotJumpWay/([0-9]+)/Zones/([0-9]+)/Devices/([0-9]+)$ /iotJumpWay/Device.php?location=$1&zone=$2&device=$3 last;
- rewrite ^/iotJumpWay/Zones/Create$ /iotJumpWay/CreateZone.php last;
- rewrite ^/iotJumpWay/([0-9]+)/Zones/([0-9]+)$ /iotJumpWay/Zone.php?location=$1&zone=$2 last;
- rewrite ^/iotJumpWay/Applications/Create$ /iotJumpWay/CreateApp.php last;
- rewrite ^/iotJumpWay/([0-9]+)/Applications/([0-9]+)/Transaction/([0-9]+)$ /iotJumpWay/ApplicationTransaction.php?location=$1&application=$2&transaction=$3 last;
- rewrite ^/iotJumpWay/([0-9]+)/Applications/([0-9]+)$ /iotJumpWay/Application.php?location=$1&application=$2 last;
- rewrite ^/Hospital/Patients/([0-9]+)$ /Hospital/Patients/Patient.php?patient=$1 last;
- rewrite ^/Hospital/Patients/([0-9]+)/Transaction/([0-9]+)$ /Hospital/Patients/Transaction.php?patient=$1&transaction=$2 last;
- rewrite ^/Hospital/Beds/([0-9]+)/$ /Hospital/Beds/Bed.php?bed=$1 last;
- rewrite ^/Hospital/Beds/([0-9]+)/Transaction/([0-9]+)$ /Hospital/Beds/Transaction.php?bed=$1&transaction=$2 last;
- rewrite ^/Hospital/Staff/API/Applications/NLU/([A-Za-z]+)$ /Hospital/Staff/API/Applications/NLU/index.php?params=$1 last;
- rewrite ^/Hospital/Staff/API/Applications/User/([A-Za-z]+)$ /Hospital/Staff/API/Applications/User/index.php?params=$1 last;
- rewrite ^/Hospital/Staff/([0-9]+)$ /Hospital/Staff/Staff.php?staff=$1 last;
- rewrite ^/Security/GeniSysAI/([0-9]+)$ /Security/GeniSysAI/Device.php?genisysai=$1 last;
- rewrite ^/GeniSysAI/([0-9]+)$ /GeniSysAI/Device.php?genisysai=$1 last;
- try_files $uri $uri.html $uri/ @extensionless-php;
- index index.php index.html index.htm index.nginx-debian.html;
- }
-
- location ~ \.php$ {
- include fastcgi_params;
- include snippets/fastcgi-php.conf;
- fastcgi_pass unix:/run/php/php7.2-fpm.sock;
- }
-
-
- location @extensionless-php {
- rewrite ^(.*)$ $1.php last;
- }
-
- location ~ /\.ht {
- deny all;
- }
-
- listen [::]:443 ssl ipv6only=on; # managed by Certbot
- listen 443 ssl; # managed by Certbot
- ssl_certificate /etc/letsencrypt/live/YourSubdomain.YourDomain.TLD/fullchain.pem; # managed by Certbot
- ssl_certificate_key /etc/letsencrypt/live/YourSubdomain.YourDomain.TLD/privkey.pem; # managed by Certbot
- include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
- ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
-}
-server {
- listen 80;
- server_name "";
- return 444;
+ proxy_connect_timeout 600;
+ proxy_send_timeout 600;
+ proxy_read_timeout 600;
+ send_timeout 600;
+
+ location /Blockchain/API/ {
+ auth_basic "Restricted";
+ auth_basic_user_file /etc/nginx/security/htpasswd;
+ proxy_pass http://HiasServerIp:8545/;
+ }
+
+ location /ContextBroker/v1/about {
+ auth_basic "Restricted";
+ auth_basic_user_file /etc/nginx/security/htpasswd;
+ proxy_pass http://HiasServerIp:3524/about;
+ }
+
+ location /ContextBroker/v1/entities {
+ auth_basic "Restricted";
+ auth_basic_user_file /etc/nginx/security/htpasswd;
+ proxy_pass http://HiasServerIp:3524/entities;
+ }
+
+ location /ContextBroker/v1/entities/(.*)$ {
+ auth_basic "Restricted";
+ auth_basic_user_file /etc/nginx/security/htpasswd;
+ proxy_pass http://HiasServerIp:3524/entities/$1$is_args$args;
+ }
+
+ location /ContextBroker/v1/entities/(.*)/attrs$ {
+ auth_basic "Restricted";
+ auth_basic_user_file /etc/nginx/security/htpasswd;
+ proxy_pass http://HiasServerIp:3524/entities/$1/attrs$is_args$args;
+ }
+
+ location /ContextBroker/v1/agents {
+ auth_basic "Restricted";
+ auth_basic_user_file /etc/nginx/security/htpasswd;
+ proxy_pass http://HiasServerIp:3524/agents;
+ }
+
+ location /ContextBroker/v1/agents/(.*)$ {
+ auth_basic "Restricted";
+ auth_basic_user_file /etc/nginx/security/htpasswd;
+ proxy_pass http://HiasServerIp:3524/agents/$1$is_args$args;
+ }
+
+ location /ContextBroker/v1/agents/(.*)/attrs$ {
+ auth_basic "Restricted";
+ auth_basic_user_file /etc/nginx/security/htpasswd;
+ proxy_pass http://HiasServerIp:3524/agents/$1/attrs$is_args$args;
+ }
+
+ location ~* ^/TassAI/API/(.*)$ {
+ auth_basic "Restricted";
+ auth_basic_user_file /etc/nginx/security/htpasswd;
+ proxy_pass http://HiasServerIp:8080/$1;
+ }
+
+ location ~ \.php$ {
+ include fastcgi_params;
+ include snippets/fastcgi-php.conf;
+ fastcgi_pass unix:/run/php/php7.2-fpm.sock;
+ fastcgi_read_timeout 300;
+ }
+
+ location @extensionless-php {
+ rewrite ^(.*)$ $1.php last;
+ }
+
+ location ~ /\.ht {
+ deny all;
+ }
+
+ location / {
+ rewrite ^/AI/TassAI/([0-9]+)$ /AI/TassAI/Device.php?device=$1 last;
+ rewrite ^/AI/AML/([0-9]+)/Classify$ /AI/AML/Classify.php?device=$1 last;
+ rewrite ^/AI/AML/([0-9]+)$ /AI/AML/Device.php?device=$1 last;
+ rewrite ^/AI/ALL/([0-9]+)/Classify$ /AI/ALL/Classify.php?device=$1 last;
+ rewrite ^/AI/ALL/([0-9]+)$ /AI/ALL/Device.php?device=$1 last;
+ rewrite ^/AI/COVID/([0-9]+)/Classify$ /AI/COVID/Classify.php?device=$1 last;
+ rewrite ^/AI/COVID/([0-9]+)$ /AI/COVID/Device.php?device=$1 last;
+ rewrite ^/AI/Skin/([0-9]+)/Classify$ /AI/Skin/Classify.php?device=$1 last;
+ rewrite ^/AI/Skin/([0-9]+)$ /AI/Skin/Device.php?device=$1 last;
+ rewrite ^/AI/GeniSysAI/([0-9]+)$ /AI/GeniSysAI/Device.php?device=$1 last;
+ rewrite ^/AI/Model/([0-9]+)$ /AI/Model.php?model=$1 last;
+ rewrite ^/Blockchain/Contracts/Create$ /Blockchain/CCreate.php last;
+ rewrite ^/Blockchain/Contracts/([0-9]+)/Transaction/([0-9]+)$ /Blockchain/Transaction.php?contract=$1&transaction=$2 last;
+ rewrite ^/Blockchain/Contracts/Contract/([0-9]+)$ /Blockchain/Contract.php?contract=$1 last;
+ rewrite ^/Data-Analysis/COVID-19/(.+)/([A-Za-z]+)/([A-Za-z]+)$ /Data-Analysis/COVID-19/index.php?country=$1&period=$2&stat=$3 last;
+ rewrite ^/Hospital/Patients/([0-9]+)$ /Hospital/Patients/Patient.php?patient=$1 last;
+ rewrite ^/Hospital/Patients/([0-9]+)/Transaction/([0-9]+)$ /Hospital/Patients/Transaction.php?patient=$1&transaction=$2 last;
+ rewrite ^/Hospital/Beds/([0-9]+)/$ /Hospital/Beds/Bed.php?bed=$1 last;
+ rewrite ^/Hospital/Beds/([0-9]+)/Transaction/([0-9]+)$ /Hospital/Beds/Transaction.php?bed=$1&transaction=$2 last;
+ rewrite ^/Hospital/Staff/API/Applications/NLU/([A-Za-z]+)$ /Hospital/Staff/API/Applications/NLU/index.php?params=$1 last;
+ rewrite ^/Hospital/Staff/API/Applications/User/([A-Za-z]+)$ /Hospital/Staff/API/Applications/User/index.php?params=$1 last;
+ rewrite ^/Hospital/Staff/([0-9]+)$ /Hospital/Staff/Staff.php?staff=$1 last;
+ rewrite ^/iotJumpWay/Things/([0-9]+)$ /iotJumpWay/Thing.php?thing=$1 last;
+ rewrite ^/iotJumpWay/Things/Update$ /iotJumpWay/ThingUpdate.php last;
+ rewrite ^/iotJumpWay/Things/Upload$ /iotJumpWay/ThingUpload.php last;
+ rewrite ^/iotJumpWay/Things/Create$ /iotJumpWay/CreateThing.php last;
+ rewrite ^/iotJumpWay/Devices/Create$ /iotJumpWay/CreateDevice.php last;
+ rewrite ^/iotJumpWay/ContextBroker/Agents/Create$ /iotJumpWay/ContextBroker/AgentCreate.php last;
+ rewrite ^/iotJumpWay/ContextBroker/Agents/Agent/([0-9]+)$ /iotJumpWay/ContextBroker/Agent.php?agent=$1 last;
+ rewrite ^/iotJumpWay/ContextBroker/Agents/([0-9]+)/Transaction/([0-9]+)$ /iotJumpWay/ContextBroker/Transaction.php?agent=$1&transaction=$2 last;
+ rewrite ^/iotJumpWay/([0-9]+)/Zones/([0-9]+)/Devices/([0-9]+)/Transaction/([0-9]+)$ /iotJumpWay/DeviceTransaction.php?location=$1&zone=$2&device=$3&transaction=$4 last;
+ rewrite ^/iotJumpWay/([0-9]+)/Zones/([0-9]+)/Devices/([0-9]+)$ /iotJumpWay/Device.php?location=$1&zone=$2&device=$3 last;
+ rewrite ^/iotJumpWay/Zones/Create$ /iotJumpWay/CreateZone.php last;
+ rewrite ^/iotJumpWay/([0-9]+)/Zones/([0-9]+)$ /iotJumpWay/Zone.php?location=$1&zone=$2 last;
+ rewrite ^/iotJumpWay/Applications/Create$ /iotJumpWay/CreateApp.php last;
+ rewrite ^/iotJumpWay/([0-9]+)/Applications/([0-9]+)/Transaction/([0-9]+)$ /iotJumpWay/ApplicationTransaction.php?location=$1&application=$2&transaction=$3 last;
+ rewrite ^/iotJumpWay/([0-9]+)/Applications/([0-9]+)$ /iotJumpWay/Application.php?location=$1&application=$2 last;
+ rewrite ^/Robotics/EMAR/([0-9]+)$ /Robotics/EMAR/Device.php?device=$1 last;
+ try_files $uri $uri.html $uri/ @extensionless-php;
+ index index.php index.html index.htm index.nginx-debian.html;
+ }
+
+ listen [::]:443 ssl ipv6only=on; # managed by Certbot
+ listen 443 ssl; # managed by Certbot
+ ssl_certificate /etc/letsencrypt/live/YourHiasDomainName/fullchain.pem; # managed by Certbot
+ ssl_certificate_key /etc/letsencrypt/live/YourHiasDomainName/privkey.pem; # managed by Certbot
+ include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
+ ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
-server {
- if ($host = YourSubdomain.YourDomain.TLD){
- return 301 https://$host$request_uri;
- } # managed by Certbot
+server {
+ if ($host = YourHiasDomainName){
+ return 301 https://$host$request_uri;
+ } # managed by Certbot
- listen 80 default_server;
- listen [::]:80 default_server;
+ listen 80 default_server;
+ listen [::]:80 default_server;
- server_name YourSubdomain.YourDomain.TLD;
- return 404; # managed by Certbot
+ server_name YourHiasDomainName;
+ return 404; # managed by Certbot
-}
\ No newline at end of file
+}
diff --git a/Root/fserver/ethereum/Contracts/HIAS.sol b/Root/fserver/ethereum/Contracts/HIAS.sol
index d033520..c71329f 100644
--- a/Root/fserver/ethereum/Contracts/HIAS.sol
+++ b/Root/fserver/ethereum/Contracts/HIAS.sol
@@ -85,7 +85,7 @@ contract HIAS {
public
view
returns(bool) {
- require(callerAllowed());
+ require(callerAllowed(), "Caller Not Allowed");
if(compare(_type, "Application")){
return applicationMap[identifier].allowed == true;
} else if(compare(_type, "User")){
@@ -99,25 +99,26 @@ contract HIAS {
public
view
returns (uint256) {
- require(isHIAS());
+ require(isHIAS(), "Caller Not HIAS");
return address(this).balance;
}
function deposit(uint256 amount)
payable
public {
- require(isHIAS());
- require(msg.value == amount);
+ require(isHIAS(), "Caller Not HIAS");
+ require(msg.value == amount, "Deposit Values Do Not Match");
}
function updateCompensation(uint amount)
public {
- require(isHIAS());
+ require(isHIAS(), "Caller Not HIAS");
compensation = amount;
}
function compensate(address payable _address, uint256 amount)
private {
+ require(amount <= address(this).balance,"Not enough balance");
_address.transfer(amount);
}
@@ -138,8 +139,8 @@ contract HIAS {
function initiate(string memory _identifier, address _address, bool _admin, uint _user, string memory _name, uint _location, uint _application, uint _createdBy, uint _time)
public {
- require(isHIAS());
- require(setup == false);
+ require(isHIAS(), "Caller Not HIAS");
+ require(setup == false, "Setup is not false");
user memory newUser = user(_address, true, _admin, _user, _name, _location, _application, _time, _createdBy, _time, true);
userMap[_identifier] = newUser;
users++;
@@ -156,8 +157,8 @@ contract HIAS {
function registerUser(string memory _identifier, address _address, bool _admin, uint _user, string memory _name, uint _location, uint _application, uint _time, uint _createdBy)
public {
- require(callerAllowed());
- require(callerAdmin());
+ require(callerAllowed(), "Caller Not Allowed");
+ require(callerAdmin(), "Caller Not Admin");
user memory newUser = user(_address, true, _admin, _user, _name, _location, _application, _time, _createdBy, _time, true);
userMap[_identifier] = newUser;
users++;
@@ -174,8 +175,8 @@ contract HIAS {
function registerApplication(string memory _identifier, address _address, bool _admin, uint _location, uint _application, string memory _name, uint _createdBy, uint _time)
public {
- require(callerAllowed());
- require(callerAdmin());
+ require(callerAllowed(), "Caller Not Allowed");
+ require(callerAdmin(), "Caller Not Admin");
application memory newApplication = application(_address, true, _admin, _location, _application, _name, "OFFLINE", _time, _createdBy, _time, true);
applicationMap[_identifier] = newApplication;
applications++;
@@ -189,8 +190,8 @@ contract HIAS {
function registerDevice(string memory _identifier, address _address, uint _location, uint _zone, uint _device, string memory _name, uint _createdBy, uint _time)
public {
- require(callerAllowed());
- require(callerAdmin());
+ require(callerAllowed(), "Caller Not Allowed");
+ require(callerAdmin(), "Caller Not Admin");
device memory newDevice = device(_address, _location, _zone, _device, _name, "OFFLINE", _time, _createdBy, _time, true);
deviceMap[_identifier] = newDevice;
devices++;
@@ -199,9 +200,9 @@ contract HIAS {
function updateUser(string memory _identifier, string memory _type, bool _allowed, bool _admin, uint _user, string memory _name, uint _location, uint _application, uint _time)
public {
- require(callerAllowed());
- require(callerAdmin());
- require(exists(_type, _identifier));
+ require(callerAllowed(), "Caller Not Allowed");
+ require(callerAdmin(), "Caller Not Admin");
+ require(exists(_type, _identifier), "User Does Not Exist");
user storage currentUser = userMap[_identifier];
currentUser.allowed = _allowed;
currentUser.admin = _admin;
@@ -217,9 +218,9 @@ contract HIAS {
function updateApplication(string memory _identifier, string memory _type, bool _allowed, bool _admin, uint _location, string memory _name, string memory _status, uint _time)
public {
- require(callerAllowed());
- require(callerAdmin());
- require(exists(_type, _identifier));
+ require(callerAllowed(), "Caller Not Allowed");
+ require(callerAdmin(), "Caller Not Admin");
+ require(exists(_type, _identifier), "Application Does Not Exist");
application storage currentApplication = applicationMap[_identifier];
currentApplication.allowed = _allowed;
currentApplication.admin = _admin;
@@ -234,9 +235,9 @@ contract HIAS {
function updateDevice(string memory _identifier, string memory _type, uint _location, uint _zone, uint _device, string memory _name, string memory _status, uint _time)
public {
- require(callerAllowed());
- require(callerAdmin());
- require(exists(_type, _identifier));
+ require(callerAllowed(), "Caller Not Allowed");
+ require(callerAdmin(), "Caller Not Admin");
+ require(exists(_type, _identifier), "Device Does Not Exist");
device storage currentDevice = deviceMap[_identifier];
currentDevice.location = _location;
currentDevice.zone = _zone;
@@ -247,35 +248,22 @@ contract HIAS {
compensate(msg.sender, compensation);
}
- function count(string memory _type)
- public
- view
- returns (uint){
- require(callerAllowed());
- require(callerAdmin());
- if(compare(_type, "Application")){
- return applications;
- } else if(compare(_type, "Device")){
- return devices;
- } else if(compare(_type, "User")){
- return users;
- }
- }
-
function deregsiter(string memory _type, string memory _identifier)
public {
- require(callerAllowed());
- require(callerAdmin());
- require(exists(_type, _identifier));
+ require(callerAllowed(), "Caller Not Allowed");
+ require(callerAdmin(), "Caller Not Admin");
if(compare(_type, "Application")){
+ require(exists(_type, _identifier), "Application Does Not Exist");
delete authorized[applicationMap[_identifier].bcaddress];
delete applicationMap[_identifier];
applications--;
} else if(compare(_type, "Device")){
+ require(exists(_type, _identifier), "Device Does Not Exist");
delete authorized[deviceMap[_identifier].bcaddress];
delete deviceMap[_identifier];
devices--;
} else if(compare(_type, "User")){
+ require(exists(_type, _identifier), "User Does Not Exist");
delete authorized[userMap[_identifier].bcaddress];
delete userMap[_identifier];
users--;
@@ -287,9 +275,9 @@ contract HIAS {
public
view
returns(user memory){
- require(callerAllowed());
- require(callerAdmin());
- require(exists("User", _identifier));
+ require(callerAllowed(), "Caller Not Allowed");
+ require(callerAdmin(), "Caller Not Admin");
+ require(exists("User", _identifier), "User Does Not Exist");
return(userMap[_identifier]);
}
@@ -297,9 +285,9 @@ contract HIAS {
public
view
returns(application memory){
- require(callerAllowed());
- require(callerAdmin());
- require(exists("Application", _identifier));
+ require(callerAllowed(), "Caller Not Allowed");
+ require(callerAdmin(), "Caller Not Admin");
+ require(exists("Application", _identifier), "Application Does Not Exist");
return(applicationMap[_identifier]);
}
@@ -307,9 +295,9 @@ contract HIAS {
public
view
returns(device memory){
- require(callerAllowed());
- require(callerAdmin());
- require(exists("Device", _identifier));
+ require(callerAllowed(), "Caller Not Allowed");
+ require(callerAdmin(), "Caller Not Admin");
+ require(exists("Device", _identifier), "Device Does Not Exist");
return(deviceMap[_identifier]);
}
diff --git a/Root/fserver/ethereum/Contracts/HIASPatients.sol b/Root/fserver/ethereum/Contracts/HIASPatients.sol
index 05d5cb1..1f66cda 100644
--- a/Root/fserver/ethereum/Contracts/HIASPatients.sol
+++ b/Root/fserver/ethereum/Contracts/HIASPatients.sol
@@ -37,7 +37,7 @@ contract HIASPatients {
function initiate()
public {
- require(isHIAS());
+ require(isHIAS(), "Caller Not HIAS");
require(setup == false);
authorized[msg.sender] = true;
setup = true;
@@ -47,25 +47,26 @@ contract HIASPatients {
public
view
returns (uint256) {
- require(isHIAS());
+ require(isHIAS(), "Caller Not HIAS");
return address(this).balance;
}
function deposit(uint256 amount)
payable
public {
- require(isHIAS());
+ require(isHIAS(), "Caller Not HIAS");
require(msg.value == amount);
}
function updateCompensation(uint amount)
public {
- require(isHIAS());
+ require(isHIAS(), "Caller Not HIAS");
compensation = amount;
}
function compensate(address payable _address, uint256 amount)
private {
+ require( amount <= address(this).balance,"Not enough balance") ;
_address.transfer(amount);
}
@@ -80,7 +81,7 @@ contract HIASPatients {
public
view
returns(bool) {
- require(userAllowed());
+ require(userAllowed(), "Access not allowed");
return patientMap[_identifier].exists == true;
}
@@ -88,7 +89,7 @@ contract HIASPatients {
public
view
returns(bool) {
- require(userAllowed());
+ require(userAllowed(), "Access not allowed");
return patientMap[_identifier].active == true;
}
@@ -96,7 +97,7 @@ contract HIASPatients {
public
view
returns(bool) {
- require(userAllowed());
+ require(userAllowed(), "Access not allowed");
return patientMap[_identifier].admitted == true;
}
@@ -104,27 +105,27 @@ contract HIASPatients {
public
view
returns(bool) {
- require(userAllowed());
+ require(userAllowed(), "Access not allowed");
return patientMap[_identifier].discharged == true;
}
function registerUser(address _address)
public {
- require(userAllowed());
+ require(userAllowed(), "Access not allowed");
authorized[_address] = true;
compensate(msg.sender, compensation);
}
function deregisterUser(address _address)
public {
- require(userAllowed());
+ require(userAllowed(), "Access not allowed");
delete authorized[_address];
compensate(msg.sender, compensation);
}
function registerPatient(string memory _identifier, address _address, bool _active, bool _admitted, bool _discharged, uint _patient, uint _application, uint _time, uint _createdBy)
public {
- require(userAllowed());
+ require(userAllowed(), "Access not allowed");
patient memory newPatient = patient(_address, _active, _admitted, _discharged, _patient, _application, _time, _createdBy, _time, true);
patientMap[_identifier] = newPatient;
patients++;
@@ -135,15 +136,15 @@ contract HIASPatients {
public
view
returns(patient memory){
- require(userAllowed());
- require(patientExists(_identifier));
+ require(userAllowed(), "Access not allowed");
+ require(patientExists(_identifier), "Patient does not exist");
return(patientMap[_identifier]);
}
function updatePatient(string memory _identifier, address _address, bool _active, bool _admitted, bool _discharged, uint _patient, uint _application, uint _time)
public {
- require(userAllowed());
- require(patientExists(_identifier));
+ require(userAllowed(), "Access not allowed");
+ require(patientExists(_identifier), "Patient does not exist");
patient storage currentPatient = patientMap[_identifier];
currentPatient.bcaddress = _address;
currentPatient.active = _active;
@@ -157,19 +158,10 @@ contract HIASPatients {
function deregisterPatient(string memory _identifier)
public {
- require(userAllowed());
- require(patientExists(_identifier));
+ require(userAllowed(), "Access not allowed");
+ require(patientExists(_identifier), "Patient does not exist");
delete patientMap[_identifier];
patients--;
compensate(msg.sender, compensation);
}
-
- function countPatients()
- public
- view
- returns (uint){
- require(userAllowed());
- return patients;
- }
-
}
\ No newline at end of file
diff --git a/Root/fserver/ethereum/Contracts/build/__init__.py b/Root/fserver/ethereum/Contracts/build/.keep
similarity index 100%
rename from Root/fserver/ethereum/Contracts/build/__init__.py
rename to Root/fserver/ethereum/Contracts/build/.keep
diff --git a/Root/fserver/ethereum/Contracts/iotJumpWay.sol b/Root/fserver/ethereum/Contracts/iotJumpWay.sol
index a56d804..f279ce2 100644
--- a/Root/fserver/ethereum/Contracts/iotJumpWay.sol
+++ b/Root/fserver/ethereum/Contracts/iotJumpWay.sol
@@ -31,8 +31,8 @@ contract iotJumpWay {
function initiate()
public {
- require(isHIAS());
- require(setup == false);
+ require(isHIAS(), "Caller Not HIAS");
+ require(setup == false, "Setup is not false");
authorized[msg.sender] = true;
setup = true;
}
@@ -41,25 +41,26 @@ contract iotJumpWay {
public
view
returns (uint256) {
- require(isHIAS());
+ require(isHIAS(), "Caller Not HIAS");
return address(this).balance;
}
function deposit(uint256 amount)
payable
public {
- require(isHIAS());
+ require(isHIAS(), "Caller Not HIAS");
require(msg.value == amount);
}
function updateCompensation(uint amount)
public {
- require(isHIAS());
+ require(isHIAS(), "Caller Not HIAS");
compensation = amount;
}
function compensate(address payable _address, uint256 amount)
private {
+ require(amount <= address(this).balance,"Not enough balance");
_address.transfer(amount);
}
@@ -74,27 +75,27 @@ contract iotJumpWay {
public
view
returns(bool) {
- require(accessAllowed(msg.sender));
+ require(accessAllowed(msg.sender), "Access not allowed");
return hashMap[_identifier].exists == true;
}
function registerAuthorized(address _address)
public {
- require(accessAllowed(msg.sender));
+ require(accessAllowed(msg.sender), "Access not allowed");
authorized[_address] = true;
compensate(msg.sender, compensation);
}
function deregisterAuthorized(address _address)
public {
- require(accessAllowed(msg.sender));
+ require(accessAllowed(msg.sender), "Access not allowed");
delete authorized[_address];
compensate(msg.sender, compensation);
}
function registerHash(string memory dataId, bytes memory _dataHash, uint _time, uint _createdBy, string memory _identifier, address payable _address)
public {
- require(accessAllowed(msg.sender));
+ require(accessAllowed(msg.sender), "Access not allowed");
dataHash memory newHashMap = dataHash(_dataHash, _time, _createdBy, _identifier, true);
hashMap[dataId] = newHashMap;
hashes++;
@@ -106,17 +107,9 @@ contract iotJumpWay {
public
view
returns(dataHash memory){
- require(accessAllowed(msg.sender));
- require(hashExists(_identifier));
+ require(accessAllowed(msg.sender), "Access not allowed");
+ require(hashExists(_identifier), "Hash does not exist");
return(hashMap[_identifier]);
}
- function count()
- public
- view
- returns (uint){
- require(accessAllowed(msg.sender));
- return hashes;
- }
-
}
\ No newline at end of file
diff --git a/Root/fserver/ethereum/HIAS/__init__.py b/Root/fserver/ethereum/HIAS/.keep
similarity index 100%
rename from Root/fserver/ethereum/HIAS/__init__.py
rename to Root/fserver/ethereum/HIAS/.keep
diff --git a/Root/var/www/Classes/Core/GeniSys.php b/Root/var/www/Classes/Core/GeniSys.php
index 13ea3f1..83fbb5b 100644
--- a/Root/var/www/Classes/Core/GeniSys.php
+++ b/Root/var/www/Classes/Core/GeniSys.php
@@ -20,6 +20,68 @@ function __construct($_GeniSys)
$this->web3 = $this->blockchainConnection();
$this->contract = new Contract($this->web3->provider, $this->bcc["abi"]);
endif;
+ $this->cb = $this->getContextBrokerConf();
+ }
+
+ public function getContextBrokerConf()
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM contextbroker
+ ");
+ $pdoQuery->execute();
+ $response=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+ return $response;
+ }
+
+ private function createContextHeaders($username = "", $password = "")
+ {
+ if($username):
+ $basicAuth = $username . ":" . $password;
+ else:
+ $basicAuth = $_SESSION["GeniSysAI"]["User"] . ":" . $this->_GeniSys->_helpers->oDecrypt($_SESSION["GeniSysAI"]["Pass"]);
+ endif;
+ $basicAuth = base64_encode($basicAuth);
+
+ return [
+ "Content-Type: application/json",
+ 'Authorization: Basic '. $basicAuth
+ ];
+ }
+
+ private function contextBrokerRequest($method, $url, $headers, $json)
+ {
+ $path = $this->_GeniSys->_helpers->oDecrypt($this->_GeniSys->_confs["domainString"]) . "/" . $this->cb["url"] . "/" . $url;
+
+ if($method == "GET"):
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ curl_setopt($ch, CURLOPT_HEADER, 1);
+ curl_setopt($ch, CURLOPT_URL, $path);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ $response = curl_exec($ch);
+ $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
+ $header = substr($response, 0, $header_size);
+ $body = substr($response, $header_size);
+ curl_close($ch);
+ elseif($method == "POST"):
+ $ch = curl_init($path);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ curl_setopt($ch, CURLOPT_HEADER, 1);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
+ $response = curl_exec($ch);
+ $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
+ $header = substr($response, 0, $header_size);
+ $body = substr($response, $header_size);
+ curl_close($ch);
+ endif;
+
+ return $body;
}
public function getBlockchainConf()
@@ -138,14 +200,14 @@ public function login()
endif;
endif;
- $gsysuser = $this->getUserByName(filter_input(INPUT_POST, "username", FILTER_SANITIZE_STRING));
+ $gsysuser = $this->getUserByName(filter_input(INPUT_POST, "username", FILTER_SANITIZE_STRING), filter_input(INPUT_POST,'password',FILTER_SANITIZE_STRING));
if($gsysuser["id"]):
if($this->verifyPassword(filter_input(INPUT_POST,'password',FILTER_SANITIZE_STRING),
$this->_GeniSys->_helpers->oDecrypt($gsysuser["password"]))): session_regenerate_id();
$_SESSION["GeniSysAI"]=[
- "Active"=>true,
+ "Active"=>True,
"Uid"=>$gsysuser["id"],
"Identifier"=>$gsysuser["apub"],
"User"=>filter_input(INPUT_POST, "username", FILTER_SANITIZE_STRING),
@@ -153,7 +215,7 @@ public function login()
"Pic"=>$gsysuser["pic"],
"Mqtt"=> [
"Location" => $gsysuser["lid"],
- "Application" => $gsysuser["aid"],
+ "Application" => $gsysuser["apub"],
"ApplicationName" => $gsysuser["name"],
"User" => $gsysuser["mqttu"],
"Pass" => $gsysuser["mqttp"]
@@ -405,49 +467,60 @@ public function getUser($userId)
$this->checkBlockchainPermissions();
$pdoQuery = $this->_GeniSys->_secCon->prepare("
- SELECT id,
- name,
- password
- FROM users
- WHERE id = :id
+ SELECT users.id,
+ users.password,
+ mqtt.id as aid,
+ mqtt.apub
+ FROM users users
+ INNER JOIN mqtta mqtt
+ ON users.aid = mqtt.id
+ WHERE users.id = :id
");
$pdoQuery->execute([
":id"=> $userId
]);
- $response=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $user=$pdoQuery->fetch(PDO::FETCH_ASSOC);
$pdoQuery->closeCursor();
$pdoQuery = null;
+ $context = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "/" . $user["apub"] . "?attrs=name&type=Staff", $this->createContextHeaders(), []), true);
+ $user["name"] = $context["Data"]["name"]["value"];
- return $response;
+ return $user;
}
- public function getUserByName($username)
+ public function getUserByName($username = "", $password = "")
{
$pdoQuery = $this->_GeniSys->_secCon->prepare("
SELECT users.id,
users.bcaddress,
users.bcpw,
users.password,
- users.pic,
- mqtt.lid,
mqtt.id as aid,
- mqtt.name,
- mqtt.mqttu,
- mqtt.apub,
- mqtt.mqttp
+ mqtt.apub
FROM users users
INNER JOIN mqtta mqtt
- ON users.id = mqtt.uid
+ ON users.aid = mqtt.id
WHERE users.username = :username
");
$pdoQuery->execute([
":username"=> $username
]);
- $response=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $user=$pdoQuery->fetch(PDO::FETCH_ASSOC);
$pdoQuery->closeCursor();
$pdoQuery = null;
- return $response;
+ if($password):
+ $context = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "/" . $user["apub"] . "?type=Staff", $this->createContextHeaders($username, $password), []), true);
+ else:
+ $context = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "/" . $user["apub"] . "?type=Staff", $this->createContextHeaders(), []), true);
+ endif;
+ $user["lid"] = $context["Data"]["lid"]["entity"];
+ $user["pic"] = $context["Data"]["picture"]["value"];
+ $user["name"] = $context["Data"]["name"]["value"];
+ $user["mqttu"] = $context["Data"]["mqtt"]["username"];
+ $user["mqttp"] = $context["Data"]["mqtt"]["password"];
+
+ return $user;
}
private static function verifyPassword($password,$hash) {
@@ -456,20 +529,23 @@ private static function verifyPassword($password,$hash) {
public function getStats()
{
- $this->checkBlockchainPermissions();
$pdoQuery = $this->_GeniSys->_secCon->prepare("
- SELECT cpu,
- mem,
- hdd,
- tempr
+ SELECT apub
FROM mqtta
Where id = :id
");
$pdoQuery->execute([
":id" => $this->_GeniSys->_confs["aid"]
]);
- $stats=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $coreApp=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+
+ $context = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "/" . $coreApp["apub"] . "?type=Application&attrs=batteryLevel.value,cpuUsage.value,memoryUsage.value,hddUsage.value,temperature.value", $this->createContextHeaders(), []), true);
+
+ $stats["cpu"] = $context["Data"]["cpuUsage"]["value"];
+ $stats["mem"] = $context["Data"]["memoryUsage"]["value"];
+ $stats["hdd"] = $context["Data"]["hddUsage"]["value"];
+ $stats["tempr"] = $context["Data"]["temperature"]["value"];
return $stats;
}
diff --git a/Root/var/www/Classes/Core/confs.json b/Root/var/www/Classes/Core/confs.json
index 9104090..47a5861 100644
--- a/Root/var/www/Classes/Core/confs.json
+++ b/Root/var/www/Classes/Core/confs.json
@@ -1,9 +1,9 @@
{
- "dbname": "",
- "dbusername": "",
- "dbpassword": "",
- "mdbname": "",
- "mdbusername": "",
- "mdbpassword": "",
- "key": ""
+ "dbname": "YourMysqlDatabaseName",
+ "dbusername": "YourMysqlDatabaseUsername",
+ "dbpassword": "YourMysqlDatabasePassword^",
+ "mdbname": "YourMongoDatabaseName",
+ "mdbusername": "YourMongoDatabaseUsername",
+ "mdbpassword": "YourMongoDatabasePassword",
+ "key": "YourEncryptionKey"
}
\ No newline at end of file
diff --git a/Root/var/www/Classes/Core/init.php b/Root/var/www/Classes/Core/init.php
index 42f1801..61c1b90 100644
--- a/Root/var/www/Classes/Core/init.php
+++ b/Root/var/www/Classes/Core/init.php
@@ -75,6 +75,7 @@ function __construct(Core $_secCon, $_pageDetails)
include dirname(__FILE__) . '/../../Classes/helpers.php';
$this->_helpers = new Helpers($this);
+ $this->cb = $this->getContextBrokerConf();
$this->_confs = $this->getConfigs();
$this->_pageDetails = $_pageDetails;
@@ -97,6 +98,63 @@ private function setCookie()
endif;
}
+ public function getContextBrokerConf()
+ {
+ $pdoQuery = $this->_secCon->prepare("
+ SELECT *
+ FROM contextbroker
+ ");
+ $pdoQuery->execute();
+ $response=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+ return $response;
+ }
+
+ private function createContextHeaders()
+ {
+ $basicAuth = $_SESSION["GeniSysAI"]["User"] . ":" . $this->_helpers->oDecrypt($_SESSION["GeniSysAI"]["Pass"]);
+ $basicAuth = base64_encode($basicAuth);
+
+ return [
+ "Content-Type: application/json",
+ 'Authorization: Basic '. $basicAuth
+ ];
+ }
+
+ private function contextBrokerRequest($method, $url, $headers, $json, $domain)
+ {
+ $path = $this->_helpers->oDecrypt($domain) . "/" . $this->cb["url"] . "/" . $url;
+
+ if($method == "GET"):
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ curl_setopt($ch, CURLOPT_HEADER, 1);
+ curl_setopt($ch, CURLOPT_URL, $path);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ $response = curl_exec($ch);
+ $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
+ $header = substr($response, 0, $header_size);
+ $body = substr($response, $header_size);
+ curl_close($ch);
+ elseif($method == "POST"):
+ $ch = curl_init($path);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ curl_setopt($ch, CURLOPT_HEADER, 1);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
+ $response = curl_exec($ch);
+ $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
+ $header = substr($response, 0, $header_size);
+ $body = substr($response, $header_size);
+ curl_close($ch);
+ endif;
+
+ return $body;
+ }
+
public function getBlockchainConf()
{
$pdoQuery = $this->_secCon->prepare("
@@ -175,22 +233,28 @@ protected function getConfigs()
server.meta_title,
server.meta_description,
server.domainString,
- mqtta.status,
- mqtta.lt as alt,
- mqtta.lg as alg,
- mqtta.cpu,
- mqtta.mem,
- mqtta.hdd,
- mqtta.tempr
+ mqtta.apub
FROM settings server
INNER JOIN mqtta mqtta
ON mqtta.id = server.aid
");
$pdoQuery->execute();
- $response=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $configs=$pdoQuery->fetch(PDO::FETCH_ASSOC);
$pdoQuery->closeCursor();
$pdoQuery = null;
- return $response;
+
+ if(isSet($_SESSION["GeniSysAI"]["Active"])):
+ $context = json_decode($this->contextBrokerRequest("GET", "entities/" . $configs["apub"] . "?type=Application", $this->createContextHeaders(), [], $configs["domainString"]), true);
+ $configs["status"] = $context["Data"]["status"]["value"];
+ $configs["cpu"] = $context["Data"]["cpuUsage"]["value"];
+ $configs["mem"] = $context["Data"]["memoryUsage"]["value"];
+ $configs["hdd"] = $context["Data"]["hddUsage"]["value"];
+ $configs["tempr"] = $context["Data"]["temperature"]["value"];
+ $configs["alt"] = $context["Data"]["location"]["value"]["coordinates"][0];
+ $configs["alg"] = $context["Data"]["location"]["value"]["coordinates"][1];
+ endif;
+
+ return $configs;
}
public function updateConfigs()
diff --git a/Root/var/www/Classes/helpers.php b/Root/var/www/Classes/helpers.php
index ee8f6f4..2ae92a2 100644
--- a/Root/var/www/Classes/helpers.php
+++ b/Root/var/www/Classes/helpers.php
@@ -1,136 +1,71 @@
_GeniSys = $_GeniSys;
- }
+ function __construct($_GeniSys)
+ {
+ $this->_GeniSys = $_GeniSys;
+ }
- function decrypt($data) {
- $encryption_key = base64_decode($this->_GeniSys->_key);
- $method = "aes-" . strlen($encryption_key) * 8 . "-cbc";
- $iv = substr(base64_decode($data), 0, 16);
- $decoded = openssl_decrypt(substr(base64_decode($data), 16), $method, $encryption_key, TRUE, $iv);
- return $decoded;
- }
+ function decrypt($data) {
+ $encryption_key = base64_decode($this->_GeniSys->_key);
+ $method = "aes-" . strlen($encryption_key) * 8 . "-cbc";
+ $iv = substr(base64_decode($data), 0, 16);
+ $decoded = openssl_decrypt(substr(base64_decode($data), 16), $method, $encryption_key, TRUE, $iv);
+ return $decoded;
+ }
- public function oDecrypt($encrypted)
- {
- $encryption_key = base64_decode($this->_GeniSys->_key);
- list($encrypted_data, $iv) = explode("::", base64_decode($encrypted), 2);
- return openssl_decrypt($encrypted_data, "aes-256-cbc", $encryption_key, 0, $iv);
- }
+ public function oDecrypt($encrypted)
+ {
+ $encryption_key = base64_decode($this->_GeniSys->_key);
+ list($encrypted_data, $iv) = explode("::", base64_decode($encrypted), 2);
+ return openssl_decrypt($encrypted_data, "aes-256-cbc", $encryption_key, 0, $iv);
+ }
- public function oEncrypt($value)
- {
- $encryption_key = base64_decode($this->_GeniSys->_key);
- $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length("aes-256-cbc"));
- $encrypted = openssl_encrypt($value, "aes-256-cbc", $encryption_key, 0, $iv);
- return base64_encode($encrypted . "::" . $iv);
- }
+ public function oEncrypt($value)
+ {
+ $encryption_key = base64_decode($this->_GeniSys->_key);
+ $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length("aes-256-cbc"));
+ $encrypted = openssl_encrypt($value, "aes-256-cbc", $encryption_key, 0, $iv);
+ return base64_encode($encrypted . "::" . $iv);
+ }
- public function getUserIP()
- {
- if(array_key_exists("HTTP_X_FORWARDED_FOR", $_SERVER) && !empty($_SERVER["HTTP_X_FORWARDED_FOR"])):
- if (strpos($_SERVER["HTTP_X_FORWARDED_FOR"],",") > 0):
- $addr = explode( ",", $_SERVER["HTTP_X_FORWARDED_FOR"]);
- return trim($addr[0]);
- else:
- return $_SERVER["HTTP_X_FORWARDED_FOR"];
- endif;
- else:
- return $_SERVER["REMOTE_ADDR"];
- endif;
- }
+ public function getUserIP()
+ {
+ if(array_key_exists("HTTP_X_FORWARDED_FOR", $_SERVER) && !empty($_SERVER["HTTP_X_FORWARDED_FOR"])):
+ if (strpos($_SERVER["HTTP_X_FORWARDED_FOR"], ",") > 0):
+ $addr = explode(",", $_SERVER["HTTP_X_FORWARDED_FOR"]);
+ return trim($addr[0]);
+ else:
+ return $_SERVER["HTTP_X_FORWARDED_FOR"];
+ endif;
+ else:
+ return $_SERVER["REMOTE_ADDR"];
+ endif;
+ }
- public function generate_uuid() {
- return sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
- mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ),
- mt_rand( 0, 0xffff ),
- mt_rand( 0, 0x0C2f ) | 0x4000,
- mt_rand( 0, 0x3fff ) | 0x8000,
- mt_rand( 0, 0x2Aff ), mt_rand( 0, 0xffD3 ), mt_rand( 0, 0xff4B )
- );
- }
+ public static function verifyPassword($password, $hash)
+ {
+ return password_verify(
+ $password,
+ $hash);
+ }
- public function password($l = 20, $c = 2, $n = 2, $s = 2) {
- $out = "";
- $count = $c + $n + $s;
- if(!is_int($l) || !is_int($c) || !is_int($n) || !is_int($s)) {
- trigger_error('Argument(s) not an integer', E_USER_WARNING);
- return false;
- }
- elseif($l < 0 || $l > 20 || $c < 0 || $n < 0 || $s < 0) {
- trigger_error('Argument(s) out of range', E_USER_WARNING);
- return false;
- }
- elseif($c > $l) {
- trigger_error('Number of password capitals required exceeds password length', E_USER_WARNING);
- return false;
- }
- elseif($n > $l) {
- trigger_error('Number of password numerals exceeds password length', E_USER_WARNING);
- return false;
- }
- elseif($s > $l) {
- trigger_error('Number of password capitals exceeds password length', E_USER_WARNING);
- return false;
- }
- elseif($count > $l) {
- trigger_error('Number of password special characters exceeds specified password length', E_USER_WARNING);
- return false;
- }
- $chars = "abcdefghijklmnopqrstuvwxyz";
- $caps = strtoupper($chars);
- $nums = "0123456789";
- $syms = "!@#$%^&*()-_?";
- for($i = 0; $i < $l; $i++) {
- $out .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
- }
- if($count) {
- $tmp1 = str_split($out);
- $tmp2 = array();
- for($i = 0; $i < $c; $i++) {
- array_push($tmp2, substr($caps, mt_rand(0, strlen($caps) - 1), 1));
- }
- for($i = 0; $i < $n; $i++) {
- array_push($tmp2, substr($nums, mt_rand(0, strlen($nums) - 1), 1));
- }
- for($i = 0; $i < $s; $i++) {
- array_push($tmp2, substr($syms, mt_rand(0, strlen($syms) - 1), 1));
- }
- $tmp1 = array_slice($tmp1, 0, $l - $count);
- $tmp1 = array_merge($tmp1, $tmp2);
- shuffle($tmp1);
- $out = implode('', $tmp1);
- }
+ public static function createPasswordHash($password)
+ {
+ return password_hash(
+ $password,
+ PASSWORD_DEFAULT);
+ }
- return $out;
- }
-
- public static function verifyPassword($password, $hash)
- {
- return password_verify(
- $password,
- $hash);
- }
-
- public static function createPasswordHash($password)
- {
- return password_hash(
- $password,
- PASSWORD_DEFAULT);
- }
-
- public function generateKey($length = 10){
- $characters="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0987654321".time();
- $charactersLength = strlen($characters);
- $randomString = "";
- for ($i = $length; $i > 0; $i--)
- {
- $randomString .= $characters[rand(0, $charactersLength - 1)];
- }
- return $randomString;
- }
- }
\ No newline at end of file
+ public function generateKey($length = 10){
+ $characters="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0987654321".time();
+ $charactersLength = strlen($characters);
+ $randomString = "";
+ for ($i = $length; $i > 0; $i--)
+ {
+ $randomString .= $characters[rand(0, $charactersLength - 1)];
+ }
+ return $randomString;
+ }
+ }
\ No newline at end of file
diff --git a/Root/var/www/html/Detection/ALL/CNN/Classes/ALL.js b/Root/var/www/html/AI/ALL/Classes/ALL.js
similarity index 52%
rename from Root/var/www/html/Detection/ALL/CNN/Classes/ALL.js
rename to Root/var/www/html/AI/ALL/Classes/ALL.js
index 3ac2230..6065742 100644
--- a/Root/var/www/html/Detection/ALL/CNN/Classes/ALL.js
+++ b/Root/var/www/html/AI/ALL/Classes/ALL.js
@@ -1,12 +1,55 @@
var ALL = {
+ Create: function() {
+ $.post(window.location.href, $("#all_classifier").serialize(), function(resp) {
+ var resp = jQuery.parseJSON(resp);
+ switch (resp.Response) {
+ case "OK":
+ GeniSys.ResetForm("all_classifier");
+ $('.modal-title').text('ALL Classifier Devices');
+ $('.modal-body').html("HIAS ALL Classifier Device ID #" + resp.GDID + " created! Please save the API keys safely. The device's credentials are provided below. The credentials can be reset in the GeniSyAI Security Devices area.Device ID: " + resp.DID + "MQTT User: " + resp.MU + "MQTT Password: " + resp.MP + "Blockchain User: " + resp.BU + "Blockchain Pass: " + resp.BP + "App ID: " + resp.AppID + "App Key: " + resp.AppKey + " " + resp.Message);
+ $('#responsive-modal').modal('show');
+ Logging.logMessage("Core", "Forms", "Device ID #" + resp.DID + " created!");
+ break;
+ default:
+ msg = "ALL Create Failed: " + resp.Message
+ Logging.logMessage("Core", "ALL", msg);
+ $('.modal-title').text('ALL Classifier Devices');
+ $('.modal-body').text(msg);
+ $('#responsive-modal').modal('show');
+ break;
+ }
+ });
+ },
+ Update: function() {
+ $.post(window.location.href, $("#all_classifier_update").serialize(), function(resp) {
+ console.log(resp)
+ var resp = jQuery.parseJSON(resp);
+ switch (resp.Response) {
+ case "OK":
+ var fjson = JSON.stringify(resp.Schema, null, '\t');
+ window.parent.$('#schema').html(fjson);
+ Logging.logMessage("Core", "Forms", "Device Update OK");
+ $('.modal-title').text('ALL Classifier Devices');
+ $('.modal-body').text(resp.Message);
+ $('#responsive-modal').modal('show');
+ break;
+ default:
+ msg = "ALL Update Failed: " + resp.Message
+ Logging.logMessage("Core", "ALL", msg);
+ $('.modal-title').text('ALL Classifier Devices');
+ $('.modal-body').text(msg);
+ $('#responsive-modal').modal('show');
+ break;
+ }
+ });
+ },
deleteData: function() {
$.post(window.location.href, { "deleteData": 1 }, function(resp) {
- console.log(resp)
var resp = jQuery.parseJSON(resp);
switch (resp.Response) {
case "OK":
$('#dataBlock').empty();
- $('#dataBlock').html("
Please upload your Acute Lymphoblastic Leukemia Image Database for Image Processing Dataset data.
");
+ $('#dataBlock').html("Please upload your test dataset.
");
break;
default:
break;
@@ -38,6 +81,9 @@ var ALL = {
$('#dataBlock').html(resp.Data);
ALL.setOpacity();
Logging.logMessage("Core", "Forms", resp.Message);
+ $('.modal-title').text('Data Upload OK');
+ $('.modal-body').text(resp.Message);
+ $('#responsive-modal').modal('show');
} else {
Logging.logMessage("Core", "Forms", resp.Message);
$('.modal-title').text('Data Upload Failed');
@@ -53,7 +99,6 @@ var ALL = {
});
},
setOpacity: function() {
-
$('.classify').css("opacity", "1.0");
$('.classify').hover(function() {
$(this).stop().animate({ opacity: 0.2 }, "fast");
@@ -64,7 +109,7 @@ var ALL = {
},
classify: function(im) {
- $('#imageView').html(" ");
+ $('#imageView').html(" ");
$("#imName").text(im);
var classification = '';
$("#imClass").html("Diagnosis: WAITING FOR RESPONSE");
@@ -73,9 +118,6 @@ var ALL = {
var resp = jQuery.parseJSON(resp);
switch (resp.Response) {
case "OK":
- console.log(im);
- console.log(im.includes("_0"));
- console.log(resp.Diagnosis);
if (im.includes("_0") && resp.Diagnosis == "Negative") {
classification = "True Negative";
} else if (im.includes("_0") && resp.Diagnosis == "Positive") {
@@ -86,6 +128,11 @@ var ALL = {
classification = "False Negative";
}
$("#imClass").html("Diagnosis: " + resp.Diagnosis);
+ if (resp.Confidence) {
+ $("#imConf").html("Confidence: " + resp.Confidence);
+ } else {
+ $("#imConf").hide();
+ }
$("#imResult").html("Result: " + classification);
break;
default:
@@ -97,6 +144,20 @@ var ALL = {
};
$(document).ready(function() {
+ $('#all_classifier').validator().on('submit', function(e) {
+ if (!e.isDefaultPrevented()) {
+ e.preventDefault();
+ ALL.Create();
+ }
+ });
+
+ $('#all_classifier_update').validator().on('submit', function(e) {
+ if (!e.isDefaultPrevented()) {
+ e.preventDefault();
+ ALL.Update();
+ }
+ });
+
$("#GeniSysAI").on("click", "#uploadData", function(e) {
e.preventDefault();
$('#dataup').trigger('click');
@@ -112,7 +173,4 @@ $(document).ready(function() {
ALL.classify($(this).attr("id"));
});
- ALL.setOpacity();
- ALL.prepareUploadForm();
-
});
\ No newline at end of file
diff --git a/Root/var/www/html/AI/ALL/Classes/ALL.php b/Root/var/www/html/AI/ALL/Classes/ALL.php
new file mode 100644
index 0000000..0e851b4
--- /dev/null
+++ b/Root/var/www/html/AI/ALL/Classes/ALL.php
@@ -0,0 +1,1687 @@
+_GeniSys = $_GeniSys;
+ $this->bcc = $this->getBlockchainConf();
+ $this->web3 = $this->blockchainConnection();
+ $this->contract = new Contract($this->web3->provider, $this->bcc["abi"]);
+ $this->icontract = new Contract($this->web3->provider, $this->bcc["iabi"]);
+ $this->checkBlockchainPermissions();
+ endif;
+ $this->cb = $this->getContextBrokerConf();
+ }
+
+ public function setClassifierConfs()
+ {
+ $TId = filter_input(INPUT_GET, 'device', FILTER_SANITIZE_NUMBER_INT);
+ $Model = $this->getModel($TId);
+
+ $this->dataDir = "Data/" . $Model["context"]["Data"]["dataset"]["folder"] . "/";
+ $this->dataDirFull = "/fserver/var/www/html/AI/AI//";
+ $this->dataFiles = $this->dataDir . "*.jpg";
+ $this->allowedFiles = ["jpg","JPG"];
+ $this->api = $this->_GeniSys->_helpers->oDecrypt($this->_GeniSys->_confs["domainString"])."/AI/AI/" . $Model["context"]["Data"]["proxy"]["endpoint"] . "/Inference";
+ }
+
+ public function getContextBrokerConf()
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM contextbroker
+ ");
+ $pdoQuery->execute();
+ $response=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+ return $response;
+ }
+
+ private function createContextHeaders()
+ {
+ $basicAuth = $_SESSION["GeniSysAI"]["User"] . ":" . $this->_GeniSys->_helpers->oDecrypt($_SESSION["GeniSysAI"]["Pass"]);
+ $basicAuth = base64_encode($basicAuth);
+
+ return [
+ "Content-Type: application/json",
+ 'Authorization: Basic '. $basicAuth
+ ];
+ }
+
+ private function contextBrokerRequest($method, $endpoint, $headers, $json)
+ {
+ $path = $this->_GeniSys->_helpers->oDecrypt($this->_GeniSys->_confs["domainString"]) . "/" . $this->cb["url"] . "/" . $endpoint;
+
+ if($method == "GET"):
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ curl_setopt($ch, CURLOPT_HEADER, 1);
+ curl_setopt($ch, CURLOPT_URL, $path);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ $response = curl_exec($ch);
+ $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
+ $header = substr($response, 0, $header_size);
+ $body = substr($response, $header_size);
+ curl_close($ch);
+ elseif($method == "POST"):
+ $ch = curl_init($path);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ curl_setopt($ch, CURLOPT_HEADER, 1);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
+ $response = curl_exec($ch);
+ $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
+ $header = substr($response, 0, $header_size);
+ $body = substr($response, $header_size);
+ curl_close($ch);
+ elseif($method == "PATCH"):
+ $ch = curl_init($path);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ curl_setopt($ch, CURLOPT_HEADER, 1);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
+ $response = curl_exec($ch);
+ $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
+ $header = substr($response, 0, $header_size);
+ $body = substr($response, $header_size);
+ curl_close($ch);
+ endif;
+
+ return $body;
+ }
+
+ public function getBlockchainConf()
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT blockchain.*,
+ contracts.contract,
+ contracts.abi,
+ icontracts.contract as icontract,
+ icontracts.abi as iabi
+ FROM blockchain blockchain
+ INNER JOIN contracts contracts
+ ON contracts.id = blockchain.dc
+ INNER JOIN contracts icontracts
+ ON icontracts.id = blockchain.ic
+ ");
+ $pdoQuery->execute();
+ $response=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+ return $response;
+ }
+
+ private function blockchainConnection()
+ {
+ if(isSet($_SESSION["GeniSysAI"]["Active"])):
+ $web3 = new Web3($this->_GeniSys->_helpers->oDecrypt($this->_GeniSys->_confs["domainString"]) . "/Blockchain/API/", 30, $_SESSION["GeniSysAI"]["User"], $this->_GeniSys->_helpers->oDecrypt($_SESSION["GeniSysAI"]["Pass"]));
+ return $web3;
+ endif;
+ }
+
+ private function checkBlockchainPermissions()
+ {
+ $allowed = "";
+ $errr = "";
+ $this->contract->at($this->_GeniSys->_helpers->oDecrypt($this->bcc["contract"]))->call("identifierAllowed", "User", $_SESSION["GeniSysAI"]["Identifier"], ["from" => $_SESSION["GeniSysAI"]["BC"]["BCUser"]], function ($err, $resp) use (&$allowed, &$errr) {
+ if ($err !== null) {
+ $allowed = "FAILED";
+ $errr = $err;
+ return;
+ }
+ $allowed = $resp;
+ });
+ if(!$allowed):
+ header('Location: /Logout');
+ endif;
+ }
+
+ private function unlockBlockchainAccount()
+ {
+ $response = "";
+ $personal = $this->web3->personal;
+ $personal->unlockAccount($_SESSION["GeniSysAI"]["BC"]["BCUser"], $this->_GeniSys->_helpers->oDecrypt($_SESSION["GeniSysAI"]["BC"]["BCPass"]), function ($err, $unlocked) use (&$response) {
+ if ($err !== null) {
+ $response = "FAILED! " . $err;
+ return;
+ }
+ if ($unlocked) {
+ $response = "OK";
+ } else {
+ $response = "FAILED";
+ }
+ });
+
+ return $response;
+ }
+
+ private function lockBlockchainAccount()
+ {
+ $response = "";
+ $personal = $this->web3->personal;
+ $personal->lockAccount($_SESSION["GeniSysAI"]["BC"]["BCUser"], function ($err, $unlocked) use (&$response) {
+ if ($err !== null) {
+ $response = "FAILED! " . $err;
+ return;
+ }
+ if ($unlocked) {
+ $response = "OK";
+ } else {
+ $response = "FAILED";
+ }
+ });
+
+ return $response;
+ }
+
+ private function createBlockchainUser($pass)
+ {
+ $newAccount = "";
+ $personal = $this->web3->personal;
+ $personal->newAccount($pass, function ($err, $account) use (&$newAccount) {
+ if ($err !== null) {
+ $newAccount = "FAILED!";
+ return;
+ }
+ $newAccount = $account;
+ });
+
+ return $newAccount;
+ }
+
+ private function getBlockchainBalance()
+ {
+ $nbalance = "";
+ $this->web3->eth->getBalance($_SESSION["GeniSysAI"]["BC"]["BCUser"], function ($err, $balance) use (&$nbalance) {
+ if ($err !== null) {
+ $response = "FAILED! " . $err;
+ return;
+ }
+ $nbalance = $balance->toString();
+ });
+
+ return Utils::fromWei($nbalance, 'ether')[0];
+ }
+
+ private function addAmqpUser($username, $key)
+ {
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO amqpu (
+ `username`,
+ `pw`
+ ) VALUES (
+ :username,
+ :pw
+ )
+ ");
+ $query->execute([
+ ':username' => $username,
+ ':pw' => $this->_GeniSys->_helpers->oEncrypt($key)
+ ]);
+ $amid = $this->_GeniSys->_secCon->lastInsertId();
+ return $amid;
+ }
+
+ private function addAmqpUserVh($uid, $vhost)
+ {
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO amqpvh (
+ `uid`,
+ `vhost`
+ ) VALUES (
+ :uid,
+ :vhost
+ )
+ ");
+ $query->execute([
+ ':uid' => $uid,
+ ':vhost' => $vhost
+ ]);
+ }
+
+ private function addAmqpVhPerm($uid, $vhost, $rtype, $rname, $permission)
+ {
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO amqpvhr (
+ `uid`,
+ `vhost`,
+ `rtype`,
+ `rname`,
+ `permission`
+ ) VALUES (
+ :uid,
+ :vhost,
+ :rtype,
+ :rname,
+ :permission
+ )
+ ");
+ $query->execute([
+ ':uid' => $uid,
+ ':vhost' => $vhost,
+ ':rtype' => $rtype,
+ ':rname' => $rname,
+ ':permission' => $permission
+ ]);
+ }
+
+ private function addAmqpVhTopic($uid, $vhost, $rtype, $rname, $permission, $rkey)
+ {
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO amqpvhrt (
+ `uid`,
+ `vhost`,
+ `rtype`,
+ `rname`,
+ `permission`,
+ `rkey`
+ ) VALUES (
+ :uid,
+ :vhost,
+ :rtype,
+ :rname,
+ :permission,
+ :rkey
+ )
+ ");
+ $query->execute([
+ ':uid' => $uid,
+ ':vhost' => $vhost,
+ ':rtype' => $rtype,
+ ':rname' => $rname,
+ ':permission' => $permission,
+ ':rkey' => $rkey
+ ]);
+ }
+
+ private function storeBlockchainTransaction($action, $hash, $device = 0, $application = 0)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO transactions (
+ `uid`,
+ `did`,
+ `aid`,
+ `action`,
+ `hash`,
+ `time`
+ ) VALUES (
+ :uid,
+ :did,
+ :aid,
+ :action,
+ :hash,
+ :time
+ )
+ ");
+ $pdoQuery->execute([
+ ":uid" => $_SESSION["GeniSysAI"]["Uid"],
+ ":did" => $device,
+ ":aid" => $application,
+ ":action" => $action,
+ ':hash' => $this->_GeniSys->_helpers->oEncrypt($hash),
+ ":time" => time()
+ ]);
+ $txid = $this->_GeniSys->_secCon->lastInsertId();
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ return $txid;
+ }
+
+ private function storeUserHistory($action, $hash, $location = 0, $zone = 0, $device = 0, $sensor = 0, $application = 0)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO history (
+ `uid`,
+ `tlid`,
+ `tzid`,
+ `tdid`,
+ `tsid`,
+ `taid`,
+ `action`,
+ `hash`,
+ `time`
+ ) VALUES (
+ :uid,
+ :tlid,
+ :tzid,
+ :tdid,
+ :tsid,
+ :taid,
+ :action,
+ :hash,
+ :time
+ )
+ ");
+ $pdoQuery->execute([
+ ":uid" => $_SESSION["GeniSysAI"]["Uid"],
+ ":tlid" => $location,
+ ":tzid" => $zone,
+ ":tdid" => $device,
+ ":tsid" => $sensor,
+ ":taid" => $application,
+ ":action" => $action,
+ ":hash" => $hash,
+ ":time" => time()
+ ]);
+ $txid = $this->_GeniSys->_secCon->lastInsertId();
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ return $txid;
+ }
+
+ public function checkLocation($lid)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT id
+ FROM mqttl
+ WHERE id = :id
+ ");
+ $pdoQuery->execute([
+ ":id" => $lid
+ ]);
+ $location=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($location["id"]):
+ return True;
+ else:
+ return False;
+ endif;
+ }
+
+ public function getLocation($id, $attrs = Null)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM mqttl
+ WHERE id = :id
+ ");
+ $pdoQuery->execute([
+ ":id" => $id
+ ]);
+ $location=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($attrs):
+ $attrs="&attrs=" . $attrs;
+ endif;
+
+ $location["context"] = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "/" . $location["pub"] . "?type=Location" . $attrs, $this->createContextHeaders(), []), true);
+ return $location;
+ }
+
+ public function checkZone($zid)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT id
+ FROM mqttlz
+ WHERE id = :id
+ ");
+ $pdoQuery->execute([
+ ":id" => $zid
+ ]);
+ $location=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($location["id"]):
+ return True;
+ else:
+ return False;
+ endif;
+ }
+
+ public function getZone($id, $attrs = Null)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM mqttlz
+ WHERE id = :id
+ ORDER BY id DESC
+ ");
+ $pdoQuery->execute([
+ ":id" => $id
+ ]);
+ $zone=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($attrs):
+ $attrs="&attrs=" . $attrs;
+ endif;
+
+ $zone["context"] = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "/" . $zone["pub"] . "?type=Zone" . $attrs, $this->createContextHeaders(), []), true);
+ return $zone;
+ }
+
+ public function getDevices($limit = 0)
+ {
+ $limiter = "";
+ if($limit != 0):
+ $limiter = "&limit=" . $limit;
+ endif;
+
+ $devices = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "?type=Device&category=ALLClassifier".$limiter, $this->createContextHeaders(), []), true);
+ return $devices;
+ }
+
+ public function getDevice($id, $attrs = Null)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM mqttld
+ WHERE id = :id
+ ORDER BY id DESC
+ ");
+ $pdoQuery->execute([
+ ":id" => $id
+ ]);
+ $device=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($attrs):
+ $attrs="&attrs=" . $attrs;
+ endif;
+
+ $device["context"] = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "/" . $device["apub"] . "?type=Device" . $attrs, $this->createContextHeaders(), []), true);
+ return $device;
+ }
+
+ public function getThing($id, $attrs = Null)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM things
+ WHERE id = :id
+ ");
+ $pdoQuery->execute([
+ ":id" => $id
+ ]);
+ $thing=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($attrs):
+ $attrs="&attrs=" . $attrs;
+ endif;
+
+ $thing["context"] = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "/" . $thing["pub"] . "?type=Thing" . $attrs, $this->createContextHeaders(), []), true);
+ return $thing;
+ }
+
+ public function getModel($id, $attrs = Null)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM models
+ WHERE id = :id
+ ORDER BY id DESC
+ ");
+ $pdoQuery->execute([
+ ":id" => $id
+ ]);
+ $model=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($attrs):
+ $attrs="&attrs=" . $attrs;
+ endif;
+
+ $device["context"] = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "/" . $model["pub"] . "?type=Model" . $attrs, $this->createContextHeaders(), []), true);
+ return $device;
+ }
+
+ public function createDevice()
+ {
+ if(!filter_input(INPUT_POST, "lid", FILTER_SANITIZE_NUMBER_INT)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Location ID is required"
+ ];
+ endif;
+
+ if(!$this->checkLocation(filter_input(INPUT_POST, "lid", FILTER_SANITIZE_NUMBER_INT))):
+ return [
+ "Response"=> "Failed",
+ "Message" => "iotJumpWay location does not exist"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "zid", FILTER_SANITIZE_NUMBER_INT)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Zone ID is required"
+ ];
+ endif;
+
+ if(!$this->checkZone(filter_input(INPUT_POST, "zid", FILTER_SANITIZE_NUMBER_INT))):
+ return [
+ "Response"=> "Failed",
+ "Message" => "iotJumpWay zone does not exist"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "category", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Category is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "ctype", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Model type is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "agent", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "IoT Agent is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "name", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "description", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "deviceName", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Hardware device name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "deviceManufacturer", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Hardware device manufacturer is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "deviceModel", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Hardware device model is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osName", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osManufacturer", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system manufacturer is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osVersion", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system version is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "agent", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "IoT Agent is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "coordinates", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Coordinates entity is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "ip", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "IP is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "mac", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "MAC is required"
+ ];
+ endif;
+
+ if(!count($_POST["protocols"])):
+ return [
+ "Response"=> "Failed",
+ "Message" => "At least one M2M protocol is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "datasetUsed", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Dataset used is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "datasetLink", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Dataset link is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "datasetAuthor", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Dataset author is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "datasetFolder", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Dataset folder is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "relatedPaper", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Related paper is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "sport", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Device server port is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "endpoint", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Proxy endpoint is required"
+ ];
+ endif;
+
+ $unlocked = $this->unlockBlockchainAccount();
+
+ if($unlocked == "FAILED"):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Unlocking HIAS Blockhain Account Failed!"
+ ];
+ endif;
+
+ $mqttUser = $this->_GeniSys->_helpers->generate_uuid();
+ $mqttPass = $this->_GeniSys->_helpers->password();
+ $mqttHash = create_hash($mqttPass);
+
+ $pubKey = $this->_GeniSys->_helpers->generate_uuid();
+ $privKey = $this->_GeniSys->_helpers->generateKey(32);
+ $privKeyHash = $this->_GeniSys->_helpers->createPasswordHash($privKey);
+
+ $amqppubKey = $this->_GeniSys->_helpers->generate_uuid();
+ $amqpprvKey = $this->_GeniSys->_helpers->generateKey(32);
+ $amqpKeyHash = $this->_GeniSys->_helpers->createPasswordHash($amqpprvKey);
+
+ $bcPass = $this->_GeniSys->_helpers->password();
+
+ $lid = filter_input(INPUT_POST, 'lid', FILTER_SANITIZE_NUMBER_INT);
+ $location = $this->getLocation($lid);
+
+ $zid = filter_input(INPUT_POST, 'zid', FILTER_SANITIZE_NUMBER_INT);
+ $zone = $this->getZone($zid);
+
+ $ip = filter_input(INPUT_POST, "ip", FILTER_SANITIZE_STRING);
+ $mac = filter_input(INPUT_POST, "mac", FILTER_SANITIZE_STRING);
+ $bluetooth = filter_input(INPUT_POST, "bluetooth", FILTER_SANITIZE_STRING);
+ $name = filter_input(INPUT_POST, "name", FILTER_SANITIZE_STRING);
+ $coords = explode(",", filter_input(INPUT_POST, "coordinates", FILTER_SANITIZE_STRING));
+
+ mkdir("Data/" . filter_input(INPUT_POST, "datasetFolder", FILTER_SANITIZE_STRING), 0777, true);
+
+ $protocols = [];
+ foreach($_POST["protocols"] AS $key => $value):
+ $protocols[] = $value;
+ endforeach;
+
+ $models = [];
+ if(isSet($_POST["ai"])):
+ foreach($_POST["ai"] AS $key => $value):
+ $model = $this->getModel($value)["context"]["Data"];
+ $mname = $model["name"]["value"];
+ unset($model["id"]);
+ unset($model["type"]);
+ unset($model["mid"]);
+ unset($model["name"]);
+ unset($model["description"]);
+ unset($model["network"]);
+ unset($model["language"]);
+ unset($model["framework"]);
+ unset($model["toolkit"]);
+ unset($model["dateCreated"]);
+ unset($model["dateModified"]);
+ $models[$mname] = $model;
+ endforeach;
+ endif;
+
+ $sensors = [];
+ if(isSet($_POST["sensors"])):
+ foreach($_POST["sensors"] AS $key => $value):
+ $sensor = $this->getThing($value)["context"]["Data"];
+ unset($sensor["id"]);
+ unset($sensor["type"]);
+ unset($sensor["category"]);
+ unset($sensor["description"]);
+ unset($sensor["thing"]);
+ unset($sensor["properties"]["image"]);
+ unset($sensor["dateCreated"]);
+ unset($sensor["dateModified"]);
+ $sensors[] = $sensor;
+ endforeach;
+ endif;
+
+ $actuators = [];
+ if(isSet($_POST["actuators"])):
+ foreach($_POST["actuators"] AS $key => $value):
+ $actuator = $this->getThing($value)["context"]["Data"];
+ unset($actuator["id"]);
+ unset($actuator["type"]);
+ unset($actuator["category"]);
+ unset($actuator["description"]);
+ unset($actuator["thing"]);
+ unset($actuator["properties"]["image"]);
+ unset($actuator["dateCreated"]);
+ unset($actuator["dateModeified"]);
+ $actuators[] = $actuator;
+ endforeach;
+ endif;
+
+ $newBcUser = $this->createBlockchainUser($bcPass);
+
+ if($newBcUser == "FAILED"):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Creating New HIAS Blockhain Account Failed!"
+ ];
+ endif;
+
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO mqttld (
+ `apub`
+ ) VALUES (
+ :apub
+ )
+ ");
+ $query->execute([
+ ':apub' => $pubKey
+ ]);
+ $did = $this->_GeniSys->_secCon->lastInsertId();
+
+ $data = [
+ "id" => $pubKey,
+ "type" => "Device",
+ "category" => [
+ "value" => [filter_input(INPUT_POST, "category", FILTER_SANITIZE_STRING)]
+ ],
+ "name" => [
+ "value" => $name
+ ],
+ "description" => [
+ "value" => filter_input(INPUT_POST, "description", FILTER_SANITIZE_STRING)
+ ],
+ "lid" => [
+ "value" => $lid,
+ "entity" => $location["context"]["Data"]["id"]
+ ],
+ "zid" => [
+ "value" => $zid,
+ "entity" => $zone["context"]["Data"]["id"]
+ ],
+ "did" => [
+ "value" => $did
+ ],
+ "location" => [
+ "type" => "geo:json",
+ "value" => [
+ "type" => "Point",
+ "coordinates" => [floatval($coords[0]), floatval($coords[1])]
+ ]
+ ],
+ "agent" => [
+ "url" => filter_input(INPUT_POST, "agent", FILTER_SANITIZE_STRING)
+ ],
+ "paper" => [
+ "title" => filter_input(INPUT_POST, "relatedPaper", FILTER_SANITIZE_STRING),
+ "author" => filter_input(INPUT_POST, "relatedPaperAuthor", FILTER_SANITIZE_STRING),
+ "doi" => filter_input(INPUT_POST, "relatedPaperDOI", FILTER_SANITIZE_STRING),
+ "link" => filter_input(INPUT_POST, "relatedPaperLink", FILTER_SANITIZE_STRING)
+ ],
+ "dataset" => [
+ "name" => filter_input(INPUT_POST, "datasetUsed", FILTER_SANITIZE_STRING),
+ "author" => filter_input(INPUT_POST, "datasetAuthor", FILTER_SANITIZE_STRING),
+ "url" => filter_input(INPUT_POST, "datasetLink", FILTER_SANITIZE_STRING),
+ "folder" => filter_input(INPUT_POST, "datasetFolder", FILTER_SANITIZE_STRING)
+ ],
+ "device" => [
+ "type" => filter_input(INPUT_POST, "ctype", FILTER_SANITIZE_STRING),
+ "name" => filter_input(INPUT_POST, "deviceName", FILTER_SANITIZE_STRING),
+ "manufacturer" => filter_input(INPUT_POST, "deviceManufacturer", FILTER_SANITIZE_STRING),
+ "model" => filter_input(INPUT_POST, "deviceModel", FILTER_SANITIZE_STRING)
+ ],
+ "proxy" => [
+ "endpoint" => filter_input(INPUT_POST, "endpoint", FILTER_SANITIZE_STRING)
+ ],
+ "stream" => [
+ "port" => filter_input(INPUT_POST, "sport", FILTER_SANITIZE_STRING),
+ "file" => ""
+ ],
+ "socket" => [
+ "port" => ""
+ ],
+ "os" => [
+ "name" => filter_input(INPUT_POST, "osName", FILTER_SANITIZE_STRING),
+ "manufacturer" => filter_input(INPUT_POST, "osManufacturer", FILTER_SANITIZE_STRING),
+ "version" => filter_input(INPUT_POST, "osVersion", FILTER_SANITIZE_STRING)
+ ],
+ "protocols" => $protocols,
+ "status" => [
+ "value" => "OFFLINE",
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "keys" => [
+ "public" => $pubKey,
+ "private" => $this->_GeniSys->_helpers->oEncrypt($privKeyHash),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "blockchain" => [
+ "address" => $newBcUser,
+ "password" => $this->_GeniSys->_helpers->oEncrypt($bcPass)
+ ],
+ "mqtt" => [
+ "username" => $this->_GeniSys->_helpers->oEncrypt($mqttUser),
+ "password" => $this->_GeniSys->_helpers->oEncrypt($mqttPass),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "coap" => [
+ "username" => "",
+ "password" => ""
+ ],
+ "amqp" => [
+ "username" => $this->_GeniSys->_helpers->oEncrypt($amqppubKey),
+ "password" => $this->_GeniSys->_helpers->oEncrypt($amqpprvKey),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "batteryLevel" => [
+ "value" => 0.00
+ ],
+ "cpuUsage" => [
+ "value" => 0.00
+ ],
+ "memoryUsage" => [
+ "value" => 0.00
+ ],
+ "hddUsage" => [
+ "value" => 0.00
+ ],
+ "temperature" => [
+ "value" => 0.00
+ ],
+ "ip" => [
+ "value" => $this->_GeniSys->_helpers->oEncrypt($ip),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "mac" => [
+ "value" => $this->_GeniSys->_helpers->oEncrypt($mac),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "bluetooth" => [
+ "address" => $bluetooth ? $this->_GeniSys->_helpers->oEncrypt($bluetooth) : "",
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "ai" => $models,
+ "sensors" => $sensors,
+ "actuators" => $actuators,
+ "dateCreated" => [
+ "type" => "DateTime",
+ "value" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "dateFirstUsed" => [
+ "type" => "DateTime",
+ "value" => ""
+ ],
+ "dateModified" => [
+ "type" => "DateTime",
+ "value" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ]
+ ];
+
+ $response = json_decode($this->contextBrokerRequest("POST", $this->cb["entities_url"] . "?type=Device", $this->createContextHeaders(), json_encode($data)), true);
+
+ if($response["Response"]=="OK"):
+
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO mqttu (
+ `lid`,
+ `zid`,
+ `did`,
+ `uname`,
+ `pw`
+ ) VALUES (
+ :lid,
+ :zid,
+ :did,
+ :uname,
+ :pw
+ )
+ ");
+ $query->execute([
+ ':lid' => $lid,
+ ':zid' => $zid,
+ ':did' => $did,
+ ':uname' => $mqttUser,
+ ':pw' => $mqttHash
+ ]);
+
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO mqttua (
+ `lid`,
+ `zid`,
+ `did`,
+ `username`,
+ `topic`,
+ `rw`
+ ) VALUES (
+ :lid,
+ :zid,
+ :did,
+ :username,
+ :topic,
+ :rw
+ )
+ ");
+ $query->execute(array(
+ ':lid' => $lid,
+ ':zid' => $zid,
+ ':did' => $did,
+ ':username' => $mqttUser,
+ ':topic' => $location["context"]["Data"]["id"] . "/Devices/" . $zone["context"]["Data"]["id"] . "/" . $pubKey . "/#",
+ ':rw' => 4
+ ));
+
+ $amid = $this->addAmqpUser($amqppubKey, $amqpKeyHash);
+ $this->addAmqpUserVh($amid, "iotJumpWay");
+ $this->addAmqpVhPerm($amid, "iotJumpWay", "exchange", "Core", "read");
+ $this->addAmqpVhPerm($amid, "iotJumpWay", "exchange", "Core", "write");
+ $this->addAmqpVhPerm($amid, "iotJumpWay", "queue", "Life", "read");
+ $this->addAmqpVhPerm($amid, "iotJumpWay", "queue", "Life", "write");
+ $this->addAmqpVhPerm($amid, "iotJumpWay", "queue", "Statuses", "read");
+ $this->addAmqpVhPerm($amid, "iotJumpWay", "queue", "Statuses", "write");
+ $this->addAmqpVhTopic($amid, "iotJumpWay", "topic", "Core", "read", "Life");
+ $this->addAmqpVhTopic($amid, "iotJumpWay", "topic", "Core", "write", "Life");
+ $this->addAmqpVhTopic($amid, "iotJumpWay", "topic", "Core", "read", "Statuses");
+ $this->addAmqpVhTopic($amid, "iotJumpWay", "topic", "Core", "write", "Statuses");
+
+ $hash = "";
+ $msg = "";
+ $actionMsg = "";
+ $balanceMessage = "";
+ $this->contract->at($this->_GeniSys->_helpers->oDecrypt($this->bcc["contract"]))->send("registerDevice", $pubKey, $newBcUser, $lid, $zid, $did, $name, $_SESSION["GeniSysAI"]["Uid"], time(), ["from" => $_SESSION["GeniSysAI"]["BC"]["BCUser"]], function ($err, $resp) use (&$hash, &$msg) {
+ if ($err !== null) {
+ $hash = "FAILED";
+ $msg = $err;
+ return;
+ }
+ $hash = $resp;
+ });
+
+ if($hash == "FAILED"):
+ $actionMsg = " HIAS Blockchain registerDevice failed!\n" . $msg;
+ else:
+ $txid = $this->storeBlockchainTransaction("Register Device", $hash, $did);
+ $this->storeUserHistory("Register Device", $txid, $lid, $zid, $did);
+ $balance = $this->getBlockchainBalance();
+ $actionMsg = " HIAS Blockchain registerDevice OK!\n";
+ $balanceMessage = " You were rewarded for this action! Your balance is now: " . $balance . " HIAS Ether!";
+ endif;
+
+ $this->icontract->at($this->_GeniSys->_helpers->oDecrypt($this->bcc["icontract"]))->send("registerAuthorized", $newBcUser, ["from" => $_SESSION["GeniSysAI"]["BC"]["BCUser"]], function ($err, $resp) use (&$hash, &$msg) {
+ if ($err !== null) {
+ $hash = "FAILED";
+ $msg = $err;
+ return;
+ }
+ $hash = $resp;
+ });
+
+ if($hash == "FAILED"):
+ $actionMsg .= " HIAS Blockchain registerAuthorized failed! " . $msg;
+ else:
+ $txid = $this->storeBlockchainTransaction("iotJumpWay Register Authorized", $hash, $did);
+ $this->storeUserHistory("Register Authorized", $txid, $lid, $zid, $did);
+ $balance = $this->getBlockchainBalance();
+ $actionMsg .= " HIAS Blockchain registerAuthorized OK!\n";
+ $balanceMessage = " You were rewarded for this action! Your balance is now: " . $balance . " HIAS Ether!";
+ endif;
+
+ return [
+ "Response"=> "OK",
+ "Message" => "Device created!" . $actionMsg . $balanceMessage,
+ "LID" => filter_input(INPUT_POST, "lid", FILTER_SANITIZE_NUMBER_INT),
+ "ZID" => filter_input(INPUT_POST, "zid", FILTER_SANITIZE_NUMBER_INT),
+ "DID" => $did,
+ "MU" => $mqttUser,
+ "MP" => $mqttPass,
+ "BU" => $newBcUser,
+ "BP" => $bcPass,
+ "AppID" => $pubKey,
+ "AppKey" => $privKey
+ ];
+ else:
+ return [
+ "Response"=> "FAILED",
+ "Message" => "Device creating failed"
+ ];
+ endif;
+ }
+
+ public function updateDevice()
+ {
+ if(!filter_input(INPUT_POST, "lid", FILTER_SANITIZE_NUMBER_INT)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Location ID is required"
+ ];
+ endif;
+
+ if(!$this->checkLocation(filter_input(INPUT_POST, "lid", FILTER_SANITIZE_NUMBER_INT))):
+ return [
+ "Response"=> "Failed",
+ "Message" => "iotJumpWay location does not exist"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "zid", FILTER_SANITIZE_NUMBER_INT)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Zone ID is required"
+ ];
+ endif;
+
+ if(!$this->checkZone(filter_input(INPUT_POST, "zid", FILTER_SANITIZE_NUMBER_INT))):
+ return [
+ "Response"=> "Failed",
+ "Message" => "iotJumpWay zone does not exist"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "category", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Category is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "ctype", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Model type is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "agent", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "IoT Agent is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "name", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "description", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "deviceName", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Hardware device name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "deviceManufacturer", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Hardware device manufacturer is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "deviceModel", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Hardware device model is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osName", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osManufacturer", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system manufacturer is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osVersion", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system version is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "agent", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "IoT Agent is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "coordinates", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Coordinates entity is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "ip", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "IP is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "mac", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "MAC is required"
+ ];
+ endif;
+
+ if(!count($_POST["protocols"])):
+ return [
+ "Response"=> "Failed",
+ "Message" => "At least one M2M protocol is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "datasetUsed", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Dataset used is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "datasetLink", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Dataset link is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "datasetAuthor", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Dataset author is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "datasetFolder", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Dataset folder is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "relatedPaper", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Related paper is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "sport", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Device server port is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "endpoint", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Proxy endpoint is required"
+ ];
+ endif;
+
+ $unlocked = $this->unlockBlockchainAccount();
+
+ if($unlocked == "FAILED"):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Unlocking HIAS Blockhain Account Failed!"
+ ];
+ endif;
+
+ $ip = filter_input(INPUT_POST, "ip", FILTER_SANITIZE_STRING);
+ $mac = filter_input(INPUT_POST, "mac", FILTER_SANITIZE_STRING);
+ $bluetooth = filter_input(INPUT_POST, "bluetooth", FILTER_SANITIZE_STRING);
+ $name = filter_input(INPUT_POST, "name", FILTER_SANITIZE_STRING);
+ $status = filter_input(INPUT_POST, "status", FILTER_SANITIZE_STRING);
+ $coords = explode(",", filter_input(INPUT_POST, "coordinates", FILTER_SANITIZE_STRING));
+
+ $did = filter_input(INPUT_GET, "device", FILTER_SANITIZE_NUMBER_INT);
+ $device = $this->getDevice($did);
+
+ $lid = filter_input(INPUT_POST, 'lid', FILTER_SANITIZE_NUMBER_INT);
+ $location = $this->getLocation($lid);
+
+ $zid = filter_input(INPUT_POST, 'zid', FILTER_SANITIZE_NUMBER_INT);
+ $zone = $this->getZone($zid);
+
+ $protocols = [];
+ foreach($_POST["protocols"] AS $key => $value):
+ $protocols[] = $value;
+ endforeach;
+
+ $models = [];
+ if(isSet($_POST["ai"])):
+ foreach($_POST["ai"] AS $key => $value):
+ $model = $this->getModel($value)["context"]["Data"];
+ $mname = $model["name"]["value"];
+ unset($model["id"]);
+ unset($model["type"]);
+ unset($model["mid"]);
+ unset($model["name"]);
+ unset($model["description"]);
+ unset($model["network"]);
+ unset($model["language"]);
+ unset($model["framework"]);
+ unset($model["toolkit"]);
+ unset($model["dateCreated"]);
+ unset($model["dateModified"]);
+ $models[$mname] = $model;
+ endforeach;
+ endif;
+
+ $sensors = [];
+ if(isSet($_POST["sensors"])):
+ foreach($_POST["sensors"] AS $key => $value):
+ $sensor = $this->getThing($value)["context"]["Data"];
+ unset($sensor["id"]);
+ unset($sensor["type"]);
+ unset($sensor["category"]);
+ unset($sensor["description"]);
+ unset($sensor["thing"]);
+ unset($sensor["properties"]["image"]);
+ unset($sensor["dateCreated"]);
+ unset($sensor["dateModified"]);
+ $sensors[] = $sensor;
+ endforeach;
+ endif;
+
+ $actuators = [];
+ if(isSet($_POST["actuators"])):
+ foreach($_POST["actuators"] AS $key => $value):
+ $actuator = $this->getThing($value)["context"]["Data"];
+ unset($actuator["id"]);
+ unset($actuator["type"]);
+ unset($actuator["category"]);
+ unset($actuator["description"]);
+ unset($actuator["thing"]);
+ unset($actuator["properties"]["image"]);
+ unset($actuator["dateCreated"]);
+ unset($actuator["dateModeified"]);
+ $actuators[] = $actuator;
+ endforeach;
+ endif;
+
+ if($device["context"]["Data"]["lid"]["value"] != $lid):
+ $query = $this->_GeniSys->_secCon->prepare("
+ UPDATE mqttu
+ SET lid = :lid
+ WHERE did = :did
+ ");
+ $query->execute([
+ ':lid' => $lid,
+ ':did' => $did
+ ]);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ $query = $this->_GeniSys->_secCon->prepare("
+ UPDATE mqttua
+ SET lid = :lid
+ WHERE did = :did
+ ");
+ $query->execute([
+ ':lid' => $lid,
+ ':did' => $did
+ ]);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ $query = $this->_GeniSys->_secCon->prepare("
+ UPDATE mqttua
+ SET topic = :topicN
+ WHERE did = :did
+ & topic = :topic
+ ");
+ $query->execute([
+ ':topicN' => $device["context"]["Data"]["lid"]["entity"] . "/ " . $device["context"]["Data"]["zid"]["entity"] . "/Devices/" . $device["context"]["Data"]["id"] . "/#",
+ ':did' => $did,
+ ':topic' => $location["context"]["Data"]["id"] . "/Devices/" . $zone["context"]["Data"]["id"] . "/Devices/" . $device["context"]["Data"]["id"] . "/#"
+ ]);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+ endif;
+
+ $data = [
+ "category" => [
+ "value" => [filter_input(INPUT_POST, "category", FILTER_SANITIZE_STRING)]
+ ],
+ "name" => [
+ "value" => $name
+ ],
+ "description" => [
+ "value" => filter_input(INPUT_POST, "description", FILTER_SANITIZE_STRING)
+ ],
+ "lid" => [
+ "value" => $lid,
+ "entity" => $location["context"]["Data"]["id"]
+ ],
+ "zid" => [
+ "value" => $zid,
+ "entity" => $zone["context"]["Data"]["id"]
+ ],
+ "location" => [
+ "type" => "geo:json",
+ "value" => [
+ "type" => "Point",
+ "coordinates" => [floatval($coords[0]), floatval($coords[1])]
+ ]
+ ],
+ "agent" => [
+ "url" => filter_input(INPUT_POST, "agent", FILTER_SANITIZE_STRING)
+ ],
+ "paper" => [
+ "title" => filter_input(INPUT_POST, "relatedPaper", FILTER_SANITIZE_STRING),
+ "author" => filter_input(INPUT_POST, "relatedPaperAuthor", FILTER_SANITIZE_STRING),
+ "doi" => filter_input(INPUT_POST, "relatedPaperDOI", FILTER_SANITIZE_STRING),
+ "link" => filter_input(INPUT_POST, "relatedPaperLink", FILTER_SANITIZE_STRING)
+ ],
+ "dataset" => [
+ "name" => filter_input(INPUT_POST, "datasetUsed", FILTER_SANITIZE_STRING),
+ "author" => filter_input(INPUT_POST, "datasetAuthor", FILTER_SANITIZE_STRING),
+ "url" => filter_input(INPUT_POST, "datasetLink", FILTER_SANITIZE_STRING),
+ "folder" => filter_input(INPUT_POST, "datasetFolder", FILTER_SANITIZE_STRING)
+ ],
+ "device" => [
+ "type" => filter_input(INPUT_POST, "ctype", FILTER_SANITIZE_STRING),
+ "name" => filter_input(INPUT_POST, "deviceName", FILTER_SANITIZE_STRING),
+ "manufacturer" => filter_input(INPUT_POST, "deviceManufacturer", FILTER_SANITIZE_STRING),
+ "model" => filter_input(INPUT_POST, "deviceModel", FILTER_SANITIZE_STRING)
+ ],
+ "proxy" => [
+ "endpoint" => filter_input(INPUT_POST, "endpoint", FILTER_SANITIZE_STRING)
+ ],
+ "stream" => [
+ "port" => filter_input(INPUT_POST, "sport", FILTER_SANITIZE_STRING),
+ "file" => ""
+ ],
+ "socket" => [
+ "port" => ""
+ ],
+ "os" => [
+ "name" => filter_input(INPUT_POST, "osName", FILTER_SANITIZE_STRING),
+ "manufacturer" => filter_input(INPUT_POST, "osManufacturer", FILTER_SANITIZE_STRING),
+ "version" => filter_input(INPUT_POST, "osVersion", FILTER_SANITIZE_STRING)
+ ],
+ "protocols" => $protocols,
+ "ip" => [
+ "value" => $this->_GeniSys->_helpers->oEncrypt($ip),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "mac" => [
+ "value" => $this->_GeniSys->_helpers->oEncrypt($mac),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "bluetooth" => [
+ "address" => $bluetooth ? $this->_GeniSys->_helpers->oEncrypt($bluetooth) : "",
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "ai" => $models,
+ "sensors" => $sensors,
+ "actuators" => $actuators,
+ "dateModified" => [
+ "type" => "DateTime",
+ "value" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ]
+ ];
+
+ $response = json_decode($this->contextBrokerRequest("PATCH", $this->cb["entities_url"] . "/" . $device["context"]["Data"]["id"] . "/attrs?type=Device", $this->createContextHeaders(), json_encode($data)), true);
+
+ if($response["Response"]=="OK"):
+
+ $hash = "";
+ $msg = "";
+ $this->contract->at($this->_GeniSys->_helpers->oDecrypt($this->bcc["contract"]))->send("updateDevice", $device["context"]["Data"]["id"], "Device", $lid, $zid, $did, $name, $device["context"]["Data"]["status"]["value"], time(), ["from" => $_SESSION["GeniSysAI"]["BC"]["BCUser"]], function ($err, $resp) use (&$hash, &$msg) {
+ if ($err !== null) {
+ $hash = "FAILED";
+ $msg = $err;
+ return;
+ }
+ $hash = $resp;
+ });
+
+ $balance = "";
+ $balanceMessage = "";
+ $actionMsg = "";
+ if($hash == "FAILED"):
+ $actionMsg = " HIAS Blockchain updateDevice failed! " . $msg;
+ else:
+ $txid = $this->storeBlockchainTransaction("Update Device", $hash, $did);
+ $this->storeUserHistory("Updated Device", $txid, $lid, $zid, $did);
+ $balance = $this->getBlockchainBalance();
+ $balanceMessage = " You were rewarded for this action! Your balance is now: " . $balance . " HIAS Ether!";
+ endif;
+
+ $device = $this->getDevice($did);
+
+ return [
+ "Response"=> "OK",
+ "Message" => "Device updated!" . $actionMsg . $balanceMessage,
+ "Schema" => $device["context"]["Data"]
+ ];
+ else:
+ return [
+ "Response"=> "Failed",
+ "Message" => "There was a problem updating this device context data!"
+ ];
+ endif;
+ }
+
+ public function deleteData()
+ {
+ $images = glob($this->dataFiles);
+ foreach( $images as $image ):
+ unlink($image);
+ endforeach;
+
+ return [
+ "Response" => "OK",
+ "Message" => "Deleted Acute Lymphoblastic Leukemia Image Database for Image Processing Dataset"
+ ];
+
+ }
+
+ public function uploadData()
+ {
+ $dataCells = '';
+ if(is_array($_FILES) && !empty($_FILES['alldata'])):
+ foreach($_FILES['alldata']['name'] as $key => $filename):
+ $file_name = explode(".", $filename);
+ if(in_array($file_name[1], $this->allowedFiles)):
+ $sourcePath = $_FILES["alldata"]["tmp_name"][$key];
+ $targetPath = $this->dataDir . $filename;
+ if(!move_uploaded_file($sourcePath, $targetPath)):
+ return [
+ "Response" => "FAILED",
+ "Message" => "Upload failed " . $targetPath
+ ];
+ endif;
+ else:
+ return [
+ "Response" => "FAILED",
+ "Message" => "Please upload jpg files"
+ ];
+ endif;
+ endforeach;
+
+ $images = glob($this->dataFiles);
+ $count = 1;
+ foreach($images as $image):
+ $dataCells .= "";
+ if($count%6 == 0):
+ $dataCells .= "
";
+ endif;
+ $count++;
+ endforeach;
+
+ else:
+ return [
+ "Response" => "FAILED",
+ "Message" => "You must upload some images (jpg)"
+ ];
+ endif;
+
+ return [
+ "Response" => "OK",
+ "Message" => "Data upload OK!",
+ "Data" => $dataCells
+ ];
+
+ }
+
+ public function classifyData()
+ {
+ $file = $this->dataDirFull . filter_input(INPUT_POST, "im", FILTER_SANITIZE_STRING);
+ $mime = mime_content_type($file);
+ $info = pathinfo($file);
+ $name = $info['basename'];
+ $toSend = new CURLFile($file, $mime, $name);
+
+ $headers = [
+ 'Authorization: Basic '. base64_encode($_SESSION["GeniSysAI"]["User"] . ":" . $this->_GeniSys->_helpers->oDecrypt($_SESSION["GeniSysAI"]["Pass"]))
+ ];
+
+ $ch = curl_init($this->api);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_POST, true);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, [
+ 'file'=> $toSend,
+ ]);
+
+ $resp = curl_exec($ch);
+
+ return json_decode($resp, true);
+
+ }
+
+ }
+
+ $ALL = new ALL($_GeniSys);
+
+ if(filter_input(INPUT_POST, "create_all_classifier", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($ALL->createDevice()));
+ endif;
+
+ if(filter_input(INPUT_POST, "update_all_classifier", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($ALL->updateDevice()));
+ endif;
+
+ if(filter_input(INPUT_POST, "reset_mqtt", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($ALL->resetMqtt()));
+ endif;
+
+ if(filter_input(INPUT_POST, "reset_key", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($ALL->resetDvcKey()));
+ endif;
+
+ if(filter_input(INPUT_POST, "get_tlife", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($ALL->getLife()));
+ endif;
+
+ if(filter_input(INPUT_POST, "deleteData", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($ALL->deleteData()));
+ endif;
+
+ if(filter_input(INPUT_POST, "uploadAllData", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($ALL->uploadData()));
+ endif;
+
+ if(filter_input(INPUT_POST, "classifyData", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($ALL->classifyData()));
+ endif;
diff --git a/Root/var/www/html/AI/ALL/Classify.php b/Root/var/www/html/AI/ALL/Classify.php
new file mode 100644
index 0000000..9377add
--- /dev/null
+++ b/Root/var/www/html/AI/ALL/Classify.php
@@ -0,0 +1,202 @@
+ "AI",
+ "SubPageID" => "AIALL"
+];
+
+include dirname(__FILE__) . '/../../../Classes/Core/init.php';
+include dirname(__FILE__) . '/../../../Classes/Core/GeniSys.php';
+include dirname(__FILE__) . '/../../iotJumpWay/Classes/iotJumpWay.php';
+include dirname(__FILE__) . '/../../AI/ALL/Classes/ALL.php';
+
+$_GeniSysAi->checkSession();
+
+$Locations = $iotJumpWay->getLocations();
+$Zones = $iotJumpWay->getZones();
+$Devices = $ALL->getDevices();
+
+$TId = filter_input(INPUT_GET, 'device', FILTER_SANITIZE_NUMBER_INT);
+$Device = $iotJumpWay->getDevice($TId);
+
+list($dev1On, $dev1Off) = $iotJumpWay->getStatusShow($Device["context"]["Data"]["status"]["value"]);
+
+$ALL->setClassifierConfs();
+
+?>
+
+
+
+
+
+
+
+
+
+ =$_GeniSys->_confs["meta_title"]; ?>
+ " />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
ALL Classifier #=$TId; ?>
+
+
+
+
+
+
+
+
+
+
+
+ dataFiles);
+ $count = 1;
+ if(count($images)):
+ foreach( $images as $image ):
+ echo "
";
+ if($count%6 == 0):
+ echo"
";
+ endif;
+ $count++;
+ endforeach;
+ else:
+ echo "
Please upload your test dataset.
";
+ endif;
+ ?>
+
+
+
+
+
+
+
+
+
+
+
+
Diagnosis Results
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Root/var/www/html/AI/ALL/Create.php b/Root/var/www/html/AI/ALL/Create.php
new file mode 100644
index 0000000..97d8503
--- /dev/null
+++ b/Root/var/www/html/AI/ALL/Create.php
@@ -0,0 +1,422 @@
+ "AI",
+ "SubPageID" => "AIALL"
+];
+
+include dirname(__FILE__) . '/../../../Classes/Core/init.php';
+include dirname(__FILE__) . '/../../../Classes/Core/GeniSys.php';
+include dirname(__FILE__) . '/../../iotJumpWay/Classes/iotJumpWay.php';
+include dirname(__FILE__) . '/../../AI/ALL/Classes/ALL.php';
+include dirname(__FILE__) . '/../../AI/Classes/AI.php';
+
+$_GeniSysAi->checkSession();
+
+$Zones = $iotJumpWay->getZones();
+$Devices = $iotJumpWay->getDevices();
+
+?>
+
+
+
+
+
+
+
+
+
=$_GeniSys->_confs["meta_title"]; ?>
+
" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Create ALL Classifier Device
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Root/var/www/html/Data-Analysis/COVID-19/Data/__init__.py b/Root/var/www/html/AI/ALL/Data/.keep
similarity index 100%
rename from Root/var/www/html/Data-Analysis/COVID-19/Data/__init__.py
rename to Root/var/www/html/AI/ALL/Data/.keep
diff --git a/Root/var/www/html/AI/ALL/Device.php b/Root/var/www/html/AI/ALL/Device.php
new file mode 100644
index 0000000..2e2962e
--- /dev/null
+++ b/Root/var/www/html/AI/ALL/Device.php
@@ -0,0 +1,955 @@
+ "AI",
+ "SubPageID" => "AIALL"
+];
+
+include dirname(__FILE__) . '/../../../Classes/Core/init.php';
+include dirname(__FILE__) . '/../../../Classes/Core/GeniSys.php';
+include dirname(__FILE__) . '/../../iotJumpWay/Classes/iotJumpWay.php';
+include dirname(__FILE__) . '/../../AI/ALL/Classes/ALL.php';
+include dirname(__FILE__) . '/../../AI/Classes/AI.php';
+
+$_GeniSysAi->checkSession();
+
+$Locations = $iotJumpWay->getLocations();
+$Zones = $iotJumpWay->getZones();
+$Devices = $ALL->getDevices();
+
+$TId = filter_input(INPUT_GET, 'device', FILTER_SANITIZE_NUMBER_INT);
+$Device = $iotJumpWay->getDevice($TId);
+
+list($dev1On, $dev1Off) = $iotJumpWay->getStatusShow($Device["context"]["Data"]["status"]["value"]);
+
+?>
+
+
+
+
+
+
+
+
+
+
=$_GeniSys->_confs["meta_title"]; ?>
+
" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
ALL Classifier Device #=$TId; ?>
+
+
+
+
+
+
+
+
+
+
Device Schema
+
+
+
+
+
+
+
+
+
+
Device History
+
+
+
+
+
+
+
+
+
+
Device Transactions
+
+
+
+
+
+
+
+
+
+
Device iotJumpWay Statuses
+
+
+
+
+
+
+
+
+
+
+
+ ID
+ Status
+ Time
+
+
+
+
+ retrieveDeviceStatuses($Device["context"]["Data"]["did"]["value"], 5);
+ if($Statuses["Response"] == "OK"):
+ foreach($Statuses["ResponseData"] as $key => $value):
+ ?>
+
+
+ #=$value->_id;?>
+ =$value->Status;?>
+ =$value->Time;?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Device iotJumpWay Life
+
+
+
+
+
+
+
+
+
+
+
+ ID
+ Details
+ Time
+
+
+
+
+ retrieveDeviceLife($Device["context"]["Data"]["did"]["value"], 5);
+ if($Statuses["Response"] == "OK"):
+ foreach($Statuses["ResponseData"] as $key => $value):
+ ?>
+
+
+ #=$value->_id;?>
+
+ CPU : =$value->Data->CPU;?>%
+ Memory : =$value->Data->Memory;?>%
+ Diskspace : =$value->Data->Diskspace;?>%
+ Temperature : =$value->Data->Temperature;?>°C
+ Latitude : =$value->Data->Latitude;?>
+ Longitude : =$value->Data->Longitude;?>
+
+ =$value->Time;?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Device iotJumpWay Sensors
+
+
+
+
+
+
+
+
+
+
+
+ ID
+ Type
+ Sensor
+ Value
+ Message
+ Time
+
+
+
+
+ retrieveDeviceSensors($Device["context"]["Data"]["did"]["value"], 5);
+ if($Statuses["Response"] == "OK"):
+ foreach($Statuses["ResponseData"] as $key => $value):
+ $location = $iotJumpWay->getLocation($value->Location);
+ ?>
+
+ #=$value->_id;?>
+ =$value->Type;?>
+ =$value->Sensor;?>
+
+ Sensor == "Facial API" || $value->Sensor == "Foscam Camera" || $value->Sensor == "USB Camera") && is_array($value->Value)):
+ foreach($value->Value AS $key => $val):
+ echo $val[0] == 0 ? "Identification: Intruder " :"Identification: User #" . $val[0] . " ";
+ echo "Distance: " . $val[1] . " ";
+ echo "Message: " . $val[2] . " ";
+ endforeach;
+ else:
+ echo $value->Value;
+ endif;
+ ?>
+
+
+ =$value->Message;?>
+ =$value->Time;?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Device iotJumpWay Commands
+
+
+
+
+
+
+
+
+
+
+
+ ID
+ Details
+ Status
+ Time
+
+
+
+
+ retrieveDeviceCommands($Device["context"]["Data"]["did"]["value"], 5);
+ if($Statuses["Response"] == "OK"):
+ foreach($Statuses["ResponseData"] as $key => $value):
+ $location = $iotJumpWay->getLocation($value->Location);
+ ?>
+
+
+ #=$value->_id;?>
+ Location: #=$value->Location;?> - =$location["name"]; ?>
+ =$value->Status;?>
+ =$value->Time;?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Root/var/www/html/AI/ALL/index.php b/Root/var/www/html/AI/ALL/index.php
new file mode 100644
index 0000000..ae733bd
--- /dev/null
+++ b/Root/var/www/html/AI/ALL/index.php
@@ -0,0 +1,178 @@
+ "AI",
+ "SubPageID" => "AIALL"
+];
+
+include dirname(__FILE__) . '/../../../Classes/Core/init.php';
+include dirname(__FILE__) . '/../../../Classes/Core/GeniSys.php';
+include dirname(__FILE__) . '/../../iotJumpWay/Classes/iotJumpWay.php';
+include dirname(__FILE__) . '/../../AI/ALL/Classes/ALL.php';
+
+$_GeniSysAi->checkSession();
+$Devices = $ALL->getDevices();
+
+?>
+
+
+
+
+
+
+
+
+
+
=$_GeniSys->_confs["meta_title"]; ?>
+
" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Acute Lymphoblastic Leukemia (ALL) Models
+
+
+
+
+
+
+
+
+
+
In addition to using Acute Lymphoblastic Leukemia detection models created by the Peter Moss Acute Lymphoblastic & Lymphoblastic AI Research Project team, you can develop your own models and connect them up to the HIAS network.
+
+
+
+
+
+
+
Acute Lymphoblastic Leukemia Detection Devices
+
+
+
+
+
+
+
+
+
+
+
+ ID
+ DETAILS
+ STATUS
+ ACTION
+
+
+
+
+ $value):
+ ?>
+
+
+ #=$value["did"]["value"];?>
+
+ Name: =$value["name"]["value"];?>
+ Zone: #=$value["zid"]["value"];?>
+
+
+ ">
+ =$value["status"]["value"] == "OFFLINE" ? "OFFLINE" : "ONLINE"; ?>
+
+
+ "> Edit | /Classify"> Classify
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Root/var/www/html/AI/AML/Classes/AML.js b/Root/var/www/html/AI/AML/Classes/AML.js
new file mode 100644
index 0000000..db2883b
--- /dev/null
+++ b/Root/var/www/html/AI/AML/Classes/AML.js
@@ -0,0 +1,176 @@
+var ALL = {
+ Create: function() {
+ $.post(window.location.href, $("#aml_classifier").serialize(), function(resp) {
+ var resp = jQuery.parseJSON(resp);
+ switch (resp.Response) {
+ case "OK":
+ GeniSys.ResetForm("aml_classifier");
+ $('.modal-title').text('ALL Classifier Devices');
+ $('.modal-body').html("HIAS ALL Classifier Device ID #" + resp.GDID + " created! Please save the API keys safely. The device's credentials are provided below. The credentials can be reset in the GeniSyAI Security Devices area.
Device ID: " + resp.DID + "
MQTT User: " + resp.MU + "
MQTT Password: " + resp.MP + "
Blockchain User: " + resp.BU + "
Blockchain Pass: " + resp.BP + "
App ID: " + resp.AppID + "
App Key: " + resp.AppKey + "
" + resp.Message);
+ $('#responsive-modal').modal('show');
+ Logging.logMessage("Core", "Forms", "Device ID #" + resp.DID + " created!");
+ break;
+ default:
+ msg = "ALL Create Failed: " + resp.Message
+ Logging.logMessage("Core", "ALL", msg);
+ $('.modal-title').text('ALL Classifier Devices');
+ $('.modal-body').text(msg);
+ $('#responsive-modal').modal('show');
+ break;
+ }
+ });
+ },
+ Update: function() {
+ $.post(window.location.href, $("#aml_classifier_update").serialize(), function(resp) {
+ console.log(resp)
+ var resp = jQuery.parseJSON(resp);
+ switch (resp.Response) {
+ case "OK":
+ var fjson = JSON.stringify(resp.Schema, null, '\t');
+ window.parent.$('#schema').html(fjson);
+ Logging.logMessage("Core", "Forms", "Device Update OK");
+ $('.modal-title').text('ALL Classifier Devices');
+ $('.modal-body').text(resp.Message);
+ $('#responsive-modal').modal('show');
+ break;
+ default:
+ msg = "ALL Update Failed: " + resp.Message
+ Logging.logMessage("Core", "ALL", msg);
+ $('.modal-title').text('ALL Classifier Devices');
+ $('.modal-body').text(msg);
+ $('#responsive-modal').modal('show');
+ break;
+ }
+ });
+ },
+ deleteData: function() {
+ $.post(window.location.href, { "deleteData": 1 }, function(resp) {
+ var resp = jQuery.parseJSON(resp);
+ switch (resp.Response) {
+ case "OK":
+ $('#dataBlock').empty();
+ $('#dataBlock').html("
Please upload your test dataset.
");
+ break;
+ default:
+ break;
+ }
+ });
+ },
+ prepareUploadForm: function() {
+
+ var upper = document.querySelector('#dataup'),
+ form = new FormData(),
+ xhr = new XMLHttpRequest();
+
+ form.append('uploadAllData', 1);
+
+ upper.addEventListener('change', function(event) {
+ event.preventDefault();
+
+ var files = this.files;
+ for (var i = 0, n = files.length; i < n; i++) {
+ var file = files[i];
+
+ form.append('amldata[]', file, file.name);
+
+ xhr.onload = function() {
+ if (xhr.status === 200) {
+ var resp = jQuery.parseJSON(xhr.response);
+ if (resp.Response === "OK") {
+ $('#dataBlock').empty();
+ $('#dataBlock').html(resp.Data);
+ ALL.setOpacity();
+ Logging.logMessage("Core", "Forms", resp.Message);
+ $('.modal-title').text('Data Upload OK');
+ $('.modal-body').text(resp.Message);
+ $('#responsive-modal').modal('show');
+ } else {
+ Logging.logMessage("Core", "Forms", resp.Message);
+ $('.modal-title').text('Data Upload Failed');
+ $('.modal-body').text(resp.Message);
+ $('#responsive-modal').modal('show');
+ }
+ }
+ }
+
+ xhr.open('POST', '');
+ xhr.send(form);
+ }
+ });
+ },
+ setOpacity: function() {
+ $('.classify').css("opacity", "1.0");
+ $('.classify').hover(function() {
+ $(this).stop().animate({ opacity: 0.2 }, "fast");
+ },
+ function() {
+ $(this).stop().animate({ opacity: 1.0 }, "fast");
+ });
+ },
+ classify: function(im) {
+
+ $('#imageView').html("
");
+ $("#imName").text(im);
+ var classification = '';
+ $("#imClass").html("
Diagnosis: WAITING FOR RESPONSE");
+ $("#imResult").html("
Result: WAITING FOR RESPONSE");
+ $.post(window.location.href, { "classifyData": 1, "im": im }, function(resp) {
+ var resp = jQuery.parseJSON(resp);
+ switch (resp.Response) {
+ case "OK":
+ if (im.includes("_0") && resp.Diagnosis == "Negative") {
+ classification = "True Negative";
+ } else if (im.includes("_0") && resp.Diagnosis == "Positive") {
+ classification = "False Positive";
+ } else if (im.includes("_1") && resp.Diagnosis == "Positive") {
+ classification = "True Positive";
+ } else if (im.includes("_1") && resp.Diagnosis == "Negative") {
+ classification = "False Negative";
+ }
+ $("#imClass").html("
Diagnosis: " + resp.Diagnosis);
+ if (resp.Confidence) {
+ $("#imConf").html("
Confidence: " + resp.Confidence);
+ } else {
+ $("#imConf").hide();
+ }
+ $("#imResult").html("
Result: " + classification);
+ break;
+ default:
+ break;
+ }
+ });
+
+ }
+};
+$(document).ready(function() {
+
+ $('#aml_classifier').validator().on('submit', function(e) {
+ if (!e.isDefaultPrevented()) {
+ e.preventDefault();
+ ALL.Create();
+ }
+ });
+
+ $('#aml_classifier_update').validator().on('submit', function(e) {
+ if (!e.isDefaultPrevented()) {
+ e.preventDefault();
+ ALL.Update();
+ }
+ });
+
+ $("#GeniSysAI").on("click", "#uploadData", function(e) {
+ e.preventDefault();
+ $('#dataup').trigger('click');
+ });
+
+ $("#GeniSysAI").on("click", "#deleteData", function(e) {
+ e.preventDefault();
+ ALL.deleteData();
+ });
+
+ $("#GeniSysAI").on("click", ".classify", function(e) {
+ e.preventDefault();
+ ALL.classify($(this).attr("id"));
+ });
+
+});
\ No newline at end of file
diff --git a/Root/var/www/html/AI/AML/Classes/AML.php b/Root/var/www/html/AI/AML/Classes/AML.php
new file mode 100644
index 0000000..909b751
--- /dev/null
+++ b/Root/var/www/html/AI/AML/Classes/AML.php
@@ -0,0 +1,1687 @@
+_GeniSys = $_GeniSys;
+ $this->bcc = $this->getBlockchainConf();
+ $this->web3 = $this->blockchainConnection();
+ $this->contract = new Contract($this->web3->provider, $this->bcc["abi"]);
+ $this->icontract = new Contract($this->web3->provider, $this->bcc["iabi"]);
+ $this->checkBlockchainPermissions();
+ endif;
+ $this->cb = $this->getContextBrokerConf();
+ }
+
+ public function setClassifierConfs()
+ {
+ $TId = filter_input(INPUT_GET, 'device', FILTER_SANITIZE_NUMBER_INT);
+ $Device = $this->getDevice($TId);
+
+ $this->dataDir = "Data/" . $Device["context"]["Data"]["dataset"]["folder"] . "/";
+ $this->dataDirFull = "/fserver/var/www/html/AI/AML//";
+ $this->dataFiles = $this->dataDir . "*.jpg";
+ $this->amlowedFiles = ["jpg","JPG"];
+ $this->api = $this->_GeniSys->_helpers->oDecrypt($this->_GeniSys->_confs["domainString"])."/AI/AML/" . $Device["context"]["Data"]["proxy"]["endpoint"] . "/Inference";
+ }
+
+ public function getContextBrokerConf()
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM contextbroker
+ ");
+ $pdoQuery->execute();
+ $response=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+ return $response;
+ }
+
+ private function createContextHeaders()
+ {
+ $basicAuth = $_SESSION["GeniSysAI"]["User"] . ":" . $this->_GeniSys->_helpers->oDecrypt($_SESSION["GeniSysAI"]["Pass"]);
+ $basicAuth = base64_encode($basicAuth);
+
+ return [
+ "Content-Type: application/json",
+ 'Authorization: Basic '. $basicAuth
+ ];
+ }
+
+ private function contextBrokerRequest($method, $endpoint, $headers, $json)
+ {
+ $path = $this->_GeniSys->_helpers->oDecrypt($this->_GeniSys->_confs["domainString"]) . "/" . $this->cb["url"] . "/" . $endpoint;
+
+ if($method == "GET"):
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ curl_setopt($ch, CURLOPT_HEADER, 1);
+ curl_setopt($ch, CURLOPT_URL, $path);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ $response = curl_exec($ch);
+ $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
+ $header = substr($response, 0, $header_size);
+ $body = substr($response, $header_size);
+ curl_close($ch);
+ elseif($method == "POST"):
+ $ch = curl_init($path);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ curl_setopt($ch, CURLOPT_HEADER, 1);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
+ $response = curl_exec($ch);
+ $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
+ $header = substr($response, 0, $header_size);
+ $body = substr($response, $header_size);
+ curl_close($ch);
+ elseif($method == "PATCH"):
+ $ch = curl_init($path);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ curl_setopt($ch, CURLOPT_HEADER, 1);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
+ $response = curl_exec($ch);
+ $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
+ $header = substr($response, 0, $header_size);
+ $body = substr($response, $header_size);
+ curl_close($ch);
+ endif;
+
+ return $body;
+ }
+
+ public function getBlockchainConf()
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT blockchain.*,
+ contracts.contract,
+ contracts.abi,
+ icontracts.contract as icontract,
+ icontracts.abi as iabi
+ FROM blockchain blockchain
+ INNER JOIN contracts contracts
+ ON contracts.id = blockchain.dc
+ INNER JOIN contracts icontracts
+ ON icontracts.id = blockchain.ic
+ ");
+ $pdoQuery->execute();
+ $response=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+ return $response;
+ }
+
+ private function blockchainConnection()
+ {
+ if(isSet($_SESSION["GeniSysAI"]["Active"])):
+ $web3 = new Web3($this->_GeniSys->_helpers->oDecrypt($this->_GeniSys->_confs["domainString"]) . "/Blockchain/API/", 30, $_SESSION["GeniSysAI"]["User"], $this->_GeniSys->_helpers->oDecrypt($_SESSION["GeniSysAI"]["Pass"]));
+ return $web3;
+ endif;
+ }
+
+ private function checkBlockchainPermissions()
+ {
+ $amlowed = "";
+ $errr = "";
+ $this->contract->at($this->_GeniSys->_helpers->oDecrypt($this->bcc["contract"]))->call("identifierAllowed", "User", $_SESSION["GeniSysAI"]["Identifier"], ["from" => $_SESSION["GeniSysAI"]["BC"]["BCUser"]], function ($err, $resp) use (&$amlowed, &$errr) {
+ if ($err !== null) {
+ $amlowed = "FAILED";
+ $errr = $err;
+ return;
+ }
+ $amlowed = $resp;
+ });
+ if(!$amlowed):
+ header('Location: /Logout');
+ endif;
+ }
+
+ private function unlockBlockchainAccount()
+ {
+ $response = "";
+ $personal = $this->web3->personal;
+ $personal->unlockAccount($_SESSION["GeniSysAI"]["BC"]["BCUser"], $this->_GeniSys->_helpers->oDecrypt($_SESSION["GeniSysAI"]["BC"]["BCPass"]), function ($err, $unlocked) use (&$response) {
+ if ($err !== null) {
+ $response = "FAILED! " . $err;
+ return;
+ }
+ if ($unlocked) {
+ $response = "OK";
+ } else {
+ $response = "FAILED";
+ }
+ });
+
+ return $response;
+ }
+
+ private function lockBlockchainAccount()
+ {
+ $response = "";
+ $personal = $this->web3->personal;
+ $personal->lockAccount($_SESSION["GeniSysAI"]["BC"]["BCUser"], function ($err, $unlocked) use (&$response) {
+ if ($err !== null) {
+ $response = "FAILED! " . $err;
+ return;
+ }
+ if ($unlocked) {
+ $response = "OK";
+ } else {
+ $response = "FAILED";
+ }
+ });
+
+ return $response;
+ }
+
+ private function createBlockchainUser($pass)
+ {
+ $newAccount = "";
+ $personal = $this->web3->personal;
+ $personal->newAccount($pass, function ($err, $account) use (&$newAccount) {
+ if ($err !== null) {
+ $newAccount = "FAILED!";
+ return;
+ }
+ $newAccount = $account;
+ });
+
+ return $newAccount;
+ }
+
+ private function getBlockchainBalance()
+ {
+ $nbalance = "";
+ $this->web3->eth->getBalance($_SESSION["GeniSysAI"]["BC"]["BCUser"], function ($err, $balance) use (&$nbalance) {
+ if ($err !== null) {
+ $response = "FAILED! " . $err;
+ return;
+ }
+ $nbalance = $balance->toString();
+ });
+
+ return Utils::fromWei($nbalance, 'ether')[0];
+ }
+
+ private function addAmqpUser($username, $key)
+ {
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO amqpu (
+ `username`,
+ `pw`
+ ) VALUES (
+ :username,
+ :pw
+ )
+ ");
+ $query->execute([
+ ':username' => $username,
+ ':pw' => $this->_GeniSys->_helpers->oEncrypt($key)
+ ]);
+ $amid = $this->_GeniSys->_secCon->lastInsertId();
+ return $amid;
+ }
+
+ private function addAmqpUserVh($uid, $vhost)
+ {
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO amqpvh (
+ `uid`,
+ `vhost`
+ ) VALUES (
+ :uid,
+ :vhost
+ )
+ ");
+ $query->execute([
+ ':uid' => $uid,
+ ':vhost' => $vhost
+ ]);
+ }
+
+ private function addAmqpVhPerm($uid, $vhost, $rtype, $rname, $permission)
+ {
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO amqpvhr (
+ `uid`,
+ `vhost`,
+ `rtype`,
+ `rname`,
+ `permission`
+ ) VALUES (
+ :uid,
+ :vhost,
+ :rtype,
+ :rname,
+ :permission
+ )
+ ");
+ $query->execute([
+ ':uid' => $uid,
+ ':vhost' => $vhost,
+ ':rtype' => $rtype,
+ ':rname' => $rname,
+ ':permission' => $permission
+ ]);
+ }
+
+ private function addAmqpVhTopic($uid, $vhost, $rtype, $rname, $permission, $rkey)
+ {
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO amqpvhrt (
+ `uid`,
+ `vhost`,
+ `rtype`,
+ `rname`,
+ `permission`,
+ `rkey`
+ ) VALUES (
+ :uid,
+ :vhost,
+ :rtype,
+ :rname,
+ :permission,
+ :rkey
+ )
+ ");
+ $query->execute([
+ ':uid' => $uid,
+ ':vhost' => $vhost,
+ ':rtype' => $rtype,
+ ':rname' => $rname,
+ ':permission' => $permission,
+ ':rkey' => $rkey
+ ]);
+ }
+
+ private function storeBlockchainTransaction($action, $hash, $device = 0, $application = 0)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO transactions (
+ `uid`,
+ `did`,
+ `aid`,
+ `action`,
+ `hash`,
+ `time`
+ ) VALUES (
+ :uid,
+ :did,
+ :aid,
+ :action,
+ :hash,
+ :time
+ )
+ ");
+ $pdoQuery->execute([
+ ":uid" => $_SESSION["GeniSysAI"]["Uid"],
+ ":did" => $device,
+ ":aid" => $application,
+ ":action" => $action,
+ ':hash' => $this->_GeniSys->_helpers->oEncrypt($hash),
+ ":time" => time()
+ ]);
+ $txid = $this->_GeniSys->_secCon->lastInsertId();
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ return $txid;
+ }
+
+ private function storeUserHistory($action, $hash, $location = 0, $zone = 0, $device = 0, $sensor = 0, $application = 0)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO history (
+ `uid`,
+ `tlid`,
+ `tzid`,
+ `tdid`,
+ `tsid`,
+ `taid`,
+ `action`,
+ `hash`,
+ `time`
+ ) VALUES (
+ :uid,
+ :tlid,
+ :tzid,
+ :tdid,
+ :tsid,
+ :taid,
+ :action,
+ :hash,
+ :time
+ )
+ ");
+ $pdoQuery->execute([
+ ":uid" => $_SESSION["GeniSysAI"]["Uid"],
+ ":tlid" => $location,
+ ":tzid" => $zone,
+ ":tdid" => $device,
+ ":tsid" => $sensor,
+ ":taid" => $application,
+ ":action" => $action,
+ ":hash" => $hash,
+ ":time" => time()
+ ]);
+ $txid = $this->_GeniSys->_secCon->lastInsertId();
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ return $txid;
+ }
+
+ public function checkLocation($lid)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT id
+ FROM mqttl
+ WHERE id = :id
+ ");
+ $pdoQuery->execute([
+ ":id" => $lid
+ ]);
+ $location=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($location["id"]):
+ return True;
+ else:
+ return False;
+ endif;
+ }
+
+ public function getLocation($id, $attrs = Null)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM mqttl
+ WHERE id = :id
+ ");
+ $pdoQuery->execute([
+ ":id" => $id
+ ]);
+ $location=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($attrs):
+ $attrs="&attrs=" . $attrs;
+ endif;
+
+ $location["context"] = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "/" . $location["pub"] . "?type=Location" . $attrs, $this->createContextHeaders(), []), true);
+ return $location;
+ }
+
+ public function checkZone($zid)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT id
+ FROM mqttlz
+ WHERE id = :id
+ ");
+ $pdoQuery->execute([
+ ":id" => $zid
+ ]);
+ $location=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($location["id"]):
+ return True;
+ else:
+ return False;
+ endif;
+ }
+
+ public function getZone($id, $attrs = Null)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM mqttlz
+ WHERE id = :id
+ ORDER BY id DESC
+ ");
+ $pdoQuery->execute([
+ ":id" => $id
+ ]);
+ $zone=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($attrs):
+ $attrs="&attrs=" . $attrs;
+ endif;
+
+ $zone["context"] = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "/" . $zone["pub"] . "?type=Zone" . $attrs, $this->createContextHeaders(), []), true);
+ return $zone;
+ }
+
+ public function getDevices($limit = 0)
+ {
+ $limiter = "";
+ if($limit != 0):
+ $limiter = "&limit=" . $limit;
+ endif;
+
+ $devices = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "?type=Device&category=AMLClassifier".$limiter, $this->createContextHeaders(), []), true);
+ return $devices;
+ }
+
+ public function getDevice($id, $attrs = Null)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM mqttld
+ WHERE id = :id
+ ORDER BY id DESC
+ ");
+ $pdoQuery->execute([
+ ":id" => $id
+ ]);
+ $device=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($attrs):
+ $attrs="&attrs=" . $attrs;
+ endif;
+
+ $device["context"] = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "/" . $device["apub"] . "?type=Device" . $attrs, $this->createContextHeaders(), []), true);
+ return $device;
+ }
+
+ public function getThing($id, $attrs = Null)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM things
+ WHERE id = :id
+ ");
+ $pdoQuery->execute([
+ ":id" => $id
+ ]);
+ $thing=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($attrs):
+ $attrs="&attrs=" . $attrs;
+ endif;
+
+ $thing["context"] = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "/" . $thing["pub"] . "?type=Thing" . $attrs, $this->createContextHeaders(), []), true);
+ return $thing;
+ }
+
+ public function getModel($id, $attrs = Null)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM models
+ WHERE id = :id
+ ORDER BY id DESC
+ ");
+ $pdoQuery->execute([
+ ":id" => $id
+ ]);
+ $model=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($attrs):
+ $attrs="&attrs=" . $attrs;
+ endif;
+
+ $device["context"] = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "/" . $model["pub"] . "?type=Model" . $attrs, $this->createContextHeaders(), []), true);
+ return $device;
+ }
+
+ public function createDevice()
+ {
+ if(!filter_input(INPUT_POST, "lid", FILTER_SANITIZE_NUMBER_INT)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Location ID is required"
+ ];
+ endif;
+
+ if(!$this->checkLocation(filter_input(INPUT_POST, "lid", FILTER_SANITIZE_NUMBER_INT))):
+ return [
+ "Response"=> "Failed",
+ "Message" => "iotJumpWay location does not exist"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "zid", FILTER_SANITIZE_NUMBER_INT)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Zone ID is required"
+ ];
+ endif;
+
+ if(!$this->checkZone(filter_input(INPUT_POST, "zid", FILTER_SANITIZE_NUMBER_INT))):
+ return [
+ "Response"=> "Failed",
+ "Message" => "iotJumpWay zone does not exist"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "category", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Category is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "ctype", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Model type is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "agent", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "IoT Agent is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "name", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "description", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "deviceName", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Hardware device name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "deviceManufacturer", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Hardware device manufacturer is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "deviceModel", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Hardware device model is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osName", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osManufacturer", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system manufacturer is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osVersion", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system version is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "agent", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "IoT Agent is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "coordinates", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Coordinates entity is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "ip", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "IP is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "mac", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "MAC is required"
+ ];
+ endif;
+
+ if(!count($_POST["protocols"])):
+ return [
+ "Response"=> "Failed",
+ "Message" => "At least one M2M protocol is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "datasetUsed", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Dataset used is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "datasetLink", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Dataset link is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "datasetAuthor", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Dataset author is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "datasetFolder", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Dataset folder is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "relatedPaper", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Related paper is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "sport", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Device server port is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "endpoint", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Proxy endpoint is required"
+ ];
+ endif;
+
+ $unlocked = $this->unlockBlockchainAccount();
+
+ if($unlocked == "FAILED"):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Unlocking HIAS Blockhain Account Failed!"
+ ];
+ endif;
+
+ $mqttUser = $this->_GeniSys->_helpers->generate_uuid();
+ $mqttPass = $this->_GeniSys->_helpers->password();
+ $mqttHash = create_hash($mqttPass);
+
+ $pubKey = $this->_GeniSys->_helpers->generate_uuid();
+ $privKey = $this->_GeniSys->_helpers->generateKey(32);
+ $privKeyHash = $this->_GeniSys->_helpers->createPasswordHash($privKey);
+
+ $amqppubKey = $this->_GeniSys->_helpers->generate_uuid();
+ $amqpprvKey = $this->_GeniSys->_helpers->generateKey(32);
+ $amqpKeyHash = $this->_GeniSys->_helpers->createPasswordHash($amqpprvKey);
+
+ $bcPass = $this->_GeniSys->_helpers->password();
+
+ $lid = filter_input(INPUT_POST, 'lid', FILTER_SANITIZE_NUMBER_INT);
+ $location = $this->getLocation($lid);
+
+ $zid = filter_input(INPUT_POST, 'zid', FILTER_SANITIZE_NUMBER_INT);
+ $zone = $this->getZone($zid);
+
+ $ip = filter_input(INPUT_POST, "ip", FILTER_SANITIZE_STRING);
+ $mac = filter_input(INPUT_POST, "mac", FILTER_SANITIZE_STRING);
+ $bluetooth = filter_input(INPUT_POST, "bluetooth", FILTER_SANITIZE_STRING);
+ $name = filter_input(INPUT_POST, "name", FILTER_SANITIZE_STRING);
+ $coords = explode(",", filter_input(INPUT_POST, "coordinates", FILTER_SANITIZE_STRING));
+
+ mkdir("Data/" . filter_input(INPUT_POST, "datasetFolder", FILTER_SANITIZE_STRING), 0777, true);
+
+ $protocols = [];
+ foreach($_POST["protocols"] AS $key => $value):
+ $protocols[] = $value;
+ endforeach;
+
+ $models = [];
+ if(isSet($_POST["ai"])):
+ foreach($_POST["ai"] AS $key => $value):
+ $model = $this->getModel($value)["context"]["Data"];
+ $mname = $model["name"]["value"];
+ unset($model["id"]);
+ unset($model["type"]);
+ unset($model["mid"]);
+ unset($model["name"]);
+ unset($model["description"]);
+ unset($model["network"]);
+ unset($model["language"]);
+ unset($model["framework"]);
+ unset($model["toolkit"]);
+ unset($model["dateCreated"]);
+ unset($model["dateModified"]);
+ $models[$mname] = $model;
+ endforeach;
+ endif;
+
+ $sensors = [];
+ if(isSet($_POST["sensors"])):
+ foreach($_POST["sensors"] AS $key => $value):
+ $sensor = $this->getThing($value)["context"]["Data"];
+ unset($sensor["id"]);
+ unset($sensor["type"]);
+ unset($sensor["category"]);
+ unset($sensor["description"]);
+ unset($sensor["thing"]);
+ unset($sensor["properties"]["image"]);
+ unset($sensor["dateCreated"]);
+ unset($sensor["dateModified"]);
+ $sensors[] = $sensor;
+ endforeach;
+ endif;
+
+ $actuators = [];
+ if(isSet($_POST["actuators"])):
+ foreach($_POST["actuators"] AS $key => $value):
+ $actuator = $this->getThing($value)["context"]["Data"];
+ unset($actuator["id"]);
+ unset($actuator["type"]);
+ unset($actuator["category"]);
+ unset($actuator["description"]);
+ unset($actuator["thing"]);
+ unset($actuator["properties"]["image"]);
+ unset($actuator["dateCreated"]);
+ unset($actuator["dateModeified"]);
+ $actuators[] = $actuator;
+ endforeach;
+ endif;
+
+ $newBcUser = $this->createBlockchainUser($bcPass);
+
+ if($newBcUser == "FAILED"):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Creating New HIAS Blockhain Account Failed!"
+ ];
+ endif;
+
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO mqttld (
+ `apub`
+ ) VALUES (
+ :apub
+ )
+ ");
+ $query->execute([
+ ':apub' => $pubKey
+ ]);
+ $did = $this->_GeniSys->_secCon->lastInsertId();
+
+ $data = [
+ "id" => $pubKey,
+ "type" => "Device",
+ "category" => [
+ "value" => [filter_input(INPUT_POST, "category", FILTER_SANITIZE_STRING)]
+ ],
+ "name" => [
+ "value" => $name
+ ],
+ "description" => [
+ "value" => filter_input(INPUT_POST, "description", FILTER_SANITIZE_STRING)
+ ],
+ "lid" => [
+ "value" => $lid,
+ "entity" => $location["context"]["Data"]["id"]
+ ],
+ "zid" => [
+ "value" => $zid,
+ "entity" => $zone["context"]["Data"]["id"]
+ ],
+ "did" => [
+ "value" => $did
+ ],
+ "location" => [
+ "type" => "geo:json",
+ "value" => [
+ "type" => "Point",
+ "coordinates" => [floatval($coords[0]), floatval($coords[1])]
+ ]
+ ],
+ "agent" => [
+ "url" => filter_input(INPUT_POST, "agent", FILTER_SANITIZE_STRING)
+ ],
+ "paper" => [
+ "title" => filter_input(INPUT_POST, "relatedPaper", FILTER_SANITIZE_STRING),
+ "author" => filter_input(INPUT_POST, "relatedPaperAuthor", FILTER_SANITIZE_STRING),
+ "doi" => filter_input(INPUT_POST, "relatedPaperDOI", FILTER_SANITIZE_STRING),
+ "link" => filter_input(INPUT_POST, "relatedPaperLink", FILTER_SANITIZE_STRING)
+ ],
+ "dataset" => [
+ "name" => filter_input(INPUT_POST, "datasetUsed", FILTER_SANITIZE_STRING),
+ "author" => filter_input(INPUT_POST, "datasetAuthor", FILTER_SANITIZE_STRING),
+ "url" => filter_input(INPUT_POST, "datasetLink", FILTER_SANITIZE_STRING),
+ "folder" => filter_input(INPUT_POST, "datasetFolder", FILTER_SANITIZE_STRING)
+ ],
+ "device" => [
+ "type" => filter_input(INPUT_POST, "ctype", FILTER_SANITIZE_STRING),
+ "name" => filter_input(INPUT_POST, "deviceName", FILTER_SANITIZE_STRING),
+ "manufacturer" => filter_input(INPUT_POST, "deviceManufacturer", FILTER_SANITIZE_STRING),
+ "model" => filter_input(INPUT_POST, "deviceModel", FILTER_SANITIZE_STRING)
+ ],
+ "proxy" => [
+ "endpoint" => filter_input(INPUT_POST, "endpoint", FILTER_SANITIZE_STRING)
+ ],
+ "stream" => [
+ "port" => filter_input(INPUT_POST, "sport", FILTER_SANITIZE_STRING),
+ "file" => ""
+ ],
+ "socket" => [
+ "port" => ""
+ ],
+ "os" => [
+ "name" => filter_input(INPUT_POST, "osName", FILTER_SANITIZE_STRING),
+ "manufacturer" => filter_input(INPUT_POST, "osManufacturer", FILTER_SANITIZE_STRING),
+ "version" => filter_input(INPUT_POST, "osVersion", FILTER_SANITIZE_STRING)
+ ],
+ "protocols" => $protocols,
+ "status" => [
+ "value" => "OFFLINE",
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "keys" => [
+ "public" => $pubKey,
+ "private" => $this->_GeniSys->_helpers->oEncrypt($privKeyHash),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "blockchain" => [
+ "address" => $newBcUser,
+ "password" => $this->_GeniSys->_helpers->oEncrypt($bcPass)
+ ],
+ "mqtt" => [
+ "username" => $this->_GeniSys->_helpers->oEncrypt($mqttUser),
+ "password" => $this->_GeniSys->_helpers->oEncrypt($mqttPass),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "coap" => [
+ "username" => "",
+ "password" => ""
+ ],
+ "amqp" => [
+ "username" => $this->_GeniSys->_helpers->oEncrypt($amqppubKey),
+ "password" => $this->_GeniSys->_helpers->oEncrypt($amqpprvKey),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "batteryLevel" => [
+ "value" => 0.00
+ ],
+ "cpuUsage" => [
+ "value" => 0.00
+ ],
+ "memoryUsage" => [
+ "value" => 0.00
+ ],
+ "hddUsage" => [
+ "value" => 0.00
+ ],
+ "temperature" => [
+ "value" => 0.00
+ ],
+ "ip" => [
+ "value" => $this->_GeniSys->_helpers->oEncrypt($ip),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "mac" => [
+ "value" => $this->_GeniSys->_helpers->oEncrypt($mac),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "bluetooth" => [
+ "address" => $bluetooth ? $this->_GeniSys->_helpers->oEncrypt($bluetooth) : "",
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "ai" => $models,
+ "sensors" => $sensors,
+ "actuators" => $actuators,
+ "dateCreated" => [
+ "type" => "DateTime",
+ "value" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "dateFirstUsed" => [
+ "type" => "DateTime",
+ "value" => ""
+ ],
+ "dateModified" => [
+ "type" => "DateTime",
+ "value" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ]
+ ];
+
+ $response = json_decode($this->contextBrokerRequest("POST", $this->cb["entities_url"] . "?type=Device", $this->createContextHeaders(), json_encode($data)), true);
+
+ if($response["Response"]=="OK"):
+
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO mqttu (
+ `lid`,
+ `zid`,
+ `did`,
+ `uname`,
+ `pw`
+ ) VALUES (
+ :lid,
+ :zid,
+ :did,
+ :uname,
+ :pw
+ )
+ ");
+ $query->execute([
+ ':lid' => $lid,
+ ':zid' => $zid,
+ ':did' => $did,
+ ':uname' => $mqttUser,
+ ':pw' => $mqttHash
+ ]);
+
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO mqttua (
+ `lid`,
+ `zid`,
+ `did`,
+ `username`,
+ `topic`,
+ `rw`
+ ) VALUES (
+ :lid,
+ :zid,
+ :did,
+ :username,
+ :topic,
+ :rw
+ )
+ ");
+ $query->execute(array(
+ ':lid' => $lid,
+ ':zid' => $zid,
+ ':did' => $did,
+ ':username' => $mqttUser,
+ ':topic' => $location["context"]["Data"]["id"] . "/Devices/" . $zone["context"]["Data"]["id"] . "/" . $pubKey . "/#",
+ ':rw' => 4
+ ));
+
+ $amid = $this->addAmqpUser($amqppubKey, $amqpKeyHash);
+ $this->addAmqpUserVh($amid, "iotJumpWay");
+ $this->addAmqpVhPerm($amid, "iotJumpWay", "exchange", "Core", "read");
+ $this->addAmqpVhPerm($amid, "iotJumpWay", "exchange", "Core", "write");
+ $this->addAmqpVhPerm($amid, "iotJumpWay", "queue", "Life", "read");
+ $this->addAmqpVhPerm($amid, "iotJumpWay", "queue", "Life", "write");
+ $this->addAmqpVhPerm($amid, "iotJumpWay", "queue", "Statuses", "read");
+ $this->addAmqpVhPerm($amid, "iotJumpWay", "queue", "Statuses", "write");
+ $this->addAmqpVhTopic($amid, "iotJumpWay", "topic", "Core", "read", "Life");
+ $this->addAmqpVhTopic($amid, "iotJumpWay", "topic", "Core", "write", "Life");
+ $this->addAmqpVhTopic($amid, "iotJumpWay", "topic", "Core", "read", "Statuses");
+ $this->addAmqpVhTopic($amid, "iotJumpWay", "topic", "Core", "write", "Statuses");
+
+ $hash = "";
+ $msg = "";
+ $actionMsg = "";
+ $balanceMessage = "";
+ $this->contract->at($this->_GeniSys->_helpers->oDecrypt($this->bcc["contract"]))->send("registerDevice", $pubKey, $newBcUser, $lid, $zid, $did, $name, $_SESSION["GeniSysAI"]["Uid"], time(), ["from" => $_SESSION["GeniSysAI"]["BC"]["BCUser"]], function ($err, $resp) use (&$hash, &$msg) {
+ if ($err !== null) {
+ $hash = "FAILED";
+ $msg = $err;
+ return;
+ }
+ $hash = $resp;
+ });
+
+ if($hash == "FAILED"):
+ $actionMsg = " HIAS Blockchain registerDevice failed!\n" . $msg;
+ else:
+ $txid = $this->storeBlockchainTransaction("Register Device", $hash, $did);
+ $this->storeUserHistory("Register Device", $txid, $lid, $zid, $did);
+ $balance = $this->getBlockchainBalance();
+ $actionMsg = " HIAS Blockchain registerDevice OK!\n";
+ $balanceMessage = " You were rewarded for this action! Your balance is now: " . $balance . " HIAS Ether!";
+ endif;
+
+ $this->icontract->at($this->_GeniSys->_helpers->oDecrypt($this->bcc["icontract"]))->send("registerAuthorized", $newBcUser, ["from" => $_SESSION["GeniSysAI"]["BC"]["BCUser"]], function ($err, $resp) use (&$hash, &$msg) {
+ if ($err !== null) {
+ $hash = "FAILED";
+ $msg = $err;
+ return;
+ }
+ $hash = $resp;
+ });
+
+ if($hash == "FAILED"):
+ $actionMsg .= " HIAS Blockchain registerAuthorized failed! " . $msg;
+ else:
+ $txid = $this->storeBlockchainTransaction("iotJumpWay Register Authorized", $hash, $did);
+ $this->storeUserHistory("Register Authorized", $txid, $lid, $zid, $did);
+ $balance = $this->getBlockchainBalance();
+ $actionMsg .= " HIAS Blockchain registerAuthorized OK!\n";
+ $balanceMessage = " You were rewarded for this action! Your balance is now: " . $balance . " HIAS Ether!";
+ endif;
+
+ return [
+ "Response"=> "OK",
+ "Message" => "Device created!" . $actionMsg . $balanceMessage,
+ "LID" => filter_input(INPUT_POST, "lid", FILTER_SANITIZE_NUMBER_INT),
+ "ZID" => filter_input(INPUT_POST, "zid", FILTER_SANITIZE_NUMBER_INT),
+ "DID" => $did,
+ "MU" => $mqttUser,
+ "MP" => $mqttPass,
+ "BU" => $newBcUser,
+ "BP" => $bcPass,
+ "AppID" => $pubKey,
+ "AppKey" => $privKey
+ ];
+ else:
+ return [
+ "Response"=> "FAILED",
+ "Message" => "Device creating failed"
+ ];
+ endif;
+ }
+
+ public function updateDevice()
+ {
+ if(!filter_input(INPUT_POST, "lid", FILTER_SANITIZE_NUMBER_INT)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Location ID is required"
+ ];
+ endif;
+
+ if(!$this->checkLocation(filter_input(INPUT_POST, "lid", FILTER_SANITIZE_NUMBER_INT))):
+ return [
+ "Response"=> "Failed",
+ "Message" => "iotJumpWay location does not exist"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "zid", FILTER_SANITIZE_NUMBER_INT)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Zone ID is required"
+ ];
+ endif;
+
+ if(!$this->checkZone(filter_input(INPUT_POST, "zid", FILTER_SANITIZE_NUMBER_INT))):
+ return [
+ "Response"=> "Failed",
+ "Message" => "iotJumpWay zone does not exist"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "category", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Category is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "ctype", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Model type is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "agent", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "IoT Agent is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "name", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "description", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "deviceName", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Hardware device name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "deviceManufacturer", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Hardware device manufacturer is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "deviceModel", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Hardware device model is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osName", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osManufacturer", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system manufacturer is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osVersion", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system version is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "agent", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "IoT Agent is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "coordinates", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Coordinates entity is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "ip", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "IP is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "mac", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "MAC is required"
+ ];
+ endif;
+
+ if(!count($_POST["protocols"])):
+ return [
+ "Response"=> "Failed",
+ "Message" => "At least one M2M protocol is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "datasetUsed", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Dataset used is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "datasetLink", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Dataset link is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "datasetAuthor", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Dataset author is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "datasetFolder", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Dataset folder is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "relatedPaper", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Related paper is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "sport", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Device server port is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "endpoint", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Proxy endpoint is required"
+ ];
+ endif;
+
+ $unlocked = $this->unlockBlockchainAccount();
+
+ if($unlocked == "FAILED"):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Unlocking HIAS Blockhain Account Failed!"
+ ];
+ endif;
+
+ $ip = filter_input(INPUT_POST, "ip", FILTER_SANITIZE_STRING);
+ $mac = filter_input(INPUT_POST, "mac", FILTER_SANITIZE_STRING);
+ $bluetooth = filter_input(INPUT_POST, "bluetooth", FILTER_SANITIZE_STRING);
+ $name = filter_input(INPUT_POST, "name", FILTER_SANITIZE_STRING);
+ $status = filter_input(INPUT_POST, "status", FILTER_SANITIZE_STRING);
+ $coords = explode(",", filter_input(INPUT_POST, "coordinates", FILTER_SANITIZE_STRING));
+
+ $did = filter_input(INPUT_GET, "device", FILTER_SANITIZE_NUMBER_INT);
+ $device = $this->getDevice($did);
+
+ $lid = filter_input(INPUT_POST, 'lid', FILTER_SANITIZE_NUMBER_INT);
+ $location = $this->getLocation($lid);
+
+ $zid = filter_input(INPUT_POST, 'zid', FILTER_SANITIZE_NUMBER_INT);
+ $zone = $this->getZone($zid);
+
+ $protocols = [];
+ foreach($_POST["protocols"] AS $key => $value):
+ $protocols[] = $value;
+ endforeach;
+
+ $models = [];
+ if(isSet($_POST["ai"])):
+ foreach($_POST["ai"] AS $key => $value):
+ $model = $this->getModel($value)["context"]["Data"];
+ $mname = $model["name"]["value"];
+ unset($model["id"]);
+ unset($model["type"]);
+ unset($model["mid"]);
+ unset($model["name"]);
+ unset($model["description"]);
+ unset($model["network"]);
+ unset($model["language"]);
+ unset($model["framework"]);
+ unset($model["toolkit"]);
+ unset($model["dateCreated"]);
+ unset($model["dateModified"]);
+ $models[$mname] = $model;
+ endforeach;
+ endif;
+
+ $sensors = [];
+ if(isSet($_POST["sensors"])):
+ foreach($_POST["sensors"] AS $key => $value):
+ $sensor = $this->getThing($value)["context"]["Data"];
+ unset($sensor["id"]);
+ unset($sensor["type"]);
+ unset($sensor["category"]);
+ unset($sensor["description"]);
+ unset($sensor["thing"]);
+ unset($sensor["properties"]["image"]);
+ unset($sensor["dateCreated"]);
+ unset($sensor["dateModified"]);
+ $sensors[] = $sensor;
+ endforeach;
+ endif;
+
+ $actuators = [];
+ if(isSet($_POST["actuators"])):
+ foreach($_POST["actuators"] AS $key => $value):
+ $actuator = $this->getThing($value)["context"]["Data"];
+ unset($actuator["id"]);
+ unset($actuator["type"]);
+ unset($actuator["category"]);
+ unset($actuator["description"]);
+ unset($actuator["thing"]);
+ unset($actuator["properties"]["image"]);
+ unset($actuator["dateCreated"]);
+ unset($actuator["dateModeified"]);
+ $actuators[] = $actuator;
+ endforeach;
+ endif;
+
+ if($device["context"]["Data"]["lid"]["value"] != $lid):
+ $query = $this->_GeniSys->_secCon->prepare("
+ UPDATE mqttu
+ SET lid = :lid
+ WHERE did = :did
+ ");
+ $query->execute([
+ ':lid' => $lid,
+ ':did' => $did
+ ]);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ $query = $this->_GeniSys->_secCon->prepare("
+ UPDATE mqttua
+ SET lid = :lid
+ WHERE did = :did
+ ");
+ $query->execute([
+ ':lid' => $lid,
+ ':did' => $did
+ ]);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ $query = $this->_GeniSys->_secCon->prepare("
+ UPDATE mqttua
+ SET topic = :topicN
+ WHERE did = :did
+ & topic = :topic
+ ");
+ $query->execute([
+ ':topicN' => $device["context"]["Data"]["lid"]["entity"] . "/ " . $device["context"]["Data"]["zid"]["entity"] . "/Devices/" . $device["context"]["Data"]["id"] . "/#",
+ ':did' => $did,
+ ':topic' => $location["context"]["Data"]["id"] . "/Devices/" . $zone["context"]["Data"]["id"] . "/Devices/" . $device["context"]["Data"]["id"] . "/#"
+ ]);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+ endif;
+
+ $data = [
+ "category" => [
+ "value" => [filter_input(INPUT_POST, "category", FILTER_SANITIZE_STRING)]
+ ],
+ "name" => [
+ "value" => $name
+ ],
+ "description" => [
+ "value" => filter_input(INPUT_POST, "description", FILTER_SANITIZE_STRING)
+ ],
+ "lid" => [
+ "value" => $lid,
+ "entity" => $location["context"]["Data"]["id"]
+ ],
+ "zid" => [
+ "value" => $zid,
+ "entity" => $zone["context"]["Data"]["id"]
+ ],
+ "location" => [
+ "type" => "geo:json",
+ "value" => [
+ "type" => "Point",
+ "coordinates" => [floatval($coords[0]), floatval($coords[1])]
+ ]
+ ],
+ "agent" => [
+ "url" => filter_input(INPUT_POST, "agent", FILTER_SANITIZE_STRING)
+ ],
+ "paper" => [
+ "title" => filter_input(INPUT_POST, "relatedPaper", FILTER_SANITIZE_STRING),
+ "author" => filter_input(INPUT_POST, "relatedPaperAuthor", FILTER_SANITIZE_STRING),
+ "doi" => filter_input(INPUT_POST, "relatedPaperDOI", FILTER_SANITIZE_STRING),
+ "link" => filter_input(INPUT_POST, "relatedPaperLink", FILTER_SANITIZE_STRING)
+ ],
+ "dataset" => [
+ "name" => filter_input(INPUT_POST, "datasetUsed", FILTER_SANITIZE_STRING),
+ "author" => filter_input(INPUT_POST, "datasetAuthor", FILTER_SANITIZE_STRING),
+ "url" => filter_input(INPUT_POST, "datasetLink", FILTER_SANITIZE_STRING),
+ "folder" => filter_input(INPUT_POST, "datasetFolder", FILTER_SANITIZE_STRING)
+ ],
+ "device" => [
+ "type" => filter_input(INPUT_POST, "ctype", FILTER_SANITIZE_STRING),
+ "name" => filter_input(INPUT_POST, "deviceName", FILTER_SANITIZE_STRING),
+ "manufacturer" => filter_input(INPUT_POST, "deviceManufacturer", FILTER_SANITIZE_STRING),
+ "model" => filter_input(INPUT_POST, "deviceModel", FILTER_SANITIZE_STRING)
+ ],
+ "proxy" => [
+ "endpoint" => filter_input(INPUT_POST, "endpoint", FILTER_SANITIZE_STRING)
+ ],
+ "stream" => [
+ "port" => filter_input(INPUT_POST, "sport", FILTER_SANITIZE_STRING),
+ "file" => ""
+ ],
+ "socket" => [
+ "port" => ""
+ ],
+ "os" => [
+ "name" => filter_input(INPUT_POST, "osName", FILTER_SANITIZE_STRING),
+ "manufacturer" => filter_input(INPUT_POST, "osManufacturer", FILTER_SANITIZE_STRING),
+ "version" => filter_input(INPUT_POST, "osVersion", FILTER_SANITIZE_STRING)
+ ],
+ "protocols" => $protocols,
+ "ip" => [
+ "value" => $this->_GeniSys->_helpers->oEncrypt($ip),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "mac" => [
+ "value" => $this->_GeniSys->_helpers->oEncrypt($mac),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "bluetooth" => [
+ "address" => $bluetooth ? $this->_GeniSys->_helpers->oEncrypt($bluetooth) : "",
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "ai" => $models,
+ "sensors" => $sensors,
+ "actuators" => $actuators,
+ "dateModified" => [
+ "type" => "DateTime",
+ "value" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ]
+ ];
+
+ $response = json_decode($this->contextBrokerRequest("PATCH", $this->cb["entities_url"] . "/" . $device["context"]["Data"]["id"] . "/attrs?type=Device", $this->createContextHeaders(), json_encode($data)), true);
+
+ if($response["Response"]=="OK"):
+
+ $hash = "";
+ $msg = "";
+ $this->contract->at($this->_GeniSys->_helpers->oDecrypt($this->bcc["contract"]))->send("updateDevice", $device["context"]["Data"]["id"], "Device", $lid, $zid, $did, $name, $device["context"]["Data"]["status"]["value"], time(), ["from" => $_SESSION["GeniSysAI"]["BC"]["BCUser"]], function ($err, $resp) use (&$hash, &$msg) {
+ if ($err !== null) {
+ $hash = "FAILED";
+ $msg = $err;
+ return;
+ }
+ $hash = $resp;
+ });
+
+ $balance = "";
+ $balanceMessage = "";
+ $actionMsg = "";
+ if($hash == "FAILED"):
+ $actionMsg = " HIAS Blockchain updateDevice failed! " . $msg;
+ else:
+ $txid = $this->storeBlockchainTransaction("Update Device", $hash, $did);
+ $this->storeUserHistory("Updated Device", $txid, $lid, $zid, $did);
+ $balance = $this->getBlockchainBalance();
+ $balanceMessage = " You were rewarded for this action! Your balance is now: " . $balance . " HIAS Ether!";
+ endif;
+
+ $device = $this->getDevice($did);
+
+ return [
+ "Response"=> "OK",
+ "Message" => "Device updated!" . $actionMsg . $balanceMessage,
+ "Schema" => $device["context"]["Data"]
+ ];
+ else:
+ return [
+ "Response"=> "Failed",
+ "Message" => "There was a problem updating this device context data!"
+ ];
+ endif;
+ }
+
+ public function deleteData()
+ {
+ $images = glob($this->dataFiles);
+ foreach( $images as $image ):
+ unlink($image);
+ endforeach;
+
+ return [
+ "Response" => "OK",
+ "Message" => "Deleted Acute Lymphoblastic Leukemia Image Database for Image Processing Dataset"
+ ];
+
+ }
+
+ public function uploadData()
+ {
+ $dataCells = '';
+ if(is_array($_FILES) && !empty($_FILES['amldata'])):
+ foreach($_FILES['amldata']['name'] as $key => $filename):
+ $file_name = explode(".", $filename);
+ if(in_array($file_name[1], $this->amlowedFiles)):
+ $sourcePath = $_FILES["amldata"]["tmp_name"][$key];
+ $targetPath = $this->dataDir . $filename;
+ if(!move_uploaded_file($sourcePath, $targetPath)):
+ return [
+ "Response" => "FAILED",
+ "Message" => "Upload failed " . $targetPath
+ ];
+ endif;
+ else:
+ return [
+ "Response" => "FAILED",
+ "Message" => "Please upload jpg files"
+ ];
+ endif;
+ endforeach;
+
+ $images = glob($this->dataFiles);
+ $count = 1;
+ foreach($images as $image):
+ $dataCells .= "
";
+ if($count%6 == 0):
+ $dataCells .= "
";
+ endif;
+ $count++;
+ endforeach;
+
+ else:
+ return [
+ "Response" => "FAILED",
+ "Message" => "You must upload some images (jpg)"
+ ];
+ endif;
+
+ return [
+ "Response" => "OK",
+ "Message" => "Data upload OK!",
+ "Data" => $dataCells
+ ];
+
+ }
+
+ public function classifyData()
+ {
+ $file = $this->dataDirFull . filter_input(INPUT_POST, "im", FILTER_SANITIZE_STRING);
+ $mime = mime_content_type($file);
+ $info = pathinfo($file);
+ $name = $info['basename'];
+ $toSend = new CURLFile($file, $mime, $name);
+
+ $headers = [
+ 'Authorization: Basic '. base64_encode($_SESSION["GeniSysAI"]["User"] . ":" . $this->_GeniSys->_helpers->oDecrypt($_SESSION["GeniSysAI"]["Pass"]))
+ ];
+
+ $ch = curl_init($this->api);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_POST, true);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, [
+ 'file'=> $toSend,
+ ]);
+
+ $resp = curl_exec($ch);
+
+ return json_decode($resp, true);
+
+ }
+
+ }
+
+ $AML = new AML($_GeniSys);
+
+ if(filter_input(INPUT_POST, "create_aml_classifier", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($AML->createDevice()));
+ endif;
+
+ if(filter_input(INPUT_POST, "update_aml_classifier", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($AML->updateDevice()));
+ endif;
+
+ if(filter_input(INPUT_POST, "reset_mqtt", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($AML->resetMqtt()));
+ endif;
+
+ if(filter_input(INPUT_POST, "reset_key", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($AML->resetDvcKey()));
+ endif;
+
+ if(filter_input(INPUT_POST, "get_tlife", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($AML->getLife()));
+ endif;
+
+ if(filter_input(INPUT_POST, "deleteData", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($AML->deleteData()));
+ endif;
+
+ if(filter_input(INPUT_POST, "uploadAllData", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($AML->uploadData()));
+ endif;
+
+ if(filter_input(INPUT_POST, "classifyData", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($AML->classifyData()));
+ endif;
diff --git a/Root/var/www/html/AI/AML/Classify.php b/Root/var/www/html/AI/AML/Classify.php
new file mode 100644
index 0000000..0f03d44
--- /dev/null
+++ b/Root/var/www/html/AI/AML/Classify.php
@@ -0,0 +1,200 @@
+ "AI",
+ "SubPageID" => "AIAML"
+];
+
+include dirname(__FILE__) . '/../../../Classes/Core/init.php';
+include dirname(__FILE__) . '/../../../Classes/Core/GeniSys.php';
+include dirname(__FILE__) . '/../../iotJumpWay/Classes/iotJumpWay.php';
+include dirname(__FILE__) . '/../../AI/AML/Classes/AML.php';
+
+$_GeniSysAi->checkSession();
+
+$Locations = $iotJumpWay->getLocations();
+$Zones = $iotJumpWay->getZones();
+$Devices = $AML->getDevices();
+
+$TId = filter_input(INPUT_GET, 'device', FILTER_SANITIZE_NUMBER_INT);
+$Device = $iotJumpWay->getDevice($TId);
+
+list($dev1On, $dev1Off) = $iotJumpWay->getStatusShow($Device["context"]["Data"]["status"]["value"]);
+
+$AML->setClassifierConfs();
+
+?>
+
+
+
+
+
+
+
+
+
+
=$_GeniSys->_confs["meta_title"]; ?>
+
" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
AML Classifier #=$TId; ?>
+
+
+
+
+
+
+
+
+
+
+
+ dataFiles);
+ $count = 1;
+ if(count($images)):
+ foreach( $images as $image ):
+ echo "
";
+ if($count%6 == 0):
+ echo"
";
+ endif;
+ $count++;
+ endforeach;
+ else:
+ echo "
Please upload your test dataset.
";
+ endif;
+ ?>
+
+
+
+
+
+
+
+
+
+
+
+
Diagnosis Results
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Root/var/www/html/AI/AML/Create.php b/Root/var/www/html/AI/AML/Create.php
new file mode 100644
index 0000000..ff41465
--- /dev/null
+++ b/Root/var/www/html/AI/AML/Create.php
@@ -0,0 +1,422 @@
+ "AI",
+ "SubPageID" => "AIAML"
+];
+
+include dirname(__FILE__) . '/../../../Classes/Core/init.php';
+include dirname(__FILE__) . '/../../../Classes/Core/GeniSys.php';
+include dirname(__FILE__) . '/../../iotJumpWay/Classes/iotJumpWay.php';
+include dirname(__FILE__) . '/../../AI/AML/Classes/AML.php';
+include dirname(__FILE__) . '/../../AI/Classes/AI.php';
+
+$_GeniSysAi->checkSession();
+
+$Zones = $iotJumpWay->getZones();
+$Devices = $iotJumpWay->getDevices();
+
+?>
+
+
+
+
+
+
+
+
+
=$_GeniSys->_confs["meta_title"]; ?>
+
" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Create AML Classifier Device
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Root/var/www/html/Detection/ALL/CNN/Data/__init__.py b/Root/var/www/html/AI/AML/Data/.keep
similarity index 100%
rename from Root/var/www/html/Detection/ALL/CNN/Data/__init__.py
rename to Root/var/www/html/AI/AML/Data/.keep
diff --git a/Root/var/www/html/AI/AML/Device.php b/Root/var/www/html/AI/AML/Device.php
new file mode 100644
index 0000000..801f519
--- /dev/null
+++ b/Root/var/www/html/AI/AML/Device.php
@@ -0,0 +1,955 @@
+ "AI",
+ "SubPageID" => "AIAML"
+];
+
+include dirname(__FILE__) . '/../../../Classes/Core/init.php';
+include dirname(__FILE__) . '/../../../Classes/Core/GeniSys.php';
+include dirname(__FILE__) . '/../../iotJumpWay/Classes/iotJumpWay.php';
+include dirname(__FILE__) . '/../../AI/AML/Classes/AML.php';
+include dirname(__FILE__) . '/../../AI/Classes/AI.php';
+
+$_GeniSysAi->checkSession();
+
+$Locations = $iotJumpWay->getLocations();
+$Zones = $iotJumpWay->getZones();
+$Devices = $AML->getDevices();
+
+$TId = filter_input(INPUT_GET, 'device', FILTER_SANITIZE_NUMBER_INT);
+$Device = $iotJumpWay->getDevice($TId);
+
+list($dev1On, $dev1Off) = $iotJumpWay->getStatusShow($Device["context"]["Data"]["status"]["value"]);
+
+?>
+
+
+
+
+
+
+
+
+
+
=$_GeniSys->_confs["meta_title"]; ?>
+
" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
AML Classifier Device #=$TId; ?>
+
+
+
+
+
+
+
+
+
+
Device Schema
+
+
+
+
+
+
+
+
+
+
Device History
+
+
+
+
+
+
+
+
+
+
Device Transactions
+
+
+
+
+
+
+
+
+
+
Device iotJumpWay Statuses
+
+
+
+
+
+
+
+
+
+
+
+ ID
+ Status
+ Time
+
+
+
+
+ retrieveDeviceStatuses($Device["context"]["Data"]["did"]["value"], 5);
+ if($Statuses["Response"] == "OK"):
+ foreach($Statuses["ResponseData"] as $key => $value):
+ ?>
+
+
+ #=$value->_id;?>
+ =$value->Status;?>
+ =$value->Time;?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Device iotJumpWay Life
+
+
+
+
+
+
+
+
+
+
+
+ ID
+ Details
+ Time
+
+
+
+
+ retrieveDeviceLife($Device["context"]["Data"]["did"]["value"], 5);
+ if($Statuses["Response"] == "OK"):
+ foreach($Statuses["ResponseData"] as $key => $value):
+ ?>
+
+
+ #=$value->_id;?>
+
+ CPU : =$value->Data->CPU;?>%
+ Memory : =$value->Data->Memory;?>%
+ Diskspace : =$value->Data->Diskspace;?>%
+ Temperature : =$value->Data->Temperature;?>°C
+ Latitude : =$value->Data->Latitude;?>
+ Longitude : =$value->Data->Longitude;?>
+
+ =$value->Time;?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Device iotJumpWay Sensors
+
+
+
+
+
+
+
+
+
+
+
+ ID
+ Type
+ Sensor
+ Value
+ Message
+ Time
+
+
+
+
+ retrieveDeviceSensors($Device["context"]["Data"]["did"]["value"], 5);
+ if($Statuses["Response"] == "OK"):
+ foreach($Statuses["ResponseData"] as $key => $value):
+ $location = $iotJumpWay->getLocation($value->Location);
+ ?>
+
+ #=$value->_id;?>
+ =$value->Type;?>
+ =$value->Sensor;?>
+
+ Sensor == "Facial API" || $value->Sensor == "Foscam Camera" || $value->Sensor == "USB Camera") && is_array($value->Value)):
+ foreach($value->Value AS $key => $val):
+ echo $val[0] == 0 ? "Identification: Intruder " :"Identification: User #" . $val[0] . " ";
+ echo "Distance: " . $val[1] . " ";
+ echo "Message: " . $val[2] . " ";
+ endforeach;
+ else:
+ echo $value->Value;
+ endif;
+ ?>
+
+
+ =$value->Message;?>
+ =$value->Time;?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Device iotJumpWay Commands
+
+
+
+
+
+
+
+
+
+
+
+ ID
+ Details
+ Status
+ Time
+
+
+
+
+ retrieveDeviceCommands($Device["context"]["Data"]["did"]["value"], 5);
+ if($Statuses["Response"] == "OK"):
+ foreach($Statuses["ResponseData"] as $key => $value):
+ $location = $iotJumpWay->getLocation($value->Location);
+ ?>
+
+
+ #=$value->_id;?>
+ Location: #=$value->Location;?> - =$location["name"]; ?>
+ =$value->Status;?>
+ =$value->Time;?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Root/var/www/html/AI/AML/index.php b/Root/var/www/html/AI/AML/index.php
new file mode 100644
index 0000000..d09b012
--- /dev/null
+++ b/Root/var/www/html/AI/AML/index.php
@@ -0,0 +1,178 @@
+ "AI",
+ "SubPageID" => "AIAML"
+];
+
+include dirname(__FILE__) . '/../../../Classes/Core/init.php';
+include dirname(__FILE__) . '/../../../Classes/Core/GeniSys.php';
+include dirname(__FILE__) . '/../../iotJumpWay/Classes/iotJumpWay.php';
+include dirname(__FILE__) . '/../../AI/AML/Classes/AML.php';
+
+$_GeniSysAi->checkSession();
+$Devices = $AML->getDevices();
+
+?>
+
+
+
+
+
+
+
+
+
+
=$_GeniSys->_confs["meta_title"]; ?>
+
" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Acute Myeloid Leukemia (AML) Models
+
+
+
+
+
+
+
+
+
+
In addition to using Acute Myleoid Leukemia detection models created by the Peter Moss Acute Lymphoblastic & Lymphoblastic AI Research Project team, you can develop your own models and connect them up to the HIAS network.
+
+
+
+
+
+
+
Acute Myeloid Leukemia Detection Devices
+
+
+
+
+
+
+
+
+
+
+
+ ID
+ DETAILS
+ STATUS
+ ACTION
+
+
+
+
+ $value):
+ ?>
+
+
+ #=$value["did"]["value"];?>
+
+ Name: =$value["name"]["value"];?>
+ Zone: #=$value["zid"]["value"];?>
+
+
+ ">
+ =$value["status"]["value"] == "OFFLINE" ? "OFFLINE" : "ONLINE"; ?>
+
+
+ "> Edit | /Classify"> Classify
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Root/var/www/html/AI/COVID/Classes/COVID.js b/Root/var/www/html/AI/COVID/Classes/COVID.js
new file mode 100644
index 0000000..6e9c743
--- /dev/null
+++ b/Root/var/www/html/AI/COVID/Classes/COVID.js
@@ -0,0 +1,179 @@
+var COVID = {
+ Create: function() {
+ $.post(window.location.href, $("#aml_classifier").serialize(), function(resp) {
+ var resp = jQuery.parseJSON(resp);
+ switch (resp.Response) {
+ case "OK":
+ GeniSys.ResetForm("aml_classifier");
+ $('.modal-title').text('COVID Classifier Devices');
+ $('.modal-body').html("HIAS COVID Classifier Device ID #" + resp.GDID + " created! Please save the API keys safely. The device's credentials are provided below. The credentials can be reset in the GeniSyAI Security Devices area.
Device ID: " + resp.DID + "
MQTT User: " + resp.MU + "
MQTT Password: " + resp.MP + "
Blockchain User: " + resp.BU + "
Blockchain Pass: " + resp.BP + "
App ID: " + resp.AppID + "
App Key: " + resp.AppKey + "
" + resp.Message);
+ $('#responsive-modal').modal('show');
+ Logging.logMessage("Core", "Forms", "Device ID #" + resp.DID + " created!");
+ break;
+ default:
+ msg = "COVID Create Failed: " + resp.Message
+ Logging.logMessage("Core", "COVID", msg);
+ $('.modal-title').text('COVID Classifier Devices');
+ $('.modal-body').text(msg);
+ $('#responsive-modal').modal('show');
+ break;
+ }
+ });
+ },
+ Update: function() {
+ $.post(window.location.href, $("#aml_classifier_update").serialize(), function(resp) {
+ console.log(resp)
+ var resp = jQuery.parseJSON(resp);
+ switch (resp.Response) {
+ case "OK":
+ var fjson = JSON.stringify(resp.Schema, null, '\t');
+ window.parent.$('#schema').html(fjson);
+ Logging.logMessage("Core", "Forms", "Device Update OK");
+ $('.modal-title').text('COVID Classifier Devices');
+ $('.modal-body').text(resp.Message);
+ $('#responsive-modal').modal('show');
+ break;
+ default:
+ msg = "COVID Update Failed: " + resp.Message
+ Logging.logMessage("Core", "COVID", msg);
+ $('.modal-title').text('COVID Classifier Devices');
+ $('.modal-body').text(msg);
+ $('#responsive-modal').modal('show');
+ break;
+ }
+ });
+ },
+ deleteData: function() {
+ $.post(window.location.href, { "deleteData": 1 }, function(resp) {
+ console.log(resp)
+ var resp = jQuery.parseJSON(resp);
+ switch (resp.Response) {
+ case "OK":
+ $('#dataBlock').empty();
+ $('#dataBlock').html("
Please upload your test dataset.
");
+ break;
+ default:
+ break;
+ }
+ });
+ },
+ prepareUploadForm: function() {
+
+ var upper = document.querySelector('#dataup'),
+ form = new FormData(),
+ xhr = new XMLHttpRequest();
+
+ form.append('uploadAllData', 1);
+
+ upper.addEventListener('change', function(event) {
+ event.preventDefault();
+
+ var files = this.files;
+ for (var i = 0, n = files.length; i < n; i++) {
+ var file = files[i];
+
+ form.append('alldata[]', file, file.name);
+
+ xhr.onload = function() {
+ if (xhr.status === 200) {
+ console.log(xhr.response)
+ var resp = jQuery.parseJSON(xhr.response);
+ if (resp.Response === "OK") {
+ $('#dataBlock').empty();
+ $('#dataBlock').html(resp.Data);
+ $('.modal-title').text('Data Upload OK');
+ $('.modal-body').text(resp.Message);
+ $('#responsive-modal').modal('show');
+ COVID.setOpacity();
+ Logging.logMessage("Core", "Forms", resp.Message);
+ } else {
+ Logging.logMessage("Core", "Forms", resp.Message);
+ $('.modal-title').text('Data Upload Failed');
+ $('.modal-body').text(resp.Message);
+ $('#responsive-modal').modal('show');
+ }
+ }
+ }
+
+ xhr.open('POST', '');
+ xhr.send(form);
+ }
+ });
+ },
+ setOpacity: function() {
+ $('.classify').css("opacity", "1.0");
+ $('.classify').hover(function() {
+ $(this).stop().animate({ opacity: 0.2 }, "fast");
+ },
+ function() {
+ $(this).stop().animate({ opacity: 1.0 }, "fast");
+ });
+ },
+ classify: function(im) {
+
+ $('#imageView').html("
");
+ $("#imName").text(im);
+ var classification = '';
+ $("#imClass").html("
Diagnosis: WAITING FOR RESPONSE");
+ $("#imResult").html("
Result: WAITING FOR RESPONSE");
+ $.post(window.location.href, { "classifyData": 1, "im": im }, function(resp) {
+ console.log(resp)
+ var resp = jQuery.parseJSON(resp);
+ switch (resp.Response) {
+ case "OK":
+ if (im.indexOf("Non-Covid") >= 0 && resp.Diagnosis == "Negative") {
+ classification = "True Negative";
+ } else if (im.indexOf("Non-Covid") >= 0 && resp.Diagnosis == "Positive") {
+ classification = "False Positive";
+ } else if (im.indexOf("Non-Covid") < 0 && resp.Diagnosis == "Positive") {
+ classification = "True Positive";
+ } else if (im.indexOf("Non-Covid") < 0 && resp.Diagnosis == "Negative") {
+ classification = "False Negative";
+ }
+ $("#imClass").html("
Diagnosis: " + resp.Diagnosis);
+ if (resp.Confidence) {
+ $("#imConf").html("
Confidence: " + resp.Confidence);
+ } else {
+ $("#imConf").hide();
+ }
+ $("#imResult").html("
Result: " + classification);
+ break;
+ default:
+ break;
+ }
+ });
+
+ }
+};
+$(document).ready(function() {
+
+ $('#aml_classifier').validator().on('submit', function(e) {
+ if (!e.isDefaultPrevented()) {
+ e.preventDefault();
+ COVID.Create();
+ }
+ });
+
+ $('#aml_classifier_update').validator().on('submit', function(e) {
+ if (!e.isDefaultPrevented()) {
+ e.preventDefault();
+ COVID.Update();
+ }
+ });
+
+ $("#GeniSysAI").on("click", "#uploadData", function(e) {
+ e.preventDefault();
+ $('#dataup').trigger('click');
+ });
+
+ $("#GeniSysAI").on("click", "#deleteData", function(e) {
+ e.preventDefault();
+ COVID.deleteData();
+ });
+
+ $("#GeniSysAI").on("click", ".classify", function(e) {
+ e.preventDefault();
+ COVID.classify($(this).attr("id"));
+ });
+
+});
\ No newline at end of file
diff --git a/Root/var/www/html/AI/COVID/Classes/COVID.php b/Root/var/www/html/AI/COVID/Classes/COVID.php
new file mode 100644
index 0000000..4bd0ea4
--- /dev/null
+++ b/Root/var/www/html/AI/COVID/Classes/COVID.php
@@ -0,0 +1,1687 @@
+_GeniSys = $_GeniSys;
+ $this->bcc = $this->getBlockchainConf();
+ $this->web3 = $this->blockchainConnection();
+ $this->contract = new Contract($this->web3->provider, $this->bcc["abi"]);
+ $this->icontract = new Contract($this->web3->provider, $this->bcc["iabi"]);
+ $this->checkBlockchainPermissions();
+ endif;
+ $this->cb = $this->getContextBrokerConf();
+ }
+
+ public function setClassifierConfs()
+ {
+ $TId = filter_input(INPUT_GET, 'device', FILTER_SANITIZE_NUMBER_INT);
+ $Device = $this->getDevice($TId);
+
+ $this->dataDir = "Data/" . $Device["context"]["Data"]["dataset"]["folder"] . "/";
+ $this->dataDirFull = "/fserver/var/www/html/AI/COVID/";
+ $this->dataFiles = $this->dataDir . "*.{JPG,jpg,png,PNG,gif,GIF,tiff,tiff}";
+ $this->allowedFiles = ["jpg","JPG","png","PNG","gif","GIF","tiff","tiff"];
+ $this->api = $this->_GeniSys->_helpers->oDecrypt($this->_GeniSys->_confs["domainString"])."/AI/COVID/" . $Device["context"]["Data"]["proxy"]["endpoint"] . "/Inference";
+ }
+
+ public function getContextBrokerConf()
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM contextbroker
+ ");
+ $pdoQuery->execute();
+ $response=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+ return $response;
+ }
+
+ private function createContextHeaders()
+ {
+ $basicAuth = $_SESSION["GeniSysAI"]["User"] . ":" . $this->_GeniSys->_helpers->oDecrypt($_SESSION["GeniSysAI"]["Pass"]);
+ $basicAuth = base64_encode($basicAuth);
+
+ return [
+ "Content-Type: application/json",
+ 'Authorization: Basic '. $basicAuth
+ ];
+ }
+
+ private function contextBrokerRequest($method, $endpoint, $headers, $json)
+ {
+ $path = $this->_GeniSys->_helpers->oDecrypt($this->_GeniSys->_confs["domainString"]) . "/" . $this->cb["url"] . "/" . $endpoint;
+
+ if($method == "GET"):
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ curl_setopt($ch, CURLOPT_HEADER, 1);
+ curl_setopt($ch, CURLOPT_URL, $path);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ $response = curl_exec($ch);
+ $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
+ $header = substr($response, 0, $header_size);
+ $body = substr($response, $header_size);
+ curl_close($ch);
+ elseif($method == "POST"):
+ $ch = curl_init($path);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ curl_setopt($ch, CURLOPT_HEADER, 1);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
+ $response = curl_exec($ch);
+ $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
+ $header = substr($response, 0, $header_size);
+ $body = substr($response, $header_size);
+ curl_close($ch);
+ elseif($method == "PATCH"):
+ $ch = curl_init($path);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ curl_setopt($ch, CURLOPT_HEADER, 1);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
+ $response = curl_exec($ch);
+ $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
+ $header = substr($response, 0, $header_size);
+ $body = substr($response, $header_size);
+ curl_close($ch);
+ endif;
+
+ return $body;
+ }
+
+ public function getBlockchainConf()
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT blockchain.*,
+ contracts.contract,
+ contracts.abi,
+ icontracts.contract as icontract,
+ icontracts.abi as iabi
+ FROM blockchain blockchain
+ INNER JOIN contracts contracts
+ ON contracts.id = blockchain.dc
+ INNER JOIN contracts icontracts
+ ON icontracts.id = blockchain.ic
+ ");
+ $pdoQuery->execute();
+ $response=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+ return $response;
+ }
+
+ private function blockchainConnection()
+ {
+ if(isSet($_SESSION["GeniSysAI"]["Active"])):
+ $web3 = new Web3($this->_GeniSys->_helpers->oDecrypt($this->_GeniSys->_confs["domainString"]) . "/Blockchain/API/", 30, $_SESSION["GeniSysAI"]["User"], $this->_GeniSys->_helpers->oDecrypt($_SESSION["GeniSysAI"]["Pass"]));
+ return $web3;
+ endif;
+ }
+
+ private function checkBlockchainPermissions()
+ {
+ $allowed = "";
+ $errr = "";
+ $this->contract->at($this->_GeniSys->_helpers->oDecrypt($this->bcc["contract"]))->call("identifierAllowed", "User", $_SESSION["GeniSysAI"]["Identifier"], ["from" => $_SESSION["GeniSysAI"]["BC"]["BCUser"]], function ($err, $resp) use (&$allowed, &$errr) {
+ if ($err !== null) {
+ $allowed = "FAILED";
+ $errr = $err;
+ return;
+ }
+ $allowed = $resp;
+ });
+ if(!$allowed):
+ header('Location: /Logout');
+ endif;
+ }
+
+ private function unlockBlockchainAccount()
+ {
+ $response = "";
+ $personal = $this->web3->personal;
+ $personal->unlockAccount($_SESSION["GeniSysAI"]["BC"]["BCUser"], $this->_GeniSys->_helpers->oDecrypt($_SESSION["GeniSysAI"]["BC"]["BCPass"]), function ($err, $unlocked) use (&$response) {
+ if ($err !== null) {
+ $response = "FAILED! " . $err;
+ return;
+ }
+ if ($unlocked) {
+ $response = "OK";
+ } else {
+ $response = "FAILED";
+ }
+ });
+
+ return $response;
+ }
+
+ private function lockBlockchainAccount()
+ {
+ $response = "";
+ $personal = $this->web3->personal;
+ $personal->lockAccount($_SESSION["GeniSysAI"]["BC"]["BCUser"], function ($err, $unlocked) use (&$response) {
+ if ($err !== null) {
+ $response = "FAILED! " . $err;
+ return;
+ }
+ if ($unlocked) {
+ $response = "OK";
+ } else {
+ $response = "FAILED";
+ }
+ });
+
+ return $response;
+ }
+
+ private function createBlockchainUser($pass)
+ {
+ $newAccount = "";
+ $personal = $this->web3->personal;
+ $personal->newAccount($pass, function ($err, $account) use (&$newAccount) {
+ if ($err !== null) {
+ $newAccount = "FAILED!";
+ return;
+ }
+ $newAccount = $account;
+ });
+
+ return $newAccount;
+ }
+
+ private function getBlockchainBalance()
+ {
+ $nbalance = "";
+ $this->web3->eth->getBalance($_SESSION["GeniSysAI"]["BC"]["BCUser"], function ($err, $balance) use (&$nbalance) {
+ if ($err !== null) {
+ $response = "FAILED! " . $err;
+ return;
+ }
+ $nbalance = $balance->toString();
+ });
+
+ return Utils::fromWei($nbalance, 'ether')[0];
+ }
+
+ private function addAmqpUser($username, $key)
+ {
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO amqpu (
+ `username`,
+ `pw`
+ ) VALUES (
+ :username,
+ :pw
+ )
+ ");
+ $query->execute([
+ ':username' => $username,
+ ':pw' => $this->_GeniSys->_helpers->oEncrypt($key)
+ ]);
+ $amid = $this->_GeniSys->_secCon->lastInsertId();
+ return $amid;
+ }
+
+ private function addAmqpUserVh($uid, $vhost)
+ {
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO amqpvh (
+ `uid`,
+ `vhost`
+ ) VALUES (
+ :uid,
+ :vhost
+ )
+ ");
+ $query->execute([
+ ':uid' => $uid,
+ ':vhost' => $vhost
+ ]);
+ }
+
+ private function addAmqpVhPerm($uid, $vhost, $rtype, $rname, $permission)
+ {
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO amqpvhr (
+ `uid`,
+ `vhost`,
+ `rtype`,
+ `rname`,
+ `permission`
+ ) VALUES (
+ :uid,
+ :vhost,
+ :rtype,
+ :rname,
+ :permission
+ )
+ ");
+ $query->execute([
+ ':uid' => $uid,
+ ':vhost' => $vhost,
+ ':rtype' => $rtype,
+ ':rname' => $rname,
+ ':permission' => $permission
+ ]);
+ }
+
+ private function addAmqpVhTopic($uid, $vhost, $rtype, $rname, $permission, $rkey)
+ {
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO amqpvhrt (
+ `uid`,
+ `vhost`,
+ `rtype`,
+ `rname`,
+ `permission`,
+ `rkey`
+ ) VALUES (
+ :uid,
+ :vhost,
+ :rtype,
+ :rname,
+ :permission,
+ :rkey
+ )
+ ");
+ $query->execute([
+ ':uid' => $uid,
+ ':vhost' => $vhost,
+ ':rtype' => $rtype,
+ ':rname' => $rname,
+ ':permission' => $permission,
+ ':rkey' => $rkey
+ ]);
+ }
+
+ private function storeBlockchainTransaction($action, $hash, $device = 0, $application = 0)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO transactions (
+ `uid`,
+ `did`,
+ `aid`,
+ `action`,
+ `hash`,
+ `time`
+ ) VALUES (
+ :uid,
+ :did,
+ :aid,
+ :action,
+ :hash,
+ :time
+ )
+ ");
+ $pdoQuery->execute([
+ ":uid" => $_SESSION["GeniSysAI"]["Uid"],
+ ":did" => $device,
+ ":aid" => $application,
+ ":action" => $action,
+ ':hash' => $this->_GeniSys->_helpers->oEncrypt($hash),
+ ":time" => time()
+ ]);
+ $txid = $this->_GeniSys->_secCon->lastInsertId();
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ return $txid;
+ }
+
+ private function storeUserHistory($action, $hash, $location = 0, $zone = 0, $device = 0, $sensor = 0, $application = 0)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO history (
+ `uid`,
+ `tlid`,
+ `tzid`,
+ `tdid`,
+ `tsid`,
+ `taid`,
+ `action`,
+ `hash`,
+ `time`
+ ) VALUES (
+ :uid,
+ :tlid,
+ :tzid,
+ :tdid,
+ :tsid,
+ :taid,
+ :action,
+ :hash,
+ :time
+ )
+ ");
+ $pdoQuery->execute([
+ ":uid" => $_SESSION["GeniSysAI"]["Uid"],
+ ":tlid" => $location,
+ ":tzid" => $zone,
+ ":tdid" => $device,
+ ":tsid" => $sensor,
+ ":taid" => $application,
+ ":action" => $action,
+ ":hash" => $hash,
+ ":time" => time()
+ ]);
+ $txid = $this->_GeniSys->_secCon->lastInsertId();
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ return $txid;
+ }
+
+ public function checkLocation($lid)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT id
+ FROM mqttl
+ WHERE id = :id
+ ");
+ $pdoQuery->execute([
+ ":id" => $lid
+ ]);
+ $location=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($location["id"]):
+ return True;
+ else:
+ return False;
+ endif;
+ }
+
+ public function getLocation($id, $attrs = Null)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM mqttl
+ WHERE id = :id
+ ");
+ $pdoQuery->execute([
+ ":id" => $id
+ ]);
+ $location=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($attrs):
+ $attrs="&attrs=" . $attrs;
+ endif;
+
+ $location["context"] = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "/" . $location["pub"] . "?type=Location" . $attrs, $this->createContextHeaders(), []), true);
+ return $location;
+ }
+
+ public function checkZone($zid)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT id
+ FROM mqttlz
+ WHERE id = :id
+ ");
+ $pdoQuery->execute([
+ ":id" => $zid
+ ]);
+ $location=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($location["id"]):
+ return True;
+ else:
+ return False;
+ endif;
+ }
+
+ public function getZone($id, $attrs = Null)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM mqttlz
+ WHERE id = :id
+ ORDER BY id DESC
+ ");
+ $pdoQuery->execute([
+ ":id" => $id
+ ]);
+ $zone=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($attrs):
+ $attrs="&attrs=" . $attrs;
+ endif;
+
+ $zone["context"] = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "/" . $zone["pub"] . "?type=Zone" . $attrs, $this->createContextHeaders(), []), true);
+ return $zone;
+ }
+
+ public function getDevices($limit = 0)
+ {
+ $limiter = "";
+ if($limit != 0):
+ $limiter = "&limit=" . $limit;
+ endif;
+
+ $devices = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "?type=Device&category=COVIDClassifier".$limiter, $this->createContextHeaders(), []), true);
+ return $devices;
+ }
+
+ public function getDevice($id, $attrs = Null)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM mqttld
+ WHERE id = :id
+ ORDER BY id DESC
+ ");
+ $pdoQuery->execute([
+ ":id" => $id
+ ]);
+ $device=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($attrs):
+ $attrs="&attrs=" . $attrs;
+ endif;
+
+ $device["context"] = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "/" . $device["apub"] . "?type=Device" . $attrs, $this->createContextHeaders(), []), true);
+ return $device;
+ }
+
+ public function getThing($id, $attrs = Null)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM things
+ WHERE id = :id
+ ");
+ $pdoQuery->execute([
+ ":id" => $id
+ ]);
+ $thing=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($attrs):
+ $attrs="&attrs=" . $attrs;
+ endif;
+
+ $thing["context"] = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "/" . $thing["pub"] . "?type=Thing" . $attrs, $this->createContextHeaders(), []), true);
+ return $thing;
+ }
+
+ public function getModel($id, $attrs = Null)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM models
+ WHERE id = :id
+ ORDER BY id DESC
+ ");
+ $pdoQuery->execute([
+ ":id" => $id
+ ]);
+ $model=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($attrs):
+ $attrs="&attrs=" . $attrs;
+ endif;
+
+ $device["context"] = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "/" . $model["pub"] . "?type=Model" . $attrs, $this->createContextHeaders(), []), true);
+ return $device;
+ }
+
+ public function createDevice()
+ {
+ if(!filter_input(INPUT_POST, "lid", FILTER_SANITIZE_NUMBER_INT)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Location ID is required"
+ ];
+ endif;
+
+ if(!$this->checkLocation(filter_input(INPUT_POST, "lid", FILTER_SANITIZE_NUMBER_INT))):
+ return [
+ "Response"=> "Failed",
+ "Message" => "iotJumpWay location does not exist"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "zid", FILTER_SANITIZE_NUMBER_INT)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Zone ID is required"
+ ];
+ endif;
+
+ if(!$this->checkZone(filter_input(INPUT_POST, "zid", FILTER_SANITIZE_NUMBER_INT))):
+ return [
+ "Response"=> "Failed",
+ "Message" => "iotJumpWay zone does not exist"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "category", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Category is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "ctype", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Model type is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "agent", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "IoT Agent is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "name", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "description", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "deviceName", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Hardware device name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "deviceManufacturer", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Hardware device manufacturer is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "deviceModel", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Hardware device model is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osName", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osManufacturer", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system manufacturer is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osVersion", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system version is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "agent", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "IoT Agent is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "coordinates", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Coordinates entity is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "ip", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "IP is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "mac", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "MAC is required"
+ ];
+ endif;
+
+ if(!count($_POST["protocols"])):
+ return [
+ "Response"=> "Failed",
+ "Message" => "At least one M2M protocol is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "datasetUsed", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Dataset used is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "datasetLink", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Dataset link is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "datasetAuthor", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Dataset author is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "datasetFolder", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Dataset folder is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "relatedPaper", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Related paper is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "sport", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Device server port is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "endpoint", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Proxy endpoint is required"
+ ];
+ endif;
+
+ $unlocked = $this->unlockBlockchainAccount();
+
+ if($unlocked == "FAILED"):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Unlocking HIAS Blockhain Account Failed!"
+ ];
+ endif;
+
+ $mqttUser = $this->_GeniSys->_helpers->generate_uuid();
+ $mqttPass = $this->_GeniSys->_helpers->password();
+ $mqttHash = create_hash($mqttPass);
+
+ $pubKey = $this->_GeniSys->_helpers->generate_uuid();
+ $privKey = $this->_GeniSys->_helpers->generateKey(32);
+ $privKeyHash = $this->_GeniSys->_helpers->createPasswordHash($privKey);
+
+ $amqppubKey = $this->_GeniSys->_helpers->generate_uuid();
+ $amqpprvKey = $this->_GeniSys->_helpers->generateKey(32);
+ $amqpKeyHash = $this->_GeniSys->_helpers->createPasswordHash($amqpprvKey);
+
+ $bcPass = $this->_GeniSys->_helpers->password();
+
+ $lid = filter_input(INPUT_POST, 'lid', FILTER_SANITIZE_NUMBER_INT);
+ $location = $this->getLocation($lid);
+
+ $zid = filter_input(INPUT_POST, 'zid', FILTER_SANITIZE_NUMBER_INT);
+ $zone = $this->getZone($zid);
+
+ $ip = filter_input(INPUT_POST, "ip", FILTER_SANITIZE_STRING);
+ $mac = filter_input(INPUT_POST, "mac", FILTER_SANITIZE_STRING);
+ $bluetooth = filter_input(INPUT_POST, "bluetooth", FILTER_SANITIZE_STRING);
+ $name = filter_input(INPUT_POST, "name", FILTER_SANITIZE_STRING);
+ $coords = explode(",", filter_input(INPUT_POST, "coordinates", FILTER_SANITIZE_STRING));
+
+ mkdir("Data/" . filter_input(INPUT_POST, "datasetFolder", FILTER_SANITIZE_STRING), 0777, true);
+
+ $protocols = [];
+ foreach($_POST["protocols"] AS $key => $value):
+ $protocols[] = $value;
+ endforeach;
+
+ $models = [];
+ if(isSet($_POST["ai"])):
+ foreach($_POST["ai"] AS $key => $value):
+ $model = $this->getModel($value)["context"]["Data"];
+ $mname = $model["name"]["value"];
+ unset($model["id"]);
+ unset($model["type"]);
+ unset($model["mid"]);
+ unset($model["name"]);
+ unset($model["description"]);
+ unset($model["network"]);
+ unset($model["language"]);
+ unset($model["framework"]);
+ unset($model["toolkit"]);
+ unset($model["dateCreated"]);
+ unset($model["dateModified"]);
+ $models[$mname] = $model;
+ endforeach;
+ endif;
+
+ $sensors = [];
+ if(isSet($_POST["sensors"])):
+ foreach($_POST["sensors"] AS $key => $value):
+ $sensor = $this->getThing($value)["context"]["Data"];
+ unset($sensor["id"]);
+ unset($sensor["type"]);
+ unset($sensor["category"]);
+ unset($sensor["description"]);
+ unset($sensor["thing"]);
+ unset($sensor["properties"]["image"]);
+ unset($sensor["dateCreated"]);
+ unset($sensor["dateModified"]);
+ $sensors[] = $sensor;
+ endforeach;
+ endif;
+
+ $actuators = [];
+ if(isSet($_POST["actuators"])):
+ foreach($_POST["actuators"] AS $key => $value):
+ $actuator = $this->getThing($value)["context"]["Data"];
+ unset($actuator["id"]);
+ unset($actuator["type"]);
+ unset($actuator["category"]);
+ unset($actuator["description"]);
+ unset($actuator["thing"]);
+ unset($actuator["properties"]["image"]);
+ unset($actuator["dateCreated"]);
+ unset($actuator["dateModeified"]);
+ $actuators[] = $actuator;
+ endforeach;
+ endif;
+
+ $newBcUser = $this->createBlockchainUser($bcPass);
+
+ if($newBcUser == "FAILED"):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Creating New HIAS Blockhain Account Failed!"
+ ];
+ endif;
+
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO mqttld (
+ `apub`
+ ) VALUES (
+ :apub
+ )
+ ");
+ $query->execute([
+ ':apub' => $pubKey
+ ]);
+ $did = $this->_GeniSys->_secCon->lastInsertId();
+
+ $data = [
+ "id" => $pubKey,
+ "type" => "Device",
+ "category" => [
+ "value" => [filter_input(INPUT_POST, "category", FILTER_SANITIZE_STRING)]
+ ],
+ "name" => [
+ "value" => $name
+ ],
+ "description" => [
+ "value" => filter_input(INPUT_POST, "description", FILTER_SANITIZE_STRING)
+ ],
+ "lid" => [
+ "value" => $lid,
+ "entity" => $location["context"]["Data"]["id"]
+ ],
+ "zid" => [
+ "value" => $zid,
+ "entity" => $zone["context"]["Data"]["id"]
+ ],
+ "did" => [
+ "value" => $did
+ ],
+ "location" => [
+ "type" => "geo:json",
+ "value" => [
+ "type" => "Point",
+ "coordinates" => [floatval($coords[0]), floatval($coords[1])]
+ ]
+ ],
+ "agent" => [
+ "url" => filter_input(INPUT_POST, "agent", FILTER_SANITIZE_STRING)
+ ],
+ "paper" => [
+ "title" => filter_input(INPUT_POST, "relatedPaper", FILTER_SANITIZE_STRING),
+ "author" => filter_input(INPUT_POST, "relatedPaperAuthor", FILTER_SANITIZE_STRING),
+ "doi" => filter_input(INPUT_POST, "relatedPaperDOI", FILTER_SANITIZE_STRING),
+ "link" => filter_input(INPUT_POST, "relatedPaperLink", FILTER_SANITIZE_STRING)
+ ],
+ "dataset" => [
+ "name" => filter_input(INPUT_POST, "datasetUsed", FILTER_SANITIZE_STRING),
+ "author" => filter_input(INPUT_POST, "datasetAuthor", FILTER_SANITIZE_STRING),
+ "url" => filter_input(INPUT_POST, "datasetLink", FILTER_SANITIZE_STRING),
+ "folder" => filter_input(INPUT_POST, "datasetFolder", FILTER_SANITIZE_STRING)
+ ],
+ "device" => [
+ "type" => filter_input(INPUT_POST, "ctype", FILTER_SANITIZE_STRING),
+ "name" => filter_input(INPUT_POST, "deviceName", FILTER_SANITIZE_STRING),
+ "manufacturer" => filter_input(INPUT_POST, "deviceManufacturer", FILTER_SANITIZE_STRING),
+ "model" => filter_input(INPUT_POST, "deviceModel", FILTER_SANITIZE_STRING)
+ ],
+ "proxy" => [
+ "endpoint" => filter_input(INPUT_POST, "endpoint", FILTER_SANITIZE_STRING)
+ ],
+ "stream" => [
+ "port" => filter_input(INPUT_POST, "sport", FILTER_SANITIZE_STRING),
+ "file" => ""
+ ],
+ "socket" => [
+ "port" => ""
+ ],
+ "os" => [
+ "name" => filter_input(INPUT_POST, "osName", FILTER_SANITIZE_STRING),
+ "manufacturer" => filter_input(INPUT_POST, "osManufacturer", FILTER_SANITIZE_STRING),
+ "version" => filter_input(INPUT_POST, "osVersion", FILTER_SANITIZE_STRING)
+ ],
+ "protocols" => $protocols,
+ "status" => [
+ "value" => "OFFLINE",
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "keys" => [
+ "public" => $pubKey,
+ "private" => $this->_GeniSys->_helpers->oEncrypt($privKeyHash),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "blockchain" => [
+ "address" => $newBcUser,
+ "password" => $this->_GeniSys->_helpers->oEncrypt($bcPass)
+ ],
+ "mqtt" => [
+ "username" => $this->_GeniSys->_helpers->oEncrypt($mqttUser),
+ "password" => $this->_GeniSys->_helpers->oEncrypt($mqttPass),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "coap" => [
+ "username" => "",
+ "password" => ""
+ ],
+ "amqp" => [
+ "username" => $this->_GeniSys->_helpers->oEncrypt($amqppubKey),
+ "password" => $this->_GeniSys->_helpers->oEncrypt($amqpprvKey),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "batteryLevel" => [
+ "value" => 0.00
+ ],
+ "cpuUsage" => [
+ "value" => 0.00
+ ],
+ "memoryUsage" => [
+ "value" => 0.00
+ ],
+ "hddUsage" => [
+ "value" => 0.00
+ ],
+ "temperature" => [
+ "value" => 0.00
+ ],
+ "ip" => [
+ "value" => $this->_GeniSys->_helpers->oEncrypt($ip),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "mac" => [
+ "value" => $this->_GeniSys->_helpers->oEncrypt($mac),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "bluetooth" => [
+ "address" => $bluetooth ? $this->_GeniSys->_helpers->oEncrypt($bluetooth) : "",
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "ai" => $models,
+ "sensors" => $sensors,
+ "actuators" => $actuators,
+ "dateCreated" => [
+ "type" => "DateTime",
+ "value" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "dateFirstUsed" => [
+ "type" => "DateTime",
+ "value" => ""
+ ],
+ "dateModified" => [
+ "type" => "DateTime",
+ "value" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ]
+ ];
+
+ $response = json_decode($this->contextBrokerRequest("POST", $this->cb["entities_url"] . "?type=Device", $this->createContextHeaders(), json_encode($data)), true);
+
+ if($response["Response"]=="OK"):
+
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO mqttu (
+ `lid`,
+ `zid`,
+ `did`,
+ `uname`,
+ `pw`
+ ) VALUES (
+ :lid,
+ :zid,
+ :did,
+ :uname,
+ :pw
+ )
+ ");
+ $query->execute([
+ ':lid' => $lid,
+ ':zid' => $zid,
+ ':did' => $did,
+ ':uname' => $mqttUser,
+ ':pw' => $mqttHash
+ ]);
+
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO mqttua (
+ `lid`,
+ `zid`,
+ `did`,
+ `username`,
+ `topic`,
+ `rw`
+ ) VALUES (
+ :lid,
+ :zid,
+ :did,
+ :username,
+ :topic,
+ :rw
+ )
+ ");
+ $query->execute(array(
+ ':lid' => $lid,
+ ':zid' => $zid,
+ ':did' => $did,
+ ':username' => $mqttUser,
+ ':topic' => $location["context"]["Data"]["id"] . "/Devices/" . $zone["context"]["Data"]["id"] . "/" . $pubKey . "/#",
+ ':rw' => 4
+ ));
+
+ $amid = $this->addAmqpUser($amqppubKey, $amqpKeyHash);
+ $this->addAmqpUserVh($amid, "iotJumpWay");
+ $this->addAmqpVhPerm($amid, "iotJumpWay", "exchange", "Core", "read");
+ $this->addAmqpVhPerm($amid, "iotJumpWay", "exchange", "Core", "write");
+ $this->addAmqpVhPerm($amid, "iotJumpWay", "queue", "Life", "read");
+ $this->addAmqpVhPerm($amid, "iotJumpWay", "queue", "Life", "write");
+ $this->addAmqpVhPerm($amid, "iotJumpWay", "queue", "Statuses", "read");
+ $this->addAmqpVhPerm($amid, "iotJumpWay", "queue", "Statuses", "write");
+ $this->addAmqpVhTopic($amid, "iotJumpWay", "topic", "Core", "read", "Life");
+ $this->addAmqpVhTopic($amid, "iotJumpWay", "topic", "Core", "write", "Life");
+ $this->addAmqpVhTopic($amid, "iotJumpWay", "topic", "Core", "read", "Statuses");
+ $this->addAmqpVhTopic($amid, "iotJumpWay", "topic", "Core", "write", "Statuses");
+
+ $hash = "";
+ $msg = "";
+ $actionMsg = "";
+ $balanceMessage = "";
+ $this->contract->at($this->_GeniSys->_helpers->oDecrypt($this->bcc["contract"]))->send("registerDevice", $pubKey, $newBcUser, $lid, $zid, $did, $name, $_SESSION["GeniSysAI"]["Uid"], time(), ["from" => $_SESSION["GeniSysAI"]["BC"]["BCUser"]], function ($err, $resp) use (&$hash, &$msg) {
+ if ($err !== null) {
+ $hash = "FAILED";
+ $msg = $err;
+ return;
+ }
+ $hash = $resp;
+ });
+
+ if($hash == "FAILED"):
+ $actionMsg = " HIAS Blockchain registerDevice failed!\n" . $msg;
+ else:
+ $txid = $this->storeBlockchainTransaction("Register Device", $hash, $did);
+ $this->storeUserHistory("Register Device", $txid, $lid, $zid, $did);
+ $balance = $this->getBlockchainBalance();
+ $actionMsg = " HIAS Blockchain registerDevice OK!\n";
+ $balanceMessage = " You were rewarded for this action! Your balance is now: " . $balance . " HIAS Ether!";
+ endif;
+
+ $this->icontract->at($this->_GeniSys->_helpers->oDecrypt($this->bcc["icontract"]))->send("registerAuthorized", $newBcUser, ["from" => $_SESSION["GeniSysAI"]["BC"]["BCUser"]], function ($err, $resp) use (&$hash, &$msg) {
+ if ($err !== null) {
+ $hash = "FAILED";
+ $msg = $err;
+ return;
+ }
+ $hash = $resp;
+ });
+
+ if($hash == "FAILED"):
+ $actionMsg .= " HIAS Blockchain registerAuthorized failed! " . $msg;
+ else:
+ $txid = $this->storeBlockchainTransaction("iotJumpWay Register Authorized", $hash, $did);
+ $this->storeUserHistory("Register Authorized", $txid, $lid, $zid, $did);
+ $balance = $this->getBlockchainBalance();
+ $actionMsg .= " HIAS Blockchain registerAuthorized OK!\n";
+ $balanceMessage = " You were rewarded for this action! Your balance is now: " . $balance . " HIAS Ether!";
+ endif;
+
+ return [
+ "Response"=> "OK",
+ "Message" => "Device created!" . $actionMsg . $balanceMessage,
+ "LID" => filter_input(INPUT_POST, "lid", FILTER_SANITIZE_NUMBER_INT),
+ "ZID" => filter_input(INPUT_POST, "zid", FILTER_SANITIZE_NUMBER_INT),
+ "DID" => $did,
+ "MU" => $mqttUser,
+ "MP" => $mqttPass,
+ "BU" => $newBcUser,
+ "BP" => $bcPass,
+ "AppID" => $pubKey,
+ "AppKey" => $privKey
+ ];
+ else:
+ return [
+ "Response"=> "FAILED",
+ "Message" => "Device creating failed"
+ ];
+ endif;
+ }
+
+ public function updateDevice()
+ {
+ if(!filter_input(INPUT_POST, "lid", FILTER_SANITIZE_NUMBER_INT)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Location ID is required"
+ ];
+ endif;
+
+ if(!$this->checkLocation(filter_input(INPUT_POST, "lid", FILTER_SANITIZE_NUMBER_INT))):
+ return [
+ "Response"=> "Failed",
+ "Message" => "iotJumpWay location does not exist"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "zid", FILTER_SANITIZE_NUMBER_INT)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Zone ID is required"
+ ];
+ endif;
+
+ if(!$this->checkZone(filter_input(INPUT_POST, "zid", FILTER_SANITIZE_NUMBER_INT))):
+ return [
+ "Response"=> "Failed",
+ "Message" => "iotJumpWay zone does not exist"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "category", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Category is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "ctype", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Model type is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "agent", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "IoT Agent is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "name", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "description", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "deviceName", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Hardware device name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "deviceManufacturer", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Hardware device manufacturer is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "deviceModel", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Hardware device model is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osName", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osManufacturer", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system manufacturer is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osVersion", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system version is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "agent", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "IoT Agent is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "coordinates", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Coordinates entity is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "ip", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "IP is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "mac", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "MAC is required"
+ ];
+ endif;
+
+ if(!count($_POST["protocols"])):
+ return [
+ "Response"=> "Failed",
+ "Message" => "At least one M2M protocol is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "datasetUsed", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Dataset used is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "datasetLink", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Dataset link is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "datasetAuthor", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Dataset author is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "datasetFolder", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Dataset folder is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "relatedPaper", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Related paper is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "sport", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Device server port is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "endpoint", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Proxy endpoint is required"
+ ];
+ endif;
+
+ $unlocked = $this->unlockBlockchainAccount();
+
+ if($unlocked == "FAILED"):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Unlocking HIAS Blockhain Account Failed!"
+ ];
+ endif;
+
+ $ip = filter_input(INPUT_POST, "ip", FILTER_SANITIZE_STRING);
+ $mac = filter_input(INPUT_POST, "mac", FILTER_SANITIZE_STRING);
+ $bluetooth = filter_input(INPUT_POST, "bluetooth", FILTER_SANITIZE_STRING);
+ $name = filter_input(INPUT_POST, "name", FILTER_SANITIZE_STRING);
+ $status = filter_input(INPUT_POST, "status", FILTER_SANITIZE_STRING);
+ $coords = explode(",", filter_input(INPUT_POST, "coordinates", FILTER_SANITIZE_STRING));
+
+ $did = filter_input(INPUT_GET, "device", FILTER_SANITIZE_NUMBER_INT);
+ $device = $this->getDevice($did);
+
+ $lid = filter_input(INPUT_POST, 'lid', FILTER_SANITIZE_NUMBER_INT);
+ $location = $this->getLocation($lid);
+
+ $zid = filter_input(INPUT_POST, 'zid', FILTER_SANITIZE_NUMBER_INT);
+ $zone = $this->getZone($zid);
+
+ $protocols = [];
+ foreach($_POST["protocols"] AS $key => $value):
+ $protocols[] = $value;
+ endforeach;
+
+ $models = [];
+ if(isSet($_POST["ai"])):
+ foreach($_POST["ai"] AS $key => $value):
+ $model = $this->getModel($value)["context"]["Data"];
+ $mname = $model["name"]["value"];
+ unset($model["id"]);
+ unset($model["type"]);
+ unset($model["mid"]);
+ unset($model["name"]);
+ unset($model["description"]);
+ unset($model["network"]);
+ unset($model["language"]);
+ unset($model["framework"]);
+ unset($model["toolkit"]);
+ unset($model["dateCreated"]);
+ unset($model["dateModified"]);
+ $models[$mname] = $model;
+ endforeach;
+ endif;
+
+ $sensors = [];
+ if(isSet($_POST["sensors"])):
+ foreach($_POST["sensors"] AS $key => $value):
+ $sensor = $this->getThing($value)["context"]["Data"];
+ unset($sensor["id"]);
+ unset($sensor["type"]);
+ unset($sensor["category"]);
+ unset($sensor["description"]);
+ unset($sensor["thing"]);
+ unset($sensor["properties"]["image"]);
+ unset($sensor["dateCreated"]);
+ unset($sensor["dateModified"]);
+ $sensors[] = $sensor;
+ endforeach;
+ endif;
+
+ $actuators = [];
+ if(isSet($_POST["actuators"])):
+ foreach($_POST["actuators"] AS $key => $value):
+ $actuator = $this->getThing($value)["context"]["Data"];
+ unset($actuator["id"]);
+ unset($actuator["type"]);
+ unset($actuator["category"]);
+ unset($actuator["description"]);
+ unset($actuator["thing"]);
+ unset($actuator["properties"]["image"]);
+ unset($actuator["dateCreated"]);
+ unset($actuator["dateModeified"]);
+ $actuators[] = $actuator;
+ endforeach;
+ endif;
+
+ if($device["context"]["Data"]["lid"]["value"] != $lid):
+ $query = $this->_GeniSys->_secCon->prepare("
+ UPDATE mqttu
+ SET lid = :lid
+ WHERE did = :did
+ ");
+ $query->execute([
+ ':lid' => $lid,
+ ':did' => $did
+ ]);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ $query = $this->_GeniSys->_secCon->prepare("
+ UPDATE mqttua
+ SET lid = :lid
+ WHERE did = :did
+ ");
+ $query->execute([
+ ':lid' => $lid,
+ ':did' => $did
+ ]);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ $query = $this->_GeniSys->_secCon->prepare("
+ UPDATE mqttua
+ SET topic = :topicN
+ WHERE did = :did
+ & topic = :topic
+ ");
+ $query->execute([
+ ':topicN' => $device["context"]["Data"]["lid"]["entity"] . "/ " . $device["context"]["Data"]["zid"]["entity"] . "/Devices/" . $device["context"]["Data"]["id"] . "/#",
+ ':did' => $did,
+ ':topic' => $location["context"]["Data"]["id"] . "/Devices/" . $zone["context"]["Data"]["id"] . "/Devices/" . $device["context"]["Data"]["id"] . "/#"
+ ]);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+ endif;
+
+ $data = [
+ "category" => [
+ "value" => [filter_input(INPUT_POST, "category", FILTER_SANITIZE_STRING)]
+ ],
+ "name" => [
+ "value" => $name
+ ],
+ "description" => [
+ "value" => filter_input(INPUT_POST, "description", FILTER_SANITIZE_STRING)
+ ],
+ "lid" => [
+ "value" => $lid,
+ "entity" => $location["context"]["Data"]["id"]
+ ],
+ "zid" => [
+ "value" => $zid,
+ "entity" => $zone["context"]["Data"]["id"]
+ ],
+ "location" => [
+ "type" => "geo:json",
+ "value" => [
+ "type" => "Point",
+ "coordinates" => [floatval($coords[0]), floatval($coords[1])]
+ ]
+ ],
+ "agent" => [
+ "url" => filter_input(INPUT_POST, "agent", FILTER_SANITIZE_STRING)
+ ],
+ "paper" => [
+ "title" => filter_input(INPUT_POST, "relatedPaper", FILTER_SANITIZE_STRING),
+ "author" => filter_input(INPUT_POST, "relatedPaperAuthor", FILTER_SANITIZE_STRING),
+ "doi" => filter_input(INPUT_POST, "relatedPaperDOI", FILTER_SANITIZE_STRING),
+ "link" => filter_input(INPUT_POST, "relatedPaperLink", FILTER_SANITIZE_STRING)
+ ],
+ "dataset" => [
+ "name" => filter_input(INPUT_POST, "datasetUsed", FILTER_SANITIZE_STRING),
+ "author" => filter_input(INPUT_POST, "datasetAuthor", FILTER_SANITIZE_STRING),
+ "url" => filter_input(INPUT_POST, "datasetLink", FILTER_SANITIZE_STRING),
+ "folder" => filter_input(INPUT_POST, "datasetFolder", FILTER_SANITIZE_STRING)
+ ],
+ "device" => [
+ "type" => filter_input(INPUT_POST, "ctype", FILTER_SANITIZE_STRING),
+ "name" => filter_input(INPUT_POST, "deviceName", FILTER_SANITIZE_STRING),
+ "manufacturer" => filter_input(INPUT_POST, "deviceManufacturer", FILTER_SANITIZE_STRING),
+ "model" => filter_input(INPUT_POST, "deviceModel", FILTER_SANITIZE_STRING)
+ ],
+ "proxy" => [
+ "endpoint" => filter_input(INPUT_POST, "endpoint", FILTER_SANITIZE_STRING)
+ ],
+ "stream" => [
+ "port" => filter_input(INPUT_POST, "sport", FILTER_SANITIZE_STRING),
+ "file" => ""
+ ],
+ "socket" => [
+ "port" => ""
+ ],
+ "os" => [
+ "name" => filter_input(INPUT_POST, "osName", FILTER_SANITIZE_STRING),
+ "manufacturer" => filter_input(INPUT_POST, "osManufacturer", FILTER_SANITIZE_STRING),
+ "version" => filter_input(INPUT_POST, "osVersion", FILTER_SANITIZE_STRING)
+ ],
+ "protocols" => $protocols,
+ "ip" => [
+ "value" => $this->_GeniSys->_helpers->oEncrypt($ip),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "mac" => [
+ "value" => $this->_GeniSys->_helpers->oEncrypt($mac),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "bluetooth" => [
+ "address" => $bluetooth ? $this->_GeniSys->_helpers->oEncrypt($bluetooth) : "",
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "ai" => $models,
+ "sensors" => $sensors,
+ "actuators" => $actuators,
+ "dateModified" => [
+ "type" => "DateTime",
+ "value" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ]
+ ];
+
+ $response = json_decode($this->contextBrokerRequest("PATCH", $this->cb["entities_url"] . "/" . $device["context"]["Data"]["id"] . "/attrs?type=Device", $this->createContextHeaders(), json_encode($data)), true);
+
+ if($response["Response"]=="OK"):
+
+ $hash = "";
+ $msg = "";
+ $this->contract->at($this->_GeniSys->_helpers->oDecrypt($this->bcc["contract"]))->send("updateDevice", $device["context"]["Data"]["id"], "Device", $lid, $zid, $did, $name, $device["context"]["Data"]["status"]["value"], time(), ["from" => $_SESSION["GeniSysAI"]["BC"]["BCUser"]], function ($err, $resp) use (&$hash, &$msg) {
+ if ($err !== null) {
+ $hash = "FAILED";
+ $msg = $err;
+ return;
+ }
+ $hash = $resp;
+ });
+
+ $balance = "";
+ $balanceMessage = "";
+ $actionMsg = "";
+ if($hash == "FAILED"):
+ $actionMsg = " HIAS Blockchain updateDevice failed! " . $msg;
+ else:
+ $txid = $this->storeBlockchainTransaction("Update Device", $hash, $did);
+ $this->storeUserHistory("Updated Device", $txid, $lid, $zid, $did);
+ $balance = $this->getBlockchainBalance();
+ $balanceMessage = " You were rewarded for this action! Your balance is now: " . $balance . " HIAS Ether!";
+ endif;
+
+ $device = $this->getDevice($did);
+
+ return [
+ "Response"=> "OK",
+ "Message" => "Device updated!" . $actionMsg . $balanceMessage,
+ "Schema" => $device["context"]["Data"]
+ ];
+ else:
+ return [
+ "Response"=> "Failed",
+ "Message" => "There was a problem updating this device context data!"
+ ];
+ endif;
+ }
+
+ public function deleteData()
+ {
+ $images = glob($this->dataFiles);
+ foreach( $images as $image ):
+ unlink($image);
+ endforeach;
+
+ return [
+ "Response" => "OK",
+ "Message" => "Deleted Acute Lymphoblastic Leukemia Image Database for Image Processing Dataset"
+ ];
+
+ }
+
+ public function uploadData()
+ {
+ $dataCells = '';
+ if(is_array($_FILES) && !empty($_FILES['alldata'])):
+ foreach($_FILES['alldata']['name'] as $key => $filename):
+ $file_name = explode(".", $filename);
+ if(in_array($file_name[1], $this->allowedFiles)):
+ $sourcePath = $_FILES["alldata"]["tmp_name"][$key];
+ $targetPath = $this->dataDir . $filename;
+ if(!move_uploaded_file($sourcePath, $targetPath)):
+ return [
+ "Response" => "FAILED",
+ "Message" => "Upload failed " . $targetPath
+ ];
+ endif;
+ else:
+ return [
+ "Response" => "FAILED",
+ "Message" => "Please upload jpg files"
+ ];
+ endif;
+ endforeach;
+
+ $images = glob($this->dataFiles, GLOB_BRACE);
+ $count = 1;
+ foreach($images as $image):
+ $dataCells .= "
";
+ if($count%6 == 0):
+ $dataCells .= "
";
+ endif;
+ $count++;
+ endforeach;
+
+ else:
+ return [
+ "Response" => "FAILED",
+ "Message" => "You must upload some images (jpg)"
+ ];
+ endif;
+
+ return [
+ "Response" => "OK",
+ "Message" => "Data upload OK!",
+ "Data" => $dataCells
+ ];
+
+ }
+
+ public function classifyData()
+ {
+ $file = $this->dataDirFull . filter_input(INPUT_POST, "im", FILTER_SANITIZE_STRING);
+ $mime = mime_content_type($file);
+ $info = pathinfo($file);
+ $name = $info['basename'];
+ $toSend = new CURLFile($file, $mime, $name);
+
+ $headers = [
+ 'Authorization: Basic '. base64_encode($_SESSION["GeniSysAI"]["User"] . ":" . $this->_GeniSys->_helpers->oDecrypt($_SESSION["GeniSysAI"]["Pass"]))
+ ];
+
+ $ch = curl_init($this->api);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_POST, true);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, [
+ 'file'=> $toSend,
+ ]);
+
+ $resp = curl_exec($ch);
+
+ return json_decode($resp, true);
+
+ }
+
+ }
+
+ $COVID = new COVID($_GeniSys);
+
+ if(filter_input(INPUT_POST, "create_aml_classifier", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($COVID->createDevice()));
+ endif;
+
+ if(filter_input(INPUT_POST, "update_aml_classifier", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($COVID->updateDevice()));
+ endif;
+
+ if(filter_input(INPUT_POST, "reset_mqtt", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($COVID->resetMqtt()));
+ endif;
+
+ if(filter_input(INPUT_POST, "reset_key", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($COVID->resetDvcKey()));
+ endif;
+
+ if(filter_input(INPUT_POST, "get_tlife", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($COVID->getLife()));
+ endif;
+
+ if(filter_input(INPUT_POST, "deleteData", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($COVID->deleteData()));
+ endif;
+
+ if(filter_input(INPUT_POST, "uploadAllData", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($COVID->uploadData()));
+ endif;
+
+ if(filter_input(INPUT_POST, "classifyData", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($COVID->classifyData()));
+ endif;
diff --git a/Root/var/www/html/AI/COVID/Classify.php b/Root/var/www/html/AI/COVID/Classify.php
new file mode 100644
index 0000000..3306924
--- /dev/null
+++ b/Root/var/www/html/AI/COVID/Classify.php
@@ -0,0 +1,202 @@
+ "AI",
+ "SubPageID" => "AICOVID"
+];
+
+include dirname(__FILE__) . '/../../../Classes/Core/init.php';
+include dirname(__FILE__) . '/../../../Classes/Core/GeniSys.php';
+include dirname(__FILE__) . '/../../iotJumpWay/Classes/iotJumpWay.php';
+include dirname(__FILE__) . '/../../AI/COVID/Classes/COVID.php';
+
+$_GeniSysAi->checkSession();
+
+$Locations = $iotJumpWay->getLocations();
+$Zones = $iotJumpWay->getZones();
+$Devices = $COVID->getDevices();
+
+$TId = filter_input(INPUT_GET, 'device', FILTER_SANITIZE_NUMBER_INT);
+$Device = $iotJumpWay->getDevice($TId);
+
+list($dev1On, $dev1Off) = $iotJumpWay->getStatusShow($Device["context"]["Data"]["status"]["value"]);
+
+$COVID->setClassifierConfs();
+
+?>
+
+
+
+
+
+
+
+
+
+
=$_GeniSys->_confs["meta_title"]; ?>
+
" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
COVID Classifier #=$TId; ?>
+
+
+
+
+
+
+
+
+
+
+
+ dataFiles, GLOB_BRACE);
+ $count = 1;
+ if(count($images)):
+ foreach( $images as $image ):
+ echo "
";
+ if($count%6 == 0):
+ echo"
";
+ endif;
+ $count++;
+ endforeach;
+ else:
+ echo "
Please upload your test dataset.
";
+ endif;
+ ?>
+
+
+
+
+
+
+
+
+
+
+
+
Diagnosis Results
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Root/var/www/html/AI/COVID/Create.php b/Root/var/www/html/AI/COVID/Create.php
new file mode 100644
index 0000000..750bfae
--- /dev/null
+++ b/Root/var/www/html/AI/COVID/Create.php
@@ -0,0 +1,422 @@
+ "AI",
+ "SubPageID" => "AICOVID"
+];
+
+include dirname(__FILE__) . '/../../../Classes/Core/init.php';
+include dirname(__FILE__) . '/../../../Classes/Core/GeniSys.php';
+include dirname(__FILE__) . '/../../iotJumpWay/Classes/iotJumpWay.php';
+include dirname(__FILE__) . '/../../AI/COVID/Classes/COVID.php';
+include dirname(__FILE__) . '/../../AI/Classes/AI.php';
+
+$_GeniSysAi->checkSession();
+
+$Zones = $iotJumpWay->getZones();
+$Devices = $iotJumpWay->getDevices();
+
+?>
+
+
+
+
+
+
+
+
+
=$_GeniSys->_confs["meta_title"]; ?>
+
" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Create COVID Classifier Device
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Root/var/www/html/Detection/COVID-19/CNN/Data/__init__.py b/Root/var/www/html/AI/COVID/Data/.keep
similarity index 100%
rename from Root/var/www/html/Detection/COVID-19/CNN/Data/__init__.py
rename to Root/var/www/html/AI/COVID/Data/.keep
diff --git a/Root/var/www/html/AI/COVID/Device.php b/Root/var/www/html/AI/COVID/Device.php
new file mode 100644
index 0000000..6b2f1e1
--- /dev/null
+++ b/Root/var/www/html/AI/COVID/Device.php
@@ -0,0 +1,955 @@
+ "AI",
+ "SubPageID" => "AICOVID"
+];
+
+include dirname(__FILE__) . '/../../../Classes/Core/init.php';
+include dirname(__FILE__) . '/../../../Classes/Core/GeniSys.php';
+include dirname(__FILE__) . '/../../iotJumpWay/Classes/iotJumpWay.php';
+include dirname(__FILE__) . '/../../AI/COVID/Classes/COVID.php';
+include dirname(__FILE__) . '/../../AI/Classes/AI.php';
+
+$_GeniSysAi->checkSession();
+
+$Locations = $iotJumpWay->getLocations();
+$Zones = $iotJumpWay->getZones();
+$Devices = $COVID->getDevices();
+
+$TId = filter_input(INPUT_GET, 'device', FILTER_SANITIZE_NUMBER_INT);
+$Device = $iotJumpWay->getDevice($TId);
+
+list($dev1On, $dev1Off) = $iotJumpWay->getStatusShow($Device["context"]["Data"]["status"]["value"]);
+
+?>
+
+
+
+
+
+
+
+
+
+
=$_GeniSys->_confs["meta_title"]; ?>
+
" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
COVID Classifier Device #=$TId; ?>
+
+
+
+
+
+
+
+
+
+
Device Schema
+
+
+
+
+
+
+
+
+
+
Device History
+
+
+
+
+
+
+
+
+
+
Device Transactions
+
+
+
+
+
+
+
+
+
+
Device iotJumpWay Statuses
+
+
+
+
+
+
+
+
+
+
+
+ ID
+ Status
+ Time
+
+
+
+
+ retrieveDeviceStatuses($Device["context"]["Data"]["did"]["value"], 5);
+ if($Statuses["Response"] == "OK"):
+ foreach($Statuses["ResponseData"] as $key => $value):
+ ?>
+
+
+ #=$value->_id;?>
+ =$value->Status;?>
+ =$value->Time;?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Device iotJumpWay Life
+
+
+
+
+
+
+
+
+
+
+
+ ID
+ Details
+ Time
+
+
+
+
+ retrieveDeviceLife($Device["context"]["Data"]["did"]["value"], 5);
+ if($Statuses["Response"] == "OK"):
+ foreach($Statuses["ResponseData"] as $key => $value):
+ ?>
+
+
+ #=$value->_id;?>
+
+ CPU : =$value->Data->CPU;?>%
+ Memory : =$value->Data->Memory;?>%
+ Diskspace : =$value->Data->Diskspace;?>%
+ Temperature : =$value->Data->Temperature;?>°C
+ Latitude : =$value->Data->Latitude;?>
+ Longitude : =$value->Data->Longitude;?>
+
+ =$value->Time;?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Device iotJumpWay Sensors
+
+
+
+
+
+
+
+
+
+
+
+ ID
+ Type
+ Sensor
+ Value
+ Message
+ Time
+
+
+
+
+ retrieveDeviceSensors($Device["context"]["Data"]["did"]["value"], 5);
+ if($Statuses["Response"] == "OK"):
+ foreach($Statuses["ResponseData"] as $key => $value):
+ $location = $iotJumpWay->getLocation($value->Location);
+ ?>
+
+ #=$value->_id;?>
+ =$value->Type;?>
+ =$value->Sensor;?>
+
+ Sensor == "Facial API" || $value->Sensor == "Foscam Camera" || $value->Sensor == "USB Camera") && is_array($value->Value)):
+ foreach($value->Value AS $key => $val):
+ echo $val[0] == 0 ? "Identification: Intruder " :"Identification: User #" . $val[0] . " ";
+ echo "Distance: " . $val[1] . " ";
+ echo "Message: " . $val[2] . " ";
+ endforeach;
+ else:
+ echo $value->Value;
+ endif;
+ ?>
+
+
+ =$value->Message;?>
+ =$value->Time;?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Device iotJumpWay Commands
+
+
+
+
+
+
+
+
+
+
+
+ ID
+ Details
+ Status
+ Time
+
+
+
+
+ retrieveDeviceCommands($Device["context"]["Data"]["did"]["value"], 5);
+ if($Statuses["Response"] == "OK"):
+ foreach($Statuses["ResponseData"] as $key => $value):
+ $location = $iotJumpWay->getLocation($value->Location);
+ ?>
+
+
+ #=$value->_id;?>
+ Location: #=$value->Location;?> - =$location["name"]; ?>
+ =$value->Status;?>
+ =$value->Time;?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Root/var/www/html/AI/COVID/index.php b/Root/var/www/html/AI/COVID/index.php
new file mode 100644
index 0000000..839e67b
--- /dev/null
+++ b/Root/var/www/html/AI/COVID/index.php
@@ -0,0 +1,179 @@
+ "AI",
+ "SubPageID" => "AICOVID"
+];
+
+include dirname(__FILE__) . '/../../../Classes/Core/init.php';
+include dirname(__FILE__) . '/../../../Classes/Core/GeniSys.php';
+include dirname(__FILE__) . '/../../iotJumpWay/Classes/iotJumpWay.php';
+include dirname(__FILE__) . '/../../AI/COVID/Classes/COVID.php';
+
+$_GeniSysAi->checkSession();
+$Devices = $COVID->getDevices();
+
+?>
+
+
+
+
+
+
+
+
+
+
=$_GeniSys->_confs["meta_title"]; ?>
+
" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
COVID-19 (SARS-CoV-2) Models
+
+
+
+
+
+
+
+
+
+
In addition to using COVID-19 (SARS-CoV-2) detection models created by the Peter Moss COVID-19 AI Research Project team, you can develop your own models and connect them up to the HIAS network.
+
+
+
+
+
+
+
COVID-19 (SARS-CoV-2) Devices
+
+
+
+
+
+
+
+
+
+
+
+ ID
+ DETAILS
+ STATUS
+ ACTION
+
+
+
+
+ $value):
+ ?>
+
+
+ #=$value["did"]["value"];?>
+
+ Name: =$value["name"]["value"];?>
+ Zone: #=$value["zid"]["value"];?>
+
+
+ ">
+ =$value["status"]["value"] == "OFFLINE" ? "OFFLINE" : "ONLINE"; ?>
+
+
+ "> Edit | /Classify"> Classify
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Root/var/www/html/AI/Classes/AI.js b/Root/var/www/html/AI/Classes/AI.js
new file mode 100644
index 0000000..27750af
--- /dev/null
+++ b/Root/var/www/html/AI/Classes/AI.js
@@ -0,0 +1,128 @@
+var AI = {
+ Create: function() {
+ $.post(window.location.href, $("#ai_model").serialize(), function(resp) {
+ var resp = jQuery.parseJSON(resp);
+ switch (resp.Response) {
+ case "OK":
+ GeniSys.ResetForm("ai_model");
+ $('.modal-title').text('AI Models');
+ $('.modal-body').html("HIAS AI Model created!");
+ $('#responsive-modal').modal('show');
+ Logging.logMessage("Core", "Forms", "HIAS AI Model created!");
+ break;
+ default:
+ msg = "AI Model Create Failed: " + resp.Message
+ Logging.logMessage("Core", "AI", msg);
+ $('.modal-title').text('AI Models');
+ $('.modal-body').text(msg);
+ $('#responsive-modal').modal('show');
+ break;
+ }
+ });
+ },
+ Update: function() {
+ $.post(window.location.href, $("#model_update").serialize(), function(resp) {
+ console.log(resp)
+ var resp = jQuery.parseJSON(resp);
+ switch (resp.Response) {
+ case "OK":
+ var fjson = JSON.stringify(resp.Schema, null, '\t');
+ window.parent.$('#schema').html(fjson);
+ Logging.logMessage("Core", "AI", resp.Message);
+ $('.modal-title').text('AI Models');
+ $('.modal-body').text(resp.Message);
+ $('#responsive-modal').modal('show');
+ break;
+ default:
+ msg = "AI Update Failed: " + resp.Message
+ Logging.logMessage("Core", "AI", msg);
+ $('.modal-title').text('AI Models');
+ $('.modal-body').text(msg);
+ $('#responsive-modal').modal('show');
+ break;
+ }
+ });
+ },
+};
+$(document).ready(function() {
+
+ $("#GeniSysAI").on("click", ".removeModelProperty", function(e) {
+ e.preventDefault();
+ $('#model-property-' + $(this).data('id')).fadeOut(300, function() { $(this).remove(); });
+ });
+
+ $("#GeniSysAI").on("click", ".removeModelCommand", function(e) {
+ e.preventDefault();
+ $('#model-command-' + $(this).data('id')).fadeOut(300, function() { $(this).remove(); });
+ });
+
+ $("#GeniSysAI").on("click", ".removeModelState", function(e) {
+ e.preventDefault();
+ $('#model-state-' + $(this).data('id')).fadeOut(300, function() { $(this).remove(); });
+ });
+
+ $("#GeniSysAI").on("click", "#addModelProperty", function(e) {
+ e.preventDefault();
+ $('.modal-title').text('Add Property');
+ $('.modal-footer button').text('OK');
+ $('#buttonId').button('option', 'label', 'OK');
+ $('.modal-body').html("
");
+ $('#responsive-modal').modal('show');
+ $('#responsive-modal').on('hide.bs.modal', function() {
+ if ($("#addPropertyKey").val()) {
+ var addProperty = '
';
+ $("#propertyContent").append(addProperty);
+ $('.modal-body').html("");
+ }
+ })
+ });
+
+ $("#GeniSysAI").on("click", "#addModelCommand", function(e) {
+ e.preventDefault();
+ $('.modal-title').text('Add Command');
+ $('.modal-footer button').text('OK');
+ $('#buttonId').button('option', 'label', 'OK');
+ $('.modal-body').html("
");
+ $('#responsive-modal').modal('show');
+ $('#responsive-modal').on('hide.bs.modal', function() {
+ if ($("#addCommandKey").val() && $("#addCommandValue").val()) {
+ var addCommand = '
';
+ $("#commandsContent").append(addCommand);
+ $('.modal-body').html("");
+ }
+ })
+ });
+
+ $("#GeniSysAI").on("click", "#addModelState", function(e) {
+ e.preventDefault();
+ $('.modal-title').text('Add State');
+ $('.modal-footer button').text('OK');
+ $('#buttonId').button('option', 'label', 'OK');
+ $('.modal-body').html("
");
+ $('#responsive-modal').modal('show');
+ $('#responsive-modal').on('hide.bs.modal', function() {
+ if ($("#addStateValue").val()) {
+ var key = (parseInt($("#lastState").text()) + 1);
+ var addState = '
';
+ $("#stateContent").append(addState);
+ $('.modal-body').html("");
+ $("#lastState").text(key);
+ }
+ })
+ });
+
+ $('#ai_model').validator().on('submit', function(e) {
+ if (!e.isDefaultPrevented()) {
+ e.preventDefault();
+ AI.Create();
+ }
+ });
+
+ $('#model_update').validator().on('submit', function(e) {
+ if (!e.isDefaultPrevented()) {
+ e.preventDefault();
+ AI.Update();
+ }
+ });
+
+});
\ No newline at end of file
diff --git a/Root/var/www/html/AI/Classes/AI.php b/Root/var/www/html/AI/Classes/AI.php
new file mode 100644
index 0000000..6e5b988
--- /dev/null
+++ b/Root/var/www/html/AI/Classes/AI.php
@@ -0,0 +1,704 @@
+_GeniSys = $_GeniSys;
+ $this->bcc = $this->getBlockchainConf();
+ $this->web3 = $this->blockchainConnection();
+ $this->contract = new Contract($this->web3->provider, $this->bcc["abi"]);
+ $this->icontract = new Contract($this->web3->provider, $this->bcc["iabi"]);
+ $this->checkBlockchainPermissions();
+ endif;
+ $this->cb = $this->getContextBrokerConf();
+ }
+
+ public function getContextBrokerConf()
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM contextbroker
+ ");
+ $pdoQuery->execute();
+ $response=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+ return $response;
+ }
+
+ private function createContextHeaders()
+ {
+ $basicAuth = $_SESSION["GeniSysAI"]["User"] . ":" . $this->_GeniSys->_helpers->oDecrypt($_SESSION["GeniSysAI"]["Pass"]);
+ $basicAuth = base64_encode($basicAuth);
+
+ return [
+ "Content-Type: application/json",
+ 'Authorization: Basic '. $basicAuth
+ ];
+ }
+
+ private function contextBrokerRequest($method, $endpoint, $headers, $json)
+ {
+ $path = $this->_GeniSys->_helpers->oDecrypt($this->_GeniSys->_confs["domainString"]) . "/" . $this->cb["url"] . "/" . $endpoint;
+
+ if($method == "GET"):
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ curl_setopt($ch, CURLOPT_HEADER, 1);
+ curl_setopt($ch, CURLOPT_URL, $path);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ $response = curl_exec($ch);
+ $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
+ $header = substr($response, 0, $header_size);
+ $body = substr($response, $header_size);
+ curl_close($ch);
+ elseif($method == "POST"):
+ $ch = curl_init($path);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ curl_setopt($ch, CURLOPT_HEADER, 1);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
+ $response = curl_exec($ch);
+ $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
+ $header = substr($response, 0, $header_size);
+ $body = substr($response, $header_size);
+ curl_close($ch);
+ elseif($method == "PATCH"):
+ $ch = curl_init($path);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ curl_setopt($ch, CURLOPT_HEADER, 1);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
+ $response = curl_exec($ch);
+ $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
+ $header = substr($response, 0, $header_size);
+ $body = substr($response, $header_size);
+ curl_close($ch);
+ endif;
+
+ return $body;
+ }
+
+ public function getBlockchainConf()
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT blockchain.*,
+ contracts.contract,
+ contracts.abi,
+ icontracts.contract as icontract,
+ icontracts.abi as iabi
+ FROM blockchain blockchain
+ INNER JOIN contracts contracts
+ ON contracts.id = blockchain.dc
+ INNER JOIN contracts icontracts
+ ON icontracts.id = blockchain.ic
+ ");
+ $pdoQuery->execute();
+ $response=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+ return $response;
+ }
+
+ private function blockchainConnection()
+ {
+ if(isSet($_SESSION["GeniSysAI"]["Active"])):
+ $web3 = new Web3($this->_GeniSys->_helpers->oDecrypt($this->_GeniSys->_confs["domainString"]) . "/Blockchain/API/", 30, $_SESSION["GeniSysAI"]["User"], $this->_GeniSys->_helpers->oDecrypt($_SESSION["GeniSysAI"]["Pass"]));
+ return $web3;
+ endif;
+ }
+
+ private function checkBlockchainPermissions()
+ {
+ $allowed = "";
+ $errr = "";
+ $this->contract->at($this->_GeniSys->_helpers->oDecrypt($this->bcc["contract"]))->call("identifierAllowed", "User", $_SESSION["GeniSysAI"]["Identifier"], ["from" => $_SESSION["GeniSysAI"]["BC"]["BCUser"]], function ($err, $resp) use (&$allowed, &$errr) {
+ if ($err !== null) {
+ $allowed = "FAILED";
+ $errr = $err;
+ return;
+ }
+ $allowed = $resp;
+ });
+ if(!$allowed):
+ header('Location: /Logout');
+ endif;
+ }
+
+ private function unlockBlockchainAccount()
+ {
+ $response = "";
+ $personal = $this->web3->personal;
+ $personal->unlockAccount($_SESSION["GeniSysAI"]["BC"]["BCUser"], $this->_GeniSys->_helpers->oDecrypt($_SESSION["GeniSysAI"]["BC"]["BCPass"]), function ($err, $unlocked) use (&$response) {
+ if ($err !== null) {
+ $response = "FAILED! " . $err;
+ return;
+ }
+ if ($unlocked) {
+ $response = "OK";
+ } else {
+ $response = "FAILED";
+ }
+ });
+
+ return $response;
+ }
+
+ private function lockBlockchainAccount()
+ {
+ $response = "";
+ $personal = $this->web3->personal;
+ $personal->lockAccount($_SESSION["GeniSysAI"]["BC"]["BCUser"], function ($err, $unlocked) use (&$response) {
+ if ($err !== null) {
+ $response = "FAILED! " . $err;
+ return;
+ }
+ if ($unlocked) {
+ $response = "OK";
+ } else {
+ $response = "FAILED";
+ }
+ });
+
+ return $response;
+ }
+
+ private function createBlockchainUser($pass)
+ {
+ $newAccount = "";
+ $personal = $this->web3->personal;
+ $personal->newAccount($pass, function ($err, $account) use (&$newAccount) {
+ if ($err !== null) {
+ $newAccount = "FAILED!";
+ return;
+ }
+ $newAccount = $account;
+ });
+
+ return $newAccount;
+ }
+
+ private function getBlockchainBalance()
+ {
+ $nbalance = "";
+ $this->web3->eth->getBalance($_SESSION["GeniSysAI"]["BC"]["BCUser"], function ($err, $balance) use (&$nbalance) {
+ if ($err !== null) {
+ $response = "FAILED! " . $err;
+ return;
+ }
+ $nbalance = $balance->toString();
+ });
+
+ return Utils::fromWei($nbalance, 'ether')[0];
+ }
+
+ private function addAmqpUser($username, $key)
+ {
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO amqpu (
+ `username`,
+ `pw`
+ ) VALUES (
+ :username,
+ :pw
+ )
+ ");
+ $query->execute([
+ ':username' => $username,
+ ':pw' => $this->_GeniSys->_helpers->oEncrypt($key)
+ ]);
+ $amid = $this->_GeniSys->_secCon->lastInsertId();
+ return $amid;
+ }
+
+ private function addAmqpUserVh($uid, $vhost)
+ {
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO amqpvh (
+ `uid`,
+ `vhost`
+ ) VALUES (
+ :uid,
+ :vhost
+ )
+ ");
+ $query->execute([
+ ':uid' => $uid,
+ ':vhost' => $vhost
+ ]);
+ }
+
+ private function addAmqpVhPerm($uid, $vhost, $rtype, $rname, $permission)
+ {
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO amqpvhr (
+ `uid`,
+ `vhost`,
+ `rtype`,
+ `rname`,
+ `permission`
+ ) VALUES (
+ :uid,
+ :vhost,
+ :rtype,
+ :rname,
+ :permission
+ )
+ ");
+ $query->execute([
+ ':uid' => $uid,
+ ':vhost' => $vhost,
+ ':rtype' => $rtype,
+ ':rname' => $rname,
+ ':permission' => $permission
+ ]);
+ }
+
+ private function addAmqpVhTopic($uid, $vhost, $rtype, $rname, $permission, $rkey)
+ {
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO amqpvhrt (
+ `uid`,
+ `vhost`,
+ `rtype`,
+ `rname`,
+ `permission`,
+ `rkey`
+ ) VALUES (
+ :uid,
+ :vhost,
+ :rtype,
+ :rname,
+ :permission,
+ :rkey
+ )
+ ");
+ $query->execute([
+ ':uid' => $uid,
+ ':vhost' => $vhost,
+ ':rtype' => $rtype,
+ ':rname' => $rname,
+ ':permission' => $permission,
+ ':rkey' => $rkey
+ ]);
+ }
+
+ private function storeBlockchainTransaction($action, $hash, $device = 0, $application = 0)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO transactions (
+ `uid`,
+ `did`,
+ `aid`,
+ `action`,
+ `hash`,
+ `time`
+ ) VALUES (
+ :uid,
+ :did,
+ :aid,
+ :action,
+ :hash,
+ :time
+ )
+ ");
+ $pdoQuery->execute([
+ ":uid" => $_SESSION["GeniSysAI"]["Uid"],
+ ":did" => $device,
+ ":aid" => $application,
+ ":action" => $action,
+ ':hash' => $this->_GeniSys->_helpers->oEncrypt($hash),
+ ":time" => time()
+ ]);
+ $txid = $this->_GeniSys->_secCon->lastInsertId();
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ return $txid;
+ }
+
+ private function storeUserHistory($action, $hash, $location = 0, $zone = 0, $device = 0, $sensor = 0, $application = 0)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO history (
+ `uid`,
+ `tlid`,
+ `tzid`,
+ `tdid`,
+ `tsid`,
+ `taid`,
+ `action`,
+ `hash`,
+ `time`
+ ) VALUES (
+ :uid,
+ :tlid,
+ :tzid,
+ :tdid,
+ :tsid,
+ :taid,
+ :action,
+ :hash,
+ :time
+ )
+ ");
+ $pdoQuery->execute([
+ ":uid" => $_SESSION["GeniSysAI"]["Uid"],
+ ":tlid" => $location,
+ ":tzid" => $zone,
+ ":tdid" => $device,
+ ":tsid" => $sensor,
+ ":taid" => $application,
+ ":action" => $action,
+ ":hash" => $hash,
+ ":time" => time()
+ ]);
+ $txid = $this->_GeniSys->_secCon->lastInsertId();
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ return $txid;
+ }
+
+ public function getModels($limit = 0)
+ {
+ $limiter = "";
+ if($limit != 0):
+ $limiter = "&limit=" . $limit;
+ endif;
+
+ $devices = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "?type=Model".$limiter, $this->createContextHeaders(), []), true);
+ return $devices;
+ }
+
+ public function getModel($id, $attrs = Null)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM models
+ WHERE id = :id
+ ORDER BY id DESC
+ ");
+ $pdoQuery->execute([
+ ":id" => $id
+ ]);
+ $model=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($attrs):
+ $attrs="&attrs=" . $attrs;
+ endif;
+
+ $device["context"] = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "/" . $model["pub"] . "?type=Model" . $attrs, $this->createContextHeaders(), []), true);
+ return $device;
+ }
+
+ public function createModel()
+ {
+ if(!filter_input(INPUT_POST, "category", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Category is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "name", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "description", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Description is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "ntype", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Network type is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "ntype", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Network type is required"
+ ];
+ endif;
+
+ $pubKey = $this->_GeniSys->_helpers->generate_uuid();
+
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO models (
+ `pub`
+ ) VALUES (
+ :pub
+ )
+ ");
+ $query->execute([
+ ':pub' => $pubKey
+ ]);
+ $mid = $this->_GeniSys->_secCon->lastInsertId();
+
+ $properties=[];
+ if(isSet($_POST["properties"])):
+ foreach($_POST["properties"] AS $key => $value):
+ $properties[$value] = ["value" => ""];
+ endforeach;
+ endif;
+
+ $commands=[];
+ if(isSet($_POST["commands"])):
+ foreach($_POST["commands"] AS $key => $value):
+ $values = explode(",", $value);
+ $commands[$key] = $values;
+ endforeach;
+ endif;
+
+ $states=[];
+ $state=[];
+ if(isSet($_POST["states"])):
+ $states = $_POST["states"];
+ $state = [
+ "value" => "",
+ "timestamp" => ""
+ ];
+ endif;
+
+ $data = [
+ "id" => $pubKey,
+ "type" => "Model",
+ "category" => [
+ "value" => [filter_input(INPUT_POST, "category", FILTER_SANITIZE_STRING)]
+ ],
+ "mid" => [
+ "value" => $mid
+ ],
+ "name" => [
+ "value" => filter_input(INPUT_POST, "name", FILTER_SANITIZE_STRING)
+ ],
+ "description" => [
+ "value" => filter_input(INPUT_POST, "description", FILTER_SANITIZE_STRING)
+ ],
+ "model" => [
+ "type" => filter_input(INPUT_POST, "mtype", FILTER_SANITIZE_STRING),
+ "author" => filter_input(INPUT_POST, "author", FILTER_SANITIZE_STRING),
+ "authorLink" => filter_input(INPUT_POST, "authorLink", FILTER_SANITIZE_STRING)
+ ],
+ "network" => [
+ "value" => filter_input(INPUT_POST, "ntype", FILTER_SANITIZE_STRING)
+ ],
+ "language" => [
+ "value" => filter_input(INPUT_POST, "language", FILTER_SANITIZE_STRING)
+ ],
+ "framework" => [
+ "value" => filter_input(INPUT_POST, "framework", FILTER_SANITIZE_STRING)
+ ],
+ "toolkit" => [
+ "value" => filter_input(INPUT_POST, "toolkit", FILTER_SANITIZE_STRING)
+ ],
+ "dataset" => [
+ "name" => filter_input(INPUT_POST, "datasetUsed", FILTER_SANITIZE_STRING),
+ "author" => filter_input(INPUT_POST, "datasetAuthor", FILTER_SANITIZE_STRING),
+ "url" => filter_input(INPUT_POST, "datasetLink", FILTER_SANITIZE_STRING),
+ "type" => filter_input(INPUT_POST, "datasetType", FILTER_SANITIZE_STRING),
+ "augmentation" => filter_input(INPUT_POST, "datasetAugmentation", FILTER_SANITIZE_NUMBER_INT) ? 1 : 0,
+ "positiveLabel" => filter_input(INPUT_POST, "datasetPosLabel", FILTER_SANITIZE_STRING),
+ "negativeLabel" => filter_input(INPUT_POST, "datasetNegLabel", FILTER_SANITIZE_STRING)
+ ],
+ "paper" => [
+ "title" => filter_input(INPUT_POST, "relatedPaper", FILTER_SANITIZE_STRING),
+ "author" => filter_input(INPUT_POST, "relatedPaperAuthor", FILTER_SANITIZE_STRING),
+ "doi" => filter_input(INPUT_POST, "relatedPaperDOI", FILTER_SANITIZE_STRING),
+ "link" => filter_input(INPUT_POST, "relatedPaperLink", FILTER_SANITIZE_STRING)
+ ],
+ "properties" => $properties,
+ "commands" => $commands,
+ "states" => $states,
+ "state" => $state,
+ "dateCreated" => [
+ "type" => "DateTime",
+ "value" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "dateModified" => [
+ "type" => "DateTime",
+ "value" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ]
+ ];
+
+ $response = json_decode($this->contextBrokerRequest("POST", $this->cb["entities_url"] . "?type=Model", $this->createContextHeaders(), json_encode($data)), true);
+
+ if($response["Response"]=="OK"):
+ return [
+ "Response"=> "OK",
+ "Message" => "Model Created!"
+ ];
+ else:
+ return [
+ "Response"=> "FAILED",
+ "Message" => "Model Created KO! " . $response["Description"]
+ ];
+ endif;
+ }
+
+ public function updateModel()
+ {
+ if(!filter_input(INPUT_POST, "category", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Category is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "name", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "description", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Description is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "ntype", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Network type is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "ntype", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Network type is required"
+ ];
+ endif;
+
+ $properties=[];
+ if(isSet($_POST["properties"])):
+ foreach($_POST["properties"] AS $key => $value):
+ $properties[$value] = ["value" => ""];
+ endforeach;
+ endif;
+
+ $commands=[];
+ if(isSet($_POST["commands"])):
+ foreach($_POST["commands"] AS $key => $value):
+ $values = explode(",", $value);
+ $commands[$key] = $values;
+ endforeach;
+ endif;
+
+ $states=[];
+ $state=[];
+ if(isSet($_POST["states"])):
+ $states = $_POST["states"];
+ $state = [
+ "value" => "",
+ "timestamp" => ""
+ ];
+ endif;
+
+ $model = $this->getModel(filter_input(INPUT_GET, 'model', FILTER_SANITIZE_NUMBER_INT));
+
+ $data = [
+ "category" => [
+ "value" => [filter_input(INPUT_POST, "category", FILTER_SANITIZE_STRING)]
+ ],
+ "name" => [
+ "value" => filter_input(INPUT_POST, "name", FILTER_SANITIZE_STRING)
+ ],
+ "description" => [
+ "value" => filter_input(INPUT_POST, "description", FILTER_SANITIZE_STRING)
+ ],
+ "model" => [
+ "type" => filter_input(INPUT_POST, "mtype", FILTER_SANITIZE_STRING),
+ "link" => filter_input(INPUT_POST, "link", FILTER_SANITIZE_STRING),
+ "author" => filter_input(INPUT_POST, "author", FILTER_SANITIZE_STRING),
+ "authorLink" => filter_input(INPUT_POST, "authorLink", FILTER_SANITIZE_STRING)
+ ],
+ "network" => [
+ "value" => filter_input(INPUT_POST, "ntype", FILTER_SANITIZE_STRING)
+ ],
+ "language" => [
+ "value" => filter_input(INPUT_POST, "language", FILTER_SANITIZE_STRING)
+ ],
+ "framework" => [
+ "value" => filter_input(INPUT_POST, "framework", FILTER_SANITIZE_STRING)
+ ],
+ "toolkit" => [
+ "value" => filter_input(INPUT_POST, "toolkit", FILTER_SANITIZE_STRING)
+ ],
+ "dataset" => [
+ "name" => filter_input(INPUT_POST, "datasetUsed", FILTER_SANITIZE_STRING),
+ "author" => filter_input(INPUT_POST, "datasetAuthor", FILTER_SANITIZE_STRING),
+ "url" => filter_input(INPUT_POST, "datasetLink", FILTER_SANITIZE_STRING),
+ "type" => filter_input(INPUT_POST, "datasetType", FILTER_SANITIZE_STRING),
+ "augmentation" => filter_input(INPUT_POST, "datasetAugmentation", FILTER_SANITIZE_NUMBER_INT) ? 1 : 0,
+ "positiveLabel" => filter_input(INPUT_POST, "datasetPosLabel", FILTER_SANITIZE_STRING),
+ "negativeLabel" => filter_input(INPUT_POST, "datasetNegLabel", FILTER_SANITIZE_STRING)
+ ],
+ "paper" => [
+ "title" => filter_input(INPUT_POST, "relatedPaper", FILTER_SANITIZE_STRING),
+ "author" => filter_input(INPUT_POST, "relatedPaperAuthor", FILTER_SANITIZE_STRING),
+ "doi" => filter_input(INPUT_POST, "relatedPaperDOI", FILTER_SANITIZE_STRING),
+ "link" => filter_input(INPUT_POST, "relatedPaperLink", FILTER_SANITIZE_STRING)
+ ],
+ "properties" => $properties,
+ "commands" => $commands,
+ "states" => $states,
+ "state" => $state,
+ "dateModified" => [
+ "type" => "DateTime",
+ "value" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ]
+ ];
+
+ $response = json_decode($this->contextBrokerRequest("PATCH", $this->cb["entities_url"] . "/" . $model["context"]["Data"]["id"] . "/attrs?type=Model", $this->createContextHeaders(), json_encode($data)), true);
+
+ if($response["Response"]=="OK"):
+ $model = $this->getModel(filter_input(INPUT_GET, 'model', FILTER_SANITIZE_NUMBER_INT));
+ return [
+ "Response"=> "OK",
+ "Message" => "Model Updated!"
+ ];
+ else:
+ return [
+ "Response"=> "FAILED",
+ "Message" => "Model Update KO! " . $response["Description"]
+ ];
+ endif;
+ }
+
+ }
+
+ $AI = new AI($_GeniSys);
+
+ if(filter_input(INPUT_POST, "create_ai_model", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($AI->createModel()));
+ endif;
+
+ if(filter_input(INPUT_POST, "update_ai_model", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($AI->updateModel()));
+ endif;
\ No newline at end of file
diff --git a/Root/var/www/html/AI/Create.php b/Root/var/www/html/AI/Create.php
new file mode 100644
index 0000000..d668834
--- /dev/null
+++ b/Root/var/www/html/AI/Create.php
@@ -0,0 +1,299 @@
+ "AI",
+ "SubPageID" => "Models"
+];
+
+include dirname(__FILE__) . '/../../Classes/Core/init.php';
+include dirname(__FILE__) . '/../../Classes/Core/GeniSys.php';
+include dirname(__FILE__) . '/../iotJumpWay/Classes/iotJumpWay.php';
+include dirname(__FILE__) . '/../AI/Classes/AI.php';
+
+$_GeniSysAi->checkSession();
+
+?>
+
+
+
+
+
+
+
+
+
=$_GeniSys->_confs["meta_title"]; ?>
+
" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Create AI Classifier Model
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Root/var/www/html/GeniSysAI/Classes/NLU.js b/Root/var/www/html/AI/GeniSysAI/Classes/NLU.js
similarity index 63%
rename from Root/var/www/html/GeniSysAI/Classes/NLU.js
rename to Root/var/www/html/AI/GeniSysAI/Classes/NLU.js
index 5b51366..076ee08 100644
--- a/Root/var/www/html/GeniSysAI/Classes/NLU.js
+++ b/Root/var/www/html/AI/GeniSysAI/Classes/NLU.js
@@ -1,13 +1,12 @@
var NLU = {
Create: function() {
$.post(window.location.href, $("#genisysai_create").serialize(), function(resp) {
- console.log(resp)
var resp = jQuery.parseJSON(resp);
switch (resp.Response) {
case "OK":
GeniSys.ResetForm("genisysai_create");
$('.modal-title').text('GeniSyAI Security Devices');
- $('.modal-body').html("HIAS GeniSyAI NLU Device ID #" + resp.GDID + " created! Please save the API keys safely. The device's credentials are provided below. The credentials can be reset in the GeniSyAI Security Devices area.
Device ID: " + resp.DID + "
MQTT User: " + resp.MU + "
MQTT Password: " + resp.MP + "
Blockchain User: " + resp.BU + "
Blockchain Pass: " + resp.BP + "
App ID: " + resp.AppID + "
App Key: " + resp.AppKey + "
" + resp.Message);
+ $('.modal-body').html("HIAS GeniSyAI NLU Device ID #" + resp.DID + " created! Please save the API keys safely. The device's credentials are provided below. The credentials can be reset in the GeniSyAI Security Devices area.
MQTT User: " + resp.MU + "
MQTT Password: " + resp.MP + "
Blockchain User: " + resp.BU + "
Blockchain Pass: " + resp.BP + "
App ID: " + resp.AppID + "
App Key: " + resp.AppKey + "
" + resp.Message);
$('#responsive-modal').modal('show');
Logging.logMessage("Core", "Forms", "Device ID #" + resp.DID + " created!");
break;
@@ -23,6 +22,8 @@ var NLU = {
var resp = jQuery.parseJSON(resp);
switch (resp.Response) {
case "OK":
+ var fjson = JSON.stringify(resp.Schema, null, '\t');
+ window.parent.$('#schema').html(fjson);
$('.modal-title').text('NLU Update');
$('.modal-body').text("NLU Update OK");
$('#responsive-modal').modal('show');
@@ -36,15 +37,15 @@ var NLU = {
});
},
ResetMqtt: function() {
- $.post(window.location.href, { "reset_mqtt": 1, "id": $("#did").val(), "lid": $("#lid").val(), "zid": $("#zid").val() },
+ $.post(window.location.href, { "reset_mqtt": 1 },
function(resp) {
var resp = jQuery.parseJSON(resp);
switch (resp.Response) {
case "OK":
Logging.logMessage("Core", "Forms", "Reset OK");
- GeniSysAI.mqttpa = resp.P;
- GeniSysAI.mqttpae = resp.P.replace(/\S/gi, '*');
- $("#idmqttp").text(GeniSysAI.mqttpae);
+ NLU.mqttp3a = resp.P;
+ NLU.mqttp3ae = resp.P.replace(/\S/gi, '*');
+ $("#mqttpt").text(NLU.mqttp3ae);
$('.modal-title').text('New MQTT Password');
$('.modal-body').text("This device's new MQTT password is: " + resp.P);
$('#responsive-modal').modal('show');
@@ -57,14 +58,14 @@ var NLU = {
});
},
ResetDvcKey: function() {
- $.post(window.location.href, { "reset_key": 1, "id": $("#did").val(), "lid": $("#lid").val(), "zid": $("#zid").val() },
+ $.post(window.location.href, { "reset_key": 1 },
function(resp) {
var resp = jQuery.parseJSON(resp);
switch (resp.Response) {
case "OK":
Logging.logMessage("Core", "Forms", "Device Update OK");
$('.modal-title').text('Device Update');
- $('.modal-body').text(resp.Message);
+ $('.modal-body').text("This device's new key is: " + resp.P);
$('#responsive-modal').modal('show');
break;
default:
@@ -74,6 +75,45 @@ var NLU = {
}
});
},
+ ResetDvcAMQP: function() {
+ $.post(window.location.href, { "reset_dvc_amqp": 1 },
+ function(resp) {
+ var resp = jQuery.parseJSON(resp);
+ switch (resp.Response) {
+ case "OK":
+ GeniSysAI.damqppa = resp.P;
+ GeniSysAI.damqppae = resp.P.replace(/\S/gi, '*');
+ $("#damqpp").text(GeniSysAI.damqppae);
+ Logging.logMessage("Core", "Forms", resp.Message);
+ $('.modal-title').text('Reset Device AMQP Key');
+ $('.modal-body').text("This device's new AMQP key is: " + resp.P);
+ $('#responsive-modal').modal('show');
+ break;
+ default:
+ msg = "Reset failed: " + resp.Message
+ Logging.logMessage("Core", "Forms", msg);
+ $('.modal-title').text('Reset Device AMQP Key');
+ $('.modal-body').text(msg);
+ $('#responsive-modal').modal('show');
+ break;
+ }
+ });
+ },
+ ChatWithGeniSysAI: function() {
+ $("#chatWindow").prepend("
YOU: " + $("#GeniSysAiChat").val() + "
");
+ $.post(window.location.href, $("#genisysai_chat").serialize(),
+ function(resp) {
+ console.log(resp)
+ var resp = jQuery.parseJSON(resp);
+ switch (resp.Response) {
+ case "OK":
+ $("#chatWindow").prepend("
GeniSysAI: " + resp.Message + "
");
+ break;
+ default:
+ break;
+ }
+ });
+ },
HideInputs: function() {
$('#ip').attr('type', 'password');
$('#mac').attr('type', 'password');
@@ -81,6 +121,10 @@ var NLU = {
$('#sportf').attr('type', 'password');
$('#sckport').attr('type', 'password');
+ NLU.damqpua = $("#damqpu").text();
+ NLU.damqpuae = $("#damqpu").text().replace(/\S/gi, '*');
+ NLU.damqppa = $("#damqpp").text();
+ NLU.damqppae = $("#damqpp").text().replace(/\S/gi, '*');
NLU.mqttu3a = $("#mqttut").text();
NLU.mqttu3ae = $("#mqttut").text().replace(/\S/gi, '*');
NLU.mqttp3a = $("#mqttpt").text();
@@ -90,13 +134,15 @@ var NLU = {
NLU.bcida = $("#bcid").text();
NLU.bcidae = $("#bcid").text().replace(/\S/gi, '*');
+ $("#damqpu").text(NLU.damqpuae);
+ $("#damqpp").text(NLU.damqppae);
$("#mqttut").text(NLU.mqttu3ae);
$("#mqttpt").text(NLU.mqttp3ae);
$("#idappid").text(NLU.idappidae);
$("#bcid").text(NLU.bcidae);
},
GetLife: function() {
- $.post(window.location.href, { "get_tlife": 1, "device": $("#did").val() }, function(resp) {
+ $.post(window.location.href, { "get_tlife": 1 }, function(resp) {
var resp = jQuery.parseJSON(resp);
switch (resp.Response) {
case "OK":
@@ -153,6 +199,16 @@ $(document).ready(function() {
NLU.ResetDvcKey();
});
+ $("#GeniSysAI").on("click", "#reset_dvc_amqp", function(e) {
+ e.preventDefault();
+ NLU.ResetDvcAMQP();
+ });
+
+ $("#GeniSysAI").on("click", "#send_chat", function(e) {
+ e.preventDefault();
+ NLU.ChatWithGeniSysAI();
+ });
+
$('#idappid').hover(function() {
$("#idappid").text(NLU.idappida);
}, function() {
@@ -179,6 +235,6 @@ $(document).ready(function() {
setInterval(function() {
NLU.GetLife();
- }, 5000);
+ }, 10000);
});
\ No newline at end of file
diff --git a/Root/var/www/html/AI/GeniSysAI/Classes/NLU.php b/Root/var/www/html/AI/GeniSysAI/Classes/NLU.php
new file mode 100644
index 0000000..43cc2b4
--- /dev/null
+++ b/Root/var/www/html/AI/GeniSysAI/Classes/NLU.php
@@ -0,0 +1,1673 @@
+_GeniSys = $_GeniSys;
+ $this->bcc = $this->getBlockchainConf();
+ $this->web3 = $this->blockchainConnection();
+ $this->contract = new Contract($this->web3->provider, $this->bcc["abi"]);
+ $this->icontract = new Contract($this->web3->provider, $this->bcc["iabi"]);
+ $this->checkBlockchainPermissions();
+ $this->cb = $this->getContextBrokerConf();
+ }
+
+ public function getContextBrokerConf()
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM contextbroker
+ ");
+ $pdoQuery->execute();
+ $response=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+ return $response;
+ }
+
+ private function createContextHeaders()
+ {
+ $basicAuth = $_SESSION["GeniSysAI"]["User"] . ":" . $this->_GeniSys->_helpers->oDecrypt($_SESSION["GeniSysAI"]["Pass"]);
+ $basicAuth = base64_encode($basicAuth);
+
+ return [
+ "Content-Type: application/json",
+ 'Authorization: Basic '. $basicAuth
+ ];
+ }
+
+ private function contextBrokerRequest($method, $endpoint, $headers, $json)
+ {
+ $path = $this->_GeniSys->_helpers->oDecrypt($this->_GeniSys->_confs["domainString"]) . "/" . $this->cb["url"] . "/" . $endpoint;
+
+ if($method == "GET"):
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ curl_setopt($ch, CURLOPT_HEADER, 1);
+ curl_setopt($ch, CURLOPT_URL, $path);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ $response = curl_exec($ch);
+ $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
+ $header = substr($response, 0, $header_size);
+ $body = substr($response, $header_size);
+ curl_close($ch);
+ elseif($method == "POST"):
+ $ch = curl_init($path);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ curl_setopt($ch, CURLOPT_HEADER, 1);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
+ $response = curl_exec($ch);
+ $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
+ $header = substr($response, 0, $header_size);
+ $body = substr($response, $header_size);
+ curl_close($ch);
+ elseif($method == "PATCH"):
+ $ch = curl_init($path);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ curl_setopt($ch, CURLOPT_HEADER, 1);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
+ $response = curl_exec($ch);
+ $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
+ $header = substr($response, 0, $header_size);
+ $body = substr($response, $header_size);
+ curl_close($ch);
+ endif;
+
+ return $body;
+ }
+
+ public function getBlockchainConf()
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT blockchain.*,
+ contracts.contract,
+ contracts.abi,
+ icontracts.contract as icontract,
+ icontracts.abi as iabi
+ FROM blockchain blockchain
+ INNER JOIN contracts contracts
+ ON contracts.id = blockchain.dc
+ INNER JOIN contracts icontracts
+ ON icontracts.id = blockchain.ic
+ ");
+ $pdoQuery->execute();
+ $response=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+ return $response;
+ }
+
+ private function blockchainConnection()
+ {
+ $web3 = new Web3($this->_GeniSys->_helpers->oDecrypt($this->_GeniSys->_confs["domainString"]) . "/Blockchain/API/", 30, $_SESSION["GeniSysAI"]["User"], $this->_GeniSys->_helpers->oDecrypt($_SESSION["GeniSysAI"]["Pass"]));
+
+ return $web3;
+ }
+
+ private function checkBlockchainPermissions()
+ {
+ $allowed = "";
+ $this->contract->at($this->_GeniSys->_helpers->oDecrypt($this->bcc["contract"]))->call("identifierAllowed", "User", $_SESSION["GeniSysAI"]["Identifier"], ["from" => $_SESSION["GeniSysAI"]["BC"]["BCUser"]], function ($err, $resp) use (&$allowed) {
+ if ($err !== null) {
+ $allowed = "FAILED";
+ return;
+ }
+ $allowed = $resp[0];
+ });
+
+ if($allowed != "true"):
+ header('Location: /Logout');
+ endif;
+ }
+
+ private function unlockBlockchainAccount()
+ {
+ $response = "";
+ $personal = $this->web3->personal;
+ $personal->unlockAccount($_SESSION["GeniSysAI"]["BC"]["BCUser"], $this->_GeniSys->_helpers->oDecrypt($_SESSION["GeniSysAI"]["BC"]["BCPass"]), function ($err, $unlocked) use (&$response) {
+ if ($err !== null) {
+ $response = "FAILED! " . $err;
+ return;
+ }
+ if ($unlocked) {
+ $response = "OK";
+ } else {
+ $response = "FAILED";
+ }
+ });
+
+ return $response;
+ }
+
+ private function createBlockchainUser($pass)
+ {
+ $newAccount = "";
+ $personal = $this->web3->personal;
+ $personal->newAccount($pass, function ($err, $account) use (&$newAccount) {
+ if ($err !== null) {
+ $newAccount = "FAILED!";
+ return;
+ }
+ $newAccount = $account;
+ });
+
+ return $newAccount;
+ }
+
+ private function getBlockchainBalance()
+ {
+ $nbalance = "";
+ $this->web3->eth->getBalance($_SESSION["GeniSysAI"]["BC"]["BCUser"], function ($err, $balance) use (&$nbalance) {
+ if ($err !== null) {
+ $response = "FAILED! " . $err;
+ return;
+ }
+ $nbalance = $balance->toString();
+ });
+
+ return Utils::fromWei($nbalance, 'ether')[0];
+ }
+
+ private function storeBlockchainTransaction($action, $hash, $device = 0, $application = 0)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO transactions (
+ `uid`,
+ `did`,
+ `aid`,
+ `action`,
+ `hash`,
+ `time`
+ ) VALUES (
+ :uid,
+ :did,
+ :aid,
+ :action,
+ :hash,
+ :time
+ )
+ ");
+ $pdoQuery->execute([
+ ":uid" => $_SESSION["GeniSysAI"]["Uid"],
+ ":did" => $device,
+ ":aid" => $application,
+ ":action" => $action,
+ ':hash' => $this->_GeniSys->_helpers->oEncrypt($hash),
+ ":time" => time()
+ ]);
+ $txid = $this->_GeniSys->_secCon->lastInsertId();
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ return $txid;
+ }
+
+ private function storeUserHistory($action, $hash, $location = 0, $zone = 0, $device = 0, $sensor = 0, $application = 0)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO history (
+ `uid`,
+ `tlid`,
+ `tzid`,
+ `tdid`,
+ `tsid`,
+ `taid`,
+ `action`,
+ `hash`,
+ `time`
+ ) VALUES (
+ :uid,
+ :tlid,
+ :tzid,
+ :tdid,
+ :tsid,
+ :taid,
+ :action,
+ :hash,
+ :time
+ )
+ ");
+ $pdoQuery->execute([
+ ":uid" => $_SESSION["GeniSysAI"]["Uid"],
+ ":tlid" => $location,
+ ":tzid" => $zone,
+ ":tdid" => $device,
+ ":tsid" => $sensor,
+ ":taid" => $application,
+ ":action" => $action,
+ ":hash" => $hash,
+ ":time" => time()
+ ]);
+ $txid = $this->_GeniSys->_secCon->lastInsertId();
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ return $txid;
+ }
+
+ private function addAmqpUser($username, $key)
+ {
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO amqpu (
+ `username`,
+ `pw`
+ ) VALUES (
+ :username,
+ :pw
+ )
+ ");
+ $query->execute([
+ ':username' => $username,
+ ':pw' => $this->_GeniSys->_helpers->oEncrypt($key)
+ ]);
+ $amid = $this->_GeniSys->_secCon->lastInsertId();
+ return $amid;
+ }
+
+ private function addAmqpUserVh($uid, $vhost)
+ {
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO amqpvh (
+ `uid`,
+ `vhost`
+ ) VALUES (
+ :uid,
+ :vhost
+ )
+ ");
+ $query->execute([
+ ':uid' => $uid,
+ ':vhost' => $vhost
+ ]);
+ }
+
+ private function addAmqpVhPerm($uid, $vhost, $rtype, $rname, $permission)
+ {
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO amqpvhr (
+ `uid`,
+ `vhost`,
+ `rtype`,
+ `rname`,
+ `permission`
+ ) VALUES (
+ :uid,
+ :vhost,
+ :rtype,
+ :rname,
+ :permission
+ )
+ ");
+ $query->execute([
+ ':uid' => $uid,
+ ':vhost' => $vhost,
+ ':rtype' => $rtype,
+ ':rname' => $rname,
+ ':permission' => $permission
+ ]);
+ }
+
+ private function addAmqpVhTopic($uid, $vhost, $rtype, $rname, $permission, $rkey)
+ {
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO amqpvhrt (
+ `uid`,
+ `vhost`,
+ `rtype`,
+ `rname`,
+ `permission`,
+ `rkey`
+ ) VALUES (
+ :uid,
+ :vhost,
+ :rtype,
+ :rname,
+ :permission,
+ :rkey
+ )
+ ");
+ $query->execute([
+ ':uid' => $uid,
+ ':vhost' => $vhost,
+ ':rtype' => $rtype,
+ ':rname' => $rname,
+ ':permission' => $permission,
+ ':rkey' => $rkey
+ ]);
+ }
+
+ public function checkLocation($lid)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT id
+ FROM mqttl
+ WHERE id = :id
+ ");
+ $pdoQuery->execute([
+ ":id" => $lid
+ ]);
+ $location=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($location["id"]):
+ return True;
+ else:
+ return False;
+ endif;
+ }
+
+ public function getLocation($id, $attrs = Null)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM mqttl
+ WHERE id = :id
+ ");
+ $pdoQuery->execute([
+ ":id" => $id
+ ]);
+ $location=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($attrs):
+ $attrs="&attrs=" . $attrs;
+ endif;
+
+ $location["context"] = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "/" . $location["pub"] . "?type=Location" . $attrs, $this->createContextHeaders(), []), true);
+ return $location;
+ }
+
+ public function checkZone($zid)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT id
+ FROM mqttlz
+ WHERE id = :id
+ ");
+ $pdoQuery->execute([
+ ":id" => $zid
+ ]);
+ $location=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($location["id"]):
+ return True;
+ else:
+ return False;
+ endif;
+ }
+
+ public function getZone($id, $attrs = Null)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM mqttlz
+ WHERE id = :id
+ ORDER BY id DESC
+ ");
+ $pdoQuery->execute([
+ ":id" => $id
+ ]);
+ $zone=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($attrs):
+ $attrs="&attrs=" . $attrs;
+ endif;
+
+ $zone["context"] = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "/" . $zone["pub"] . "?type=Zone" . $attrs, $this->createContextHeaders(), []), true);
+ return $zone;
+ }
+
+ public function getDevices($limit = 0)
+ {
+ $limiter = "";
+ if($limit != 0):
+ $limiter = "&limit=" . $limit;
+ endif;
+
+ $devices = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "?type=Device&category=GeniSysAI".$limiter, $this->createContextHeaders(), []), true);
+ return $devices;
+ }
+
+ public function getDevice($id, $attrs = Null)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM mqttld
+ WHERE id = :id
+ ORDER BY id DESC
+ ");
+ $pdoQuery->execute([
+ ":id" => $id
+ ]);
+ $device=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($attrs):
+ $attrs="&attrs=" . $attrs;
+ endif;
+
+ $device["context"] = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "/" . $device["apub"] . "?type=Device" . $attrs, $this->createContextHeaders(), []), true);
+ return $device;
+ }
+
+ public function getThing($id, $attrs = Null)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM things
+ WHERE id = :id
+ ");
+ $pdoQuery->execute([
+ ":id" => $id
+ ]);
+ $thing=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($attrs):
+ $attrs="&attrs=" . $attrs;
+ endif;
+
+ $thing["context"] = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "/" . $thing["pub"] . "?type=Thing" . $attrs, $this->createContextHeaders(), []), true);
+ return $thing;
+ }
+
+ public function getModel($id, $attrs = Null)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM models
+ WHERE id = :id
+ ORDER BY id DESC
+ ");
+ $pdoQuery->execute([
+ ":id" => $id
+ ]);
+ $model=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($attrs):
+ $attrs="&attrs=" . $attrs;
+ endif;
+
+ $device["context"] = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "/" . $model["pub"] . "?type=Model" . $attrs, $this->createContextHeaders(), []), true);
+ return $device;
+ }
+
+ public function createDevice()
+ {
+ if(!filter_input(INPUT_POST, "lid", FILTER_SANITIZE_NUMBER_INT)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Location ID is required"
+ ];
+ endif;
+
+ if(!$this->checkLocation(filter_input(INPUT_POST, "lid", FILTER_SANITIZE_NUMBER_INT))):
+ return [
+ "Response"=> "Failed",
+ "Message" => "iotJumpWay location does not exist"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "zid", FILTER_SANITIZE_NUMBER_INT)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Zone ID is required"
+ ];
+ endif;
+
+ if(!$this->checkZone(filter_input(INPUT_POST, "zid", FILTER_SANITIZE_NUMBER_INT))):
+ return [
+ "Response"=> "Failed",
+ "Message" => "iotJumpWay zone does not exist"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "category", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Category is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "name", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "description", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "coordinates", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Coordinates entity is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "deviceName", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Hardware device name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "deviceManufacturer", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Hardware device manufacturer is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "deviceModel", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Hardware device model is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osName", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osManufacturer", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system manufacturer is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osVersion", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system version is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "agent", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "IoT Agent is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "ip", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "IP is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "mac", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "MAC is required"
+ ];
+ endif;
+
+ if(!count($_POST["protocols"])):
+ return [
+ "Response"=> "Failed",
+ "Message" => "At least one M2M protocol is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "apidir", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Nginx server proxy path"
+ ];
+ endif;
+
+ $mqttUser = $this->_GeniSys->_helpers->generate_uuid();
+ $mqttPass = $this->_GeniSys->_helpers->password();
+ $mqttHash = create_hash($mqttPass);
+
+ $pubKey = $this->_GeniSys->_helpers->generate_uuid();
+ $privKey = $this->_GeniSys->_helpers->generateKey(32);
+ $privKeyHash = $this->_GeniSys->_helpers->createPasswordHash($privKey);
+
+ $amqppubKey = $this->_GeniSys->_helpers->generate_uuid();
+ $amqpprvKey = $this->_GeniSys->_helpers->generateKey(32);
+ $amqpKeyHash = $this->_GeniSys->_helpers->createPasswordHash($amqpprvKey);
+
+ $bcPass = $this->_GeniSys->_helpers->password();
+
+ $lid = filter_input(INPUT_POST, 'lid', FILTER_SANITIZE_NUMBER_INT);
+ $location = $this->getLocation($lid);
+
+ $zid = filter_input(INPUT_POST, 'zid', FILTER_SANITIZE_NUMBER_INT);
+ $zone = $this->getZone($zid);
+
+ $ip = filter_input(INPUT_POST, "ip", FILTER_SANITIZE_STRING);
+ $mac = filter_input(INPUT_POST, "mac", FILTER_SANITIZE_STRING);
+
+ $ip = filter_input(INPUT_POST, "ip", FILTER_SANITIZE_STRING);
+ $mac = filter_input(INPUT_POST, "mac", FILTER_SANITIZE_STRING);
+ $bluetooth = filter_input(INPUT_POST, "bluetooth", FILTER_SANITIZE_STRING);
+ $name = filter_input(INPUT_POST, "name", FILTER_SANITIZE_STRING);
+ $coords = explode(",", filter_input(INPUT_POST, "coordinates", FILTER_SANITIZE_STRING));
+
+ $protocols = [];
+ foreach($_POST["protocols"] AS $key => $value):
+ $protocols[] = $value;
+ endforeach;
+
+ $models = [];
+ if(isSet($_POST["ai"])):
+ foreach($_POST["ai"] AS $key => $value):
+ $model = $this->getModel($value)["context"]["Data"];
+ $mname = $model["name"]["value"];
+ unset($model["id"]);
+ unset($model["type"]);
+ unset($model["mid"]);
+ unset($model["name"]);
+ unset($model["description"]);
+ unset($model["network"]);
+ unset($model["language"]);
+ unset($model["framework"]);
+ unset($model["toolkit"]);
+ unset($model["dateCreated"]);
+ unset($model["dateModified"]);
+ $models[$mname] = $model;
+ endforeach;
+ endif;
+
+ $sensors = [];
+ if(isSet($_POST["sensors"])):
+ foreach($_POST["sensors"] AS $key => $value):
+ $sensor = $this->getThing($value)["context"]["Data"];
+ unset($sensor["id"]);
+ unset($sensor["type"]);
+ unset($sensor["category"]);
+ unset($sensor["description"]);
+ unset($sensor["thing"]);
+ unset($sensor["properties"]["image"]);
+ unset($sensor["dateCreated"]);
+ unset($sensor["dateModified"]);
+ $sensors[] = $sensor;
+ endforeach;
+ endif;
+
+ $actuators = [];
+ if(isSet($_POST["actuators"])):
+ foreach($_POST["actuators"] AS $key => $value):
+ $actuator = $this->getThing($value)["context"]["Data"];
+ unset($actuator["id"]);
+ unset($actuator["type"]);
+ unset($actuator["category"]);
+ unset($actuator["description"]);
+ unset($actuator["thing"]);
+ unset($actuator["properties"]["image"]);
+ unset($actuator["dateCreated"]);
+ unset($actuator["dateModeified"]);
+ $actuators[] = $actuator;
+ endforeach;
+ endif;
+
+ $newBcUser = $this->createBlockchainUser($bcPass);
+
+ if($newBcUser == "FAILED"):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Creating New HIAS Blockhain Account Failed!"
+ ];
+ endif;
+
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO mqttld (
+ `apub`
+ ) VALUES (
+ :apub
+ )
+ ");
+ $query->execute([
+ ':apub' => $pubKey
+ ]);
+ $did = $this->_GeniSys->_secCon->lastInsertId();
+
+ $data = [
+ "id" => $pubKey,
+ "type" => "Device",
+ "category" => [
+ "value" => [filter_input(INPUT_POST, "category", FILTER_SANITIZE_STRING)]
+ ],
+ "name" => [
+ "value" => $name
+ ],
+ "description" => [
+ "value" => filter_input(INPUT_POST, "description", FILTER_SANITIZE_STRING)
+ ],
+ "lid" => [
+ "value" => $lid,
+ "entity" => $location["context"]["Data"]["id"]
+ ],
+ "zid" => [
+ "value" => $zid,
+ "entity" => $zone["context"]["Data"]["id"]
+ ],
+ "did" => [
+ "value" => $did
+ ],
+ "location" => [
+ "type" => "geo:json",
+ "value" => [
+ "type" => "Point",
+ "coordinates" => [floatval($coords[0]), floatval($coords[1])]
+ ]
+ ],
+ "agent" => [
+ "url" => filter_input(INPUT_POST, "agent", FILTER_SANITIZE_STRING)
+ ],
+ "device" => [
+ "type" => filter_input(INPUT_POST, "type", FILTER_SANITIZE_STRING),
+ "name" => filter_input(INPUT_POST, "deviceName", FILTER_SANITIZE_STRING),
+ "manufacturer" => filter_input(INPUT_POST, "deviceManufacturer", FILTER_SANITIZE_STRING),
+ "model" => filter_input(INPUT_POST, "deviceModel", FILTER_SANITIZE_STRING)
+ ],
+ "proxy" => [
+ "endpoint" => filter_input(INPUT_POST, "apidir", FILTER_SANITIZE_STRING)
+ ],
+ "stream" => [
+ "port" => "",
+ "file" => ""
+ ],
+ "socket" => [
+ "port" => ""
+ ],
+ "os" => [
+ "name" => filter_input(INPUT_POST, "osName", FILTER_SANITIZE_STRING),
+ "manufacturer" => filter_input(INPUT_POST, "osManufacturer", FILTER_SANITIZE_STRING),
+ "version" => filter_input(INPUT_POST, "osVersion", FILTER_SANITIZE_STRING)
+ ],
+ "protocols" => $protocols,
+ "status" => [
+ "value" => "OFFLINE",
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "keys" => [
+ "public" => $pubKey,
+ "private" => $this->_GeniSys->_helpers->oEncrypt($privKeyHash),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "blockchain" => [
+ "address" => $newBcUser,
+ "password" => $this->_GeniSys->_helpers->oEncrypt($bcPass)
+ ],
+ "mqtt" => [
+ "username" => $this->_GeniSys->_helpers->oEncrypt($mqttUser),
+ "password" => $this->_GeniSys->_helpers->oEncrypt($mqttPass),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "coap" => [
+ "username" => "",
+ "password" => ""
+ ],
+ "amqp" => [
+ "username" => $this->_GeniSys->_helpers->oEncrypt($amqppubKey),
+ "password" => $this->_GeniSys->_helpers->oEncrypt($amqpprvKey),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "batteryLevel" => [
+ "value" => 0.00
+ ],
+ "cpuUsage" => [
+ "value" => 0.00
+ ],
+ "memoryUsage" => [
+ "value" => 0.00
+ ],
+ "hddUsage" => [
+ "value" => 0.00
+ ],
+ "temperature" => [
+ "value" => 0.00
+ ],
+ "ip" => [
+ "value" => $ip,
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "mac" => [
+ "value" => $this->_GeniSys->_helpers->oEncrypt($mac),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "bluetooth" => [
+ "address" => $bluetooth ? $this->_GeniSys->_helpers->oEncrypt($bluetooth) : "",
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "ai" => $models,
+ "sensors" => $sensors,
+ "actuators" => $actuators,
+ "dateCreated" => [
+ "type" => "DateTime",
+ "value" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "dateFirstUsed" => [
+ "type" => "DateTime",
+ "value" => ""
+ ],
+ "dateModified" => [
+ "type" => "DateTime",
+ "value" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ]
+ ];
+
+ $response = json_decode($this->contextBrokerRequest("POST", $this->cb["entities_url"] . "?type=Device", $this->createContextHeaders(), json_encode($data)), true);
+ if($response["Response"]=="OK"):
+
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO mqttu (
+ `lid`,
+ `zid`,
+ `did`,
+ `uname`,
+ `pw`
+ ) VALUES (
+ :lid,
+ :zid,
+ :did,
+ :uname,
+ :pw
+ )
+ ");
+ $query->execute([
+ ':lid' => $lid,
+ ':zid' => $zid,
+ ':did' => $did,
+ ':uname' => $mqttUser,
+ ':pw' => $mqttHash
+ ]);
+
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO mqttua (
+ `lid`,
+ `zid`,
+ `did`,
+ `username`,
+ `topic`,
+ `rw`
+ ) VALUES (
+ :lid,
+ :zid,
+ :did,
+ :username,
+ :topic,
+ :rw
+ )
+ ");
+ $query->execute(array(
+ ':lid' => $lid,
+ ':zid' => $zid,
+ ':did' => $did,
+ ':username' => $mqttUser,
+ ':topic' => $location["context"]["Data"]["id"] . "/Devices/" . $zone["context"]["Data"]["id"] . "/" . $pubKey . "/#",
+ ':rw' => 4
+ ));
+
+ $amid = $this->addAmqpUser($amqppubKey, $amqpKeyHash);
+ $this->addAmqpUserVh($amid, "iotJumpWay");
+ $this->addAmqpVhPerm($amid, "iotJumpWay", "exchange", "Core", "read");
+ $this->addAmqpVhPerm($amid, "iotJumpWay", "exchange", "Core", "write");
+ $this->addAmqpVhPerm($amid, "iotJumpWay", "queue", "Life", "read");
+ $this->addAmqpVhPerm($amid, "iotJumpWay", "queue", "Life", "write");
+ $this->addAmqpVhPerm($amid, "iotJumpWay", "queue", "Statuses", "read");
+ $this->addAmqpVhPerm($amid, "iotJumpWay", "queue", "Statuses", "write");
+ $this->addAmqpVhTopic($amid, "iotJumpWay", "topic", "Core", "read", "Life");
+ $this->addAmqpVhTopic($amid, "iotJumpWay", "topic", "Core", "write", "Life");
+ $this->addAmqpVhTopic($amid, "iotJumpWay", "topic", "Core", "read", "Statuses");
+ $this->addAmqpVhTopic($amid, "iotJumpWay", "topic", "Core", "write", "Statuses");
+
+ $unlocked = $this->unlockBlockchainAccount();
+
+ if($unlocked == "FAILED"):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Unlocking HIAS Blockhain Account Failed!"
+ ];
+ endif;
+
+ $hash = "";
+ $msg = "";
+ $actionMsg = "";
+ $balanceMessage = "";
+ $this->contract->at($this->_GeniSys->_helpers->oDecrypt($this->bcc["contract"]))->send("registerDevice", $pubKey, $newBcUser, $lid, $zid, $did, $name, $_SESSION["GeniSysAI"]["Uid"], time(), ["from" => $_SESSION["GeniSysAI"]["BC"]["BCUser"]], function ($err, $resp) use (&$hash, &$msg) {
+ if ($err !== null) {
+ $hash = "FAILED";
+ $msg = $err;
+ return;
+ }
+ $hash = $resp;
+ });
+
+ if($hash == "FAILED"):
+ $actionMsg = " HIAS Blockchain registerDevice failed!\n";
+ else:
+ $txid = $this->storeBlockchainTransaction("Register Device", $hash, $did);
+ $this->storeUserHistory("Register Device", $txid, $lid, $zid, $did);
+ $balance = $this->getBlockchainBalance();
+ $balanceMessage = " You were rewarded for this action! Your balance is now: " . $balance . " HIAS Ether!\n";
+ endif;
+
+ $this->icontract->at($this->_GeniSys->_helpers->oDecrypt($this->bcc["icontract"]))->send("registerAuthorized", $newBcUser, ["from" => $_SESSION["GeniSysAI"]["BC"]["BCUser"]], function ($err, $resp) use (&$hash, &$msg) {
+ if ($err !== null) {
+ $hash = "FAILED";
+ $msg = $err;
+ return;
+ }
+ $hash = $resp;
+ });
+
+ if($hash == "FAILED"):
+ $actionMsg .= " HIAS Blockchain registerAuthorized failed!\n";
+ else:
+ $txid = $this->storeBlockchainTransaction("iotJumpWay Register Authorized", $hash, $did);
+ $this->storeUserHistory("Register Authorized", $txid, $lid, $zid, $did);
+ $balance = $this->getBlockchainBalance();
+ if($balanceMessage == ""):
+ $balanceMessage = " You were rewarded for this action! Your balance is now: " . $balance . " HIAS Ether!\n";
+ endif;
+ endif;
+
+ return [
+ "Response"=> "OK",
+ "Message" => "Device created!" . $actionMsg . $balanceMessage,
+ "LID" => $lid,
+ "ZID" => $zid,
+ "DID" => $did,
+ "MU" => $mqttUser,
+ "MP" => $mqttPass,
+ "BU" => $newBcUser,
+ "BP" => $bcPass,
+ "AppID" => $pubKey,
+ "AppKey" => $privKey
+ ];
+ else:
+ return [
+ "Response"=> "FAILED",
+ "Message" => "Device creation failed"
+ ];
+ endif;
+ }
+
+ public function updateDevice()
+ {
+
+ if(!filter_input(INPUT_POST, "lid", FILTER_SANITIZE_NUMBER_INT)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Location ID is required"
+ ];
+ endif;
+
+ if(!$this->checkLocation(filter_input(INPUT_POST, "lid", FILTER_SANITIZE_NUMBER_INT))):
+ return [
+ "Response"=> "Failed",
+ "Message" => "iotJumpWay location does not exist"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "zid", FILTER_SANITIZE_NUMBER_INT)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Zone ID is required"
+ ];
+ endif;
+
+ if(!$this->checkZone(filter_input(INPUT_POST, "zid", FILTER_SANITIZE_NUMBER_INT))):
+ return [
+ "Response"=> "Failed",
+ "Message" => "iotJumpWay location does not exist"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "category", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Category is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "name", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "description", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Description is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "coordinates", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Coordinates entity is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "deviceName", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Hardware device name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "deviceManufacturer", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Hardware device manufacturer is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "deviceModel", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Hardware device model is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osName", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osManufacturer", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system manufacturer is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osVersion", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system version is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osVersion", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system version is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "agent", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "IoT Agent is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "ip", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "IP is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "mac", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "MAC is required"
+ ];
+ endif;
+
+ if(!count($_POST["protocols"])):
+ return [
+ "Response"=> "Failed",
+ "Message" => "At least one M2M protocol is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "apidir", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Device proxy url is required"
+ ];
+ endif;
+
+ $unlocked = $this->unlockBlockchainAccount();
+
+ if($unlocked == "FAILED"):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Unlocking HIAS Blockhain Account Failed!"
+ ];
+ endif;
+
+ $ip = filter_input(INPUT_POST, "ip", FILTER_SANITIZE_STRING);
+ $mac = filter_input(INPUT_POST, "mac", FILTER_SANITIZE_STRING);
+ $bluetooth = filter_input(INPUT_POST, "bluetooth", FILTER_SANITIZE_STRING);
+ $name = filter_input(INPUT_POST, "name", FILTER_SANITIZE_STRING);
+ $status = filter_input(INPUT_POST, "status", FILTER_SANITIZE_STRING);
+ $coords = explode(",", filter_input(INPUT_POST, "coordinates", FILTER_SANITIZE_STRING));
+
+ $did = filter_input(INPUT_GET, "device", FILTER_SANITIZE_NUMBER_INT);
+ $device = $this->getDevice($did);
+
+ $lid = filter_input(INPUT_POST, 'lid', FILTER_SANITIZE_NUMBER_INT);
+ $location = $this->getLocation($lid);
+
+ $zid = filter_input(INPUT_POST, 'zid', FILTER_SANITIZE_NUMBER_INT);
+ $zone = $this->getZone($zid);
+
+ $protocols = [];
+ foreach($_POST["protocols"] AS $key => $value):
+ $protocols[] = $value;
+ endforeach;
+
+ $models = [];
+ if(isSet($_POST["ai"])):
+ foreach($_POST["ai"] AS $key => $value):
+ $model = $this->getModel($value)["context"]["Data"];
+ $mname = $model["name"]["value"];
+ unset($model["id"]);
+ unset($model["type"]);
+ unset($model["mid"]);
+ unset($model["name"]);
+ unset($model["description"]);
+ unset($model["network"]);
+ unset($model["language"]);
+ unset($model["framework"]);
+ unset($model["toolkit"]);
+ unset($model["dateCreated"]);
+ unset($model["dateModified"]);
+ $models[$mname] = $model;
+ endforeach;
+ endif;
+
+ $sensors = [];
+ if(isSet($_POST["sensors"])):
+ foreach($_POST["sensors"] AS $key => $value):
+ $sensor = $this->getThing($value)["context"]["Data"];
+ unset($sensor["id"]);
+ unset($sensor["type"]);
+ unset($sensor["category"]);
+ unset($sensor["description"]);
+ unset($sensor["thing"]);
+ unset($sensor["properties"]["image"]);
+ unset($sensor["dateCreated"]);
+ unset($sensor["dateModified"]);
+ $sensors[] = $sensor;
+ endforeach;
+ endif;
+
+ $actuators = [];
+ if(isSet($_POST["actuators"])):
+ foreach($_POST["actuators"] AS $key => $value):
+ $actuator = $this->getThing($value)["context"]["Data"];
+ unset($actuator["id"]);
+ unset($actuator["type"]);
+ unset($actuator["category"]);
+ unset($actuator["description"]);
+ unset($actuator["thing"]);
+ unset($actuator["properties"]["image"]);
+ unset($actuator["dateCreated"]);
+ unset($actuator["dateModeified"]);
+ $actuators[] = $actuator;
+ endforeach;
+ endif;
+
+ if($device["context"]["Data"]["lid"]["value"] != $lid):
+ $query = $this->_GeniSys->_secCon->prepare("
+ UPDATE mqttu
+ SET lid = :lid
+ WHERE did = :did
+ ");
+ $query->execute([
+ ':lid' => $lid,
+ ':did' => $did
+ ]);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ $query = $this->_GeniSys->_secCon->prepare("
+ UPDATE mqttua
+ SET lid = :lid
+ WHERE did = :did
+ ");
+ $query->execute([
+ ':lid' => $lid,
+ ':did' => $did
+ ]);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ $query = $this->_GeniSys->_secCon->prepare("
+ UPDATE mqttua
+ SET topic = :topicN
+ WHERE did = :did
+ & topic = :topic
+ ");
+ $query->execute([
+ ':topicN' => $device["context"]["Data"]["lid"]["entity"] . "/ " . $device["context"]["Data"]["zid"]["entity"] . "/Devices/" . $device["context"]["Data"]["id"] . "/#",
+ ':did' => $did,
+ ':topic' => $location["context"]["Data"]["id"] . "/Devices/" . $zone["context"]["Data"]["id"] . "/Devices/" . $device["context"]["Data"]["id"] . "/#"
+ ]);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+ endif;
+
+ $data = [
+ "category" => [
+ "value" => [filter_input(INPUT_POST, "category", FILTER_SANITIZE_STRING)]
+ ],
+ "type" => "Device",
+ "name" => [
+ "value" => $name
+ ],
+ "description" => [
+ "value" => filter_input(INPUT_POST, "description", FILTER_SANITIZE_STRING)
+ ],
+ "lid" => [
+ "value" => $lid,
+ "entity" => $location["context"]["Data"]["id"]
+ ],
+ "zid" => [
+ "value" => $zid,
+ "entity" => $zone["context"]["Data"]["id"]
+ ],
+ "did" => [
+ "value" => $did
+ ],
+ "location" => [
+ "type" => "geo:json",
+ "value" => [
+ "type" => "Point",
+ "coordinates" => [floatval($coords[0]), floatval($coords[1])]
+ ]
+ ],
+ "agent" => [
+ "url" => filter_input(INPUT_POST, "agent", FILTER_SANITIZE_STRING)
+ ],
+ "device" => [
+ "type" => "NLU",
+ "name" => filter_input(INPUT_POST, "deviceName", FILTER_SANITIZE_STRING),
+ "manufacturer" => filter_input(INPUT_POST, "deviceManufacturer", FILTER_SANITIZE_STRING),
+ "model" => filter_input(INPUT_POST, "deviceModel", FILTER_SANITIZE_STRING)
+ ],
+ "proxy" => [
+ "endpoint" => filter_input(INPUT_POST, "apidir", FILTER_SANITIZE_STRING)
+ ],
+ "os" => [
+ "name" => filter_input(INPUT_POST, "osName", FILTER_SANITIZE_STRING),
+ "manufacturer" => filter_input(INPUT_POST, "osManufacturer", FILTER_SANITIZE_STRING),
+ "version" => filter_input(INPUT_POST, "osVersion", FILTER_SANITIZE_STRING)
+ ],
+ "protocols" => $protocols,
+ "status" => [
+ "value" => $device["context"]["Data"]["status"]["value"],
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "ip" => [
+ "value" => $this->_GeniSys->_helpers->oEncrypt($ip),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "mac" => [
+ "value" => $this->_GeniSys->_helpers->oEncrypt($mac),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "bluetooth" => [
+ "address" => $bluetooth ? $this->_GeniSys->_helpers->oEncrypt($bluetooth) : "",
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "ai" => $models,
+ "sensors" => $sensors,
+ "actuators" => $actuators,
+ "dateModified" => [
+ "type" => "DateTime",
+ "value" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ]
+ ];
+
+ $response = json_decode($this->contextBrokerRequest("PATCH", $this->cb["entities_url"] . "/" . $device["context"]["Data"]["id"] . "/attrs?type=Device", $this->createContextHeaders(), json_encode($data)), true);
+
+ if($response["Response"]=="OK"):
+
+ $hash = "";
+ $msg = "";
+ $this->contract->at($this->_GeniSys->_helpers->oDecrypt($this->bcc["contract"]))->send("updateDevice", $device["context"]["Data"]["id"], "Device", $lid, $zid, $did, $name, $device["context"]["Data"]["status"]["value"], time(), ["from" => $_SESSION["GeniSysAI"]["BC"]["BCUser"]], function ($err, $resp) use (&$hash, &$msg) {
+ if ($err !== null) {
+ $hash = "FAILED";
+ $msg = $err;
+ return;
+ }
+ $hash = $resp;
+ });
+
+ $balance = "";
+ $balanceMessage = "";
+ $actionMsg = "";
+ if($hash == "FAILED"):
+ $actionMsg = " HIAS Blockchain updateDevice failed!\n";
+ else:
+ $txid = $this->storeBlockchainTransaction("Update Device", $hash, $did);
+ $this->storeUserHistory("Updated Device", $txid, $lid, $zid, $did);
+ $balance = $this->getBlockchainBalance();
+ $balanceMessage = " You were rewarded for this action! Your balance is now: " . $balance . " HIAS Ether!\n";
+ endif;
+
+ $device = $this->getDevice($did);
+
+ return [
+ "Response"=> "OK",
+ "Message" => "Device updated!" . $actionMsg . $balanceMessage,
+ "Schema" => $device["context"]["Data"]
+ ];
+ else:
+ return [
+ "Response"=> "Failed",
+ "Message" => "There was a problem updating this device context data!"
+ ];
+ endif;
+ }
+
+ public function resetDvcMqtt()
+ {
+ $id = filter_input(INPUT_GET, 'device', FILTER_SANITIZE_NUMBER_INT);
+ $Device = $this->getDevice($id);
+
+ $mqttPass = $this->_GeniSys->_helpers->password();
+ $mqttHash = create_hash($mqttPass);
+
+ $data = [
+ "mqtt" => [
+ "username" => $Device["context"]["Data"]["mqtt"]["username"],
+ "password" => $this->_GeniSys->_helpers->oEncrypt($mqttPass),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "dateModified" => [
+ "type" => "DateTime",
+ "value" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ]
+ ];
+
+ $response = json_decode($this->contextBrokerRequest("PATCH", $this->cb["entities_url"] . "/" . $Device["context"]["Data"]["id"] . "/attrs?type=Device", $this->createContextHeaders(), json_encode($data)), true);
+
+ if($response["Response"]=="OK"):
+ $query = $this->_GeniSys->_secCon->prepare("
+ UPDATE mqttu
+ SET pw = :pw
+ WHERE did = :did
+ ");
+ $query->execute(array(
+ ':pw' => $mqttHash,
+ ':did' => $id
+ ));
+
+ $this->storeUserHistory("Reset Device MQTT Password", 0, $Device["context"]["Data"]["lid"]["value"], $Device["context"]["Data"]["zid"]["value"], $id);
+
+ return [
+ "Response"=> "OK",
+ "Message" => "MQTT password reset!",
+ "P" => $mqttPass
+ ];
+ else:
+ return [
+ "Response"=> "FAILED",
+ "Message" => "MQTT password reset failed!"
+ ];
+ endif;
+ }
+
+ public function resetDvcKey()
+ {
+ $id = filter_input(INPUT_GET, 'device', FILTER_SANITIZE_NUMBER_INT);
+ $Device = $this->getDevice($id);
+
+ $privKey = $this->_GeniSys->_helpers->generateKey(32);
+ $privKeyHash = $this->_GeniSys->_helpers->createPasswordHash($privKey);
+
+ $data = [
+ "keys" => [
+ "public" => $Device["context"]["Data"]["keys"]["public"],
+ "private" => $this->_GeniSys->_helpers->oEncrypt($privKeyHash),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "dateModified" => [
+ "type" => "DateTime",
+ "value" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ]
+ ];
+
+ $response = json_decode($this->contextBrokerRequest("PATCH", $this->cb["entities_url"] . "/" . $Device["context"]["Data"]["id"] . "/attrs?type=Device", $this->createContextHeaders(), json_encode($data)), true);
+
+ if($response["Response"]=="OK"):
+ $this->storeUserHistory("Reset Device Key", 0, $Device["context"]["Data"]["lid"]["value"], $Device["context"]["Data"]["zid"]["value"], $id);
+ return [
+ "Response"=> "OK",
+ "Message" => "Device key reset!",
+ "P" => $privKey
+ ];
+ else:
+ return [
+ "Response"=> "FAILED",
+ "Message" => "Device key reset failed!"
+ ];
+ endif;
+
+ }
+
+ public function resetDvcAmqpKey()
+ {
+ $id = filter_input(INPUT_GET, 'device', FILTER_SANITIZE_NUMBER_INT);
+ $Device = $this->getDevice($id);
+
+ $amqpPass = $this->_GeniSys->_helpers->password();
+ $amqpHash = $this->_GeniSys->_helpers->createPasswordHash($amqpPass);
+
+ $data = [
+ "amqp" => [
+ "username" => $Device["context"]["Data"]["amqp"]["username"],
+ "password" => $this->_GeniSys->_helpers->oEncrypt($amqpPass),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "dateModified" => [
+ "type" => "DateTime",
+ "value" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ]
+ ];
+
+ $response = json_decode($this->contextBrokerRequest("PATCH", $this->cb["entities_url"] . "/" . $Device["context"]["Data"]["id"] . "/attrs?type=Device", $this->createContextHeaders(), json_encode($data)), true);
+
+ if($response["Response"]=="OK"):
+ $query = $this->_GeniSys->_secCon->prepare("
+ UPDATE amqpu
+ SET pw = :pw
+ WHERE username = :username
+ ");
+ $query->execute(array(
+ ':pw' => $this->_GeniSys->_helpers->oEncrypt($amqpHash),
+ ':username' => $this->_GeniSys->_helpers->oDecrypt($Device["context"]["Data"]["amqp"]["username"])
+ ));
+
+ $this->storeUserHistory("Reset Device AMQP Key", 0, $Device["context"]["Data"]["lid"]["value"], $Device["context"]["Data"]["zid"]["value"], $id);
+
+ return [
+ "Response"=> "OK",
+ "Message" => "AMQP password reset!",
+ "P" => $amqpPass
+ ];
+ else:
+ return [
+ "Response"=> "FAILED",
+ "Message" => "AMQP password reset failed!"
+ ];
+ endif;
+ }
+
+ public function getLife()
+ {
+ $Device = $this->getDevice(filter_input(INPUT_GET, 'device', FILTER_SANITIZE_NUMBER_INT), "batteryLevel,cpuUsage,memoryUsage,hddUsage,temperature,status");
+
+ if($Device["context"]["Response"]=="OK"):
+ $response = [
+ "battery" => $Device["context"]["Data"]["batteryLevel"]["value"],
+ "cpu" => $Device["context"]["Data"]["cpuUsage"]["value"],
+ "mem" => $Device["context"]["Data"]["memoryUsage"]["value"],
+ "hdd" => $Device["context"]["Data"]["hddUsage"]["value"],
+ "tempr" => $Device["context"]["Data"]["temperature"]["value"],
+ "status" => $Device["context"]["Data"]["status"]["value"]
+ ];
+ return [
+ 'Response' => 'OK',
+ 'ResponseData' => $response
+ ];
+ else:
+ return [
+ 'Response'=>'FAILED'
+ ];
+ endif;
+ }
+
+
+ public function chatWithGeniSysAI()
+ {
+ if(!filter_input(INPUT_POST, "GeniSysAiChat", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Please enter some text"
+ ];
+ endif;
+
+ $did = filter_input(INPUT_GET, "device", FILTER_SANITIZE_NUMBER_INT);
+ $device = $this->getDevice($did);
+
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO genisysai (
+ `uid`,
+ `device`,
+ `chat`,
+ `timestamp`
+ ) VALUES (
+ :uid,
+ :device,
+ :chat,
+ :timestamp
+ )
+ ");
+ $pdoQuery->execute([
+ ":uid" => $_SESSION["GeniSysAI"]["Uid"],
+ ":device" => $device["context"]["Data"]["id"],
+ ":chat" => filter_input(INPUT_POST, 'GeniSysAiChat', FILTER_SANITIZE_STRING),
+ ":timestamp" => time()
+ ]);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ $path = $this->_GeniSys->_helpers->oDecrypt($this->_GeniSys->_confs["domainString"]) . "/GeniSysAI/NLU/API/Api";
+
+ $json = json_encode(["query" => filter_input(INPUT_POST, 'GeniSysAiChat', FILTER_SANITIZE_STRING)]);
+ $ch = curl_init($path);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $this->createContextHeaders());
+ curl_setopt($ch, CURLOPT_HEADER, 1);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
+ $response = curl_exec($ch);
+ $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
+ $header = substr($response, 0, $header_size);
+ $body = substr($response, $header_size);
+ curl_close($ch);
+ $response = json_decode($body, True);
+
+ if($response["Response"]=="OK"):
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO genisysai (
+ `isGeniSys`,
+ `device`,
+ `chat`,
+ `timestamp`
+ ) VALUES (
+ :isGeniSys,
+ :device,
+ :chat,
+ :timestamp
+ )
+ ");
+ $pdoQuery->execute([
+ ":isGeniSys" => 1,
+ ":device" => $device["context"]["Data"]["id"],
+ ":chat" => $response["ResponseData"][0]["Response"],
+ ":timestamp" => time()
+ ]);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+ return [
+ "Response"=> "OK",
+ "Message" => $response["ResponseData"][0]["Response"]
+ ];
+ else:
+ return [
+ "Response"=> "Failed",
+ "Message" => "There was a problem communicating with GeniSysAI"
+ ];
+ endif;
+ }
+
+ }
+
+ $NLU = new NLU($_GeniSys);
+
+ if(filter_input(INPUT_POST, "update_genisysai", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($NLU->updateDevice()));
+ endif;
+ if(filter_input(INPUT_POST, "create_genisysai", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($NLU->createDevice()));
+ endif;
+ if(filter_input(INPUT_POST, "reset_mqtt", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($NLU->resetDvcMqtt()));
+ endif;
+ if(filter_input(INPUT_POST, "reset_key", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($NLU->resetDvcKey()));
+ endif;
+ if(filter_input(INPUT_POST, "reset_key", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($NLU->resetDvcKey()));
+ endif;
+ if(filter_input(INPUT_POST, "reset_dvc_amqp", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($NLU->resetDvcAmqpKey()));
+ endif;
+ if(filter_input(INPUT_POST, "get_tlife", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($NLU->getLife()));
+ endif;
+ if(filter_input(INPUT_POST, "chatToGeniSys", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($NLU->chatWithGeniSysAI()));
+ endif;
\ No newline at end of file
diff --git a/Root/var/www/html/AI/GeniSysAI/Create.php b/Root/var/www/html/AI/GeniSysAI/Create.php
new file mode 100644
index 0000000..aec0241
--- /dev/null
+++ b/Root/var/www/html/AI/GeniSysAI/Create.php
@@ -0,0 +1,385 @@
+ "AI",
+ "SubPageID" => "GeniSysAI"
+];
+
+include dirname(__FILE__) . '/../../../Classes/Core/init.php';
+include dirname(__FILE__) . '/../../../Classes/Core/GeniSys.php';
+include dirname(__FILE__) . '/../../iotJumpWay/Classes/iotJumpWay.php';
+include dirname(__FILE__) . '/../../AI/GeniSysAI/Classes/NLU.php';
+
+$_GeniSysAi->checkSession();
+
+$Zones = $iotJumpWay->getZones();
+$Devices = $iotJumpWay->getDevices();
+
+?>
+
+
+
+
+
+
+
+
+
=$_GeniSys->_confs["meta_title"]; ?>
+
" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Create GeniSysAI NLU Device
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Root/var/www/html/AI/GeniSysAI/Device.php b/Root/var/www/html/AI/GeniSysAI/Device.php
new file mode 100644
index 0000000..7d76838
--- /dev/null
+++ b/Root/var/www/html/AI/GeniSysAI/Device.php
@@ -0,0 +1,913 @@
+ "AI",
+ "SubPageID" => "GeniSysAI"
+];
+
+include dirname(__FILE__) . '/../../../Classes/Core/init.php';
+include dirname(__FILE__) . '/../../../Classes/Core/GeniSys.php';
+include dirname(__FILE__) . '/../../iotJumpWay/Classes/iotJumpWay.php';
+include dirname(__FILE__) . '/../../AI/GeniSysAI/Classes/NLU.php';
+
+$_GeniSysAi->checkSession();
+
+$Locations = $iotJumpWay->getLocations();
+$Zones = $iotJumpWay->getZones();
+
+$TId = filter_input(INPUT_GET, 'device', FILTER_SANITIZE_NUMBER_INT);
+$Device = $iotJumpWay->getDevice($TId);
+
+list($dev1On, $dev1Off) = $iotJumpWay->getStatusShow($Device["context"]["Data"]["status"]["value"]);
+
+?>
+
+
+
+
+
+
+
+
+
+
=$_GeniSys->_confs["meta_title"]; ?>
+
" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
GeniSysAI Security NLU Device #=$TId; ?>
+
+
+
+
+
+
+
+
+
+
Device Schema
+
+
+
+
+
+
+
+
+
+
Device History
+
+
+
+
+
+
+
+
+
+
Device Transactions
+
+
+
+
+
+
+
+
+
+
Device iotJumpWay Statuses
+
+
+
+
+
+
+
+
+
+
+
+ ID
+ Status
+ Time
+
+
+
+
+ retrieveDeviceStatuses($Device["context"]["Data"]["id"], 5);
+ if($Statuses["Response"] == "OK"):
+ foreach($Statuses["ResponseData"] as $key => $value):
+ ?>
+
+
+ #=$value->_id;?>
+ =$value->Status;?>
+ =$value->Time;?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Device iotJumpWay Life
+
+
+
+
+
+
+
+
+
+
+
+ ID
+ Details
+ Time
+
+
+
+
+ retrieveDeviceLife($Device["context"]["Data"]["id"], 5);
+ if($Statuses["Response"] == "OK"):
+ foreach($Statuses["ResponseData"] as $key => $value):
+ ?>
+
+
+ #=$value->_id;?>
+
+ CPU : =$value->Data->CPU;?>%
+ Memory : =$value->Data->Memory;?>%
+ Diskspace : =$value->Data->Diskspace;?>%
+ Temperature : =$value->Data->Temperature;?>°C
+ Latitude : =$value->Data->Latitude;?>
+ Longitude : =$value->Data->Longitude;?>
+
+ =$value->Time;?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Device iotJumpWay Sensors
+
+
+
+
+
+
+
+
+
+
+
+ ID
+ Type
+ Sensor
+ Value
+ Message
+ Time
+
+
+
+
+ retrieveDeviceSensors($Device["context"]["Data"]["id"], 5);
+ if($Statuses["Response"] == "OK"):
+ foreach($Statuses["ResponseData"] as $key => $value):
+ $location = $iotJumpWay->getLocation($value->Location);
+ ?>
+
+ #=$value->_id;?>
+ =$value->Type;?>
+ =$value->Sensor;?>
+
+ Sensor == "Facial API" || $value->Sensor == "Foscam Camera" || $value->Sensor == "USB Camera") && is_array($value->Value)):
+ foreach($value->Value AS $key => $val):
+ echo $val[0] == 0 ? "Identification: Intruder " :"Identification: User #" . $val[0] . " ";
+ echo "Distance: " . $val[1] . " ";
+ echo "Message: " . $val[2] . " ";
+ endforeach;
+ else:
+ echo $value->Value;
+ endif;
+ ?>
+
+
+ =$value->Message;?>
+ =$value->Time;?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Device iotJumpWay Commands
+
+
+
+
+
+
+
+
+
+
+
+ ID
+ Location
+ Info
+ Time
+
+
+
+
+ retrieveDeviceCommands($Device["context"]["Data"]["id"], 5);
+ if($Statuses["Response"] == "OK"):
+ foreach($Statuses["ResponseData"] as $key => $value):
+ $location = $iotJumpWay->getLocation($value->Location);
+ $device = $iotJumpWay->getDevice($value->From);
+ $devicet = $iotJumpWay->getDevice($value->To);
+ $zone = $iotJumpWay->getZone($value->Zone);
+ if(!$device["name"]):
+ $type = "App";
+ $application = $iotJumpWay->getApplication($value->From);
+ $name = $application["name"];
+ else:
+ $type = "Device";
+ $name = $device["name"];
+ endif;
+ ?>
+
+
+ #=$value->_id;?>
+ Location #=$value->Location;?>: =$location["name"]; ?>
+ Zone =$value->Zone != 0 ? "#" . $value->Zone . ": " . $zone["zn"] : "NA"; ?>
+ From =$type; ?> =$value->From != 0 ? "#" . $value->From . ": " . $name : "NA"; ?>
+
+
+ Type: =$value->Type;?>
+ Value: =$value->Value;?>
+ Message: =$value->Message;?>
+
+ =$value->Time;?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Root/var/www/html/AI/GeniSysAI/Media/CSS/GeniSys.css b/Root/var/www/html/AI/GeniSysAI/Media/CSS/GeniSys.css
new file mode 100644
index 0000000..3db462d
--- /dev/null
+++ b/Root/var/www/html/AI/GeniSysAI/Media/CSS/GeniSys.css
@@ -0,0 +1,25 @@
+.iotJumpWayText {
+ font-size: 10px !important;
+ color: white !important;
+}
+
+.iotJumpWayTextTitle {
+ font-size: 10px !important;
+ color: #3b8dda !important;
+}
+
+input:read-only {
+ background-color: #333 !important;
+}
+
+select:read-only {
+ background-color: #333 !important;
+}
+
+input:disabled {
+ background-color: #333 !important;
+}
+
+select:disabled {
+ background-color: #333 !important;
+}
\ No newline at end of file
diff --git a/Root/var/www/html/GeniSysAI/Media/JS/GeniSysAi.js b/Root/var/www/html/AI/GeniSysAI/Media/JS/GeniSysAi.js
similarity index 99%
rename from Root/var/www/html/GeniSysAI/Media/JS/GeniSysAi.js
rename to Root/var/www/html/AI/GeniSysAI/Media/JS/GeniSysAi.js
index 29b7e42..e29d284 100644
--- a/Root/var/www/html/GeniSysAI/Media/JS/GeniSysAi.js
+++ b/Root/var/www/html/AI/GeniSysAI/Media/JS/GeniSysAi.js
@@ -27,6 +27,7 @@ var GeniSys = {
if (submit) {
$.post(window.location.href, $("#Login").serialize(), function(arsep) {
+ console.log(arsep)
var arsep = jQuery.parseJSON(arsep);
switch (arsep.Response) {
case "OK":
diff --git a/Root/var/www/html/Blockchain/Media/JS/Logging.js b/Root/var/www/html/AI/GeniSysAI/Media/JS/Logging.js
similarity index 100%
rename from Root/var/www/html/Blockchain/Media/JS/Logging.js
rename to Root/var/www/html/AI/GeniSysAI/Media/JS/Logging.js
diff --git a/Root/var/www/html/Blockchain/Media/JS/Validation.js b/Root/var/www/html/AI/GeniSysAI/Media/JS/Validation.js
similarity index 100%
rename from Root/var/www/html/Blockchain/Media/JS/Validation.js
rename to Root/var/www/html/AI/GeniSysAI/Media/JS/Validation.js
diff --git a/Root/var/www/html/AI/GeniSysAI/index.php b/Root/var/www/html/AI/GeniSysAI/index.php
new file mode 100644
index 0000000..41cc5eb
--- /dev/null
+++ b/Root/var/www/html/AI/GeniSysAI/index.php
@@ -0,0 +1,172 @@
+ "AI",
+ "SubPageID" => "GeniSysAI"
+];
+
+include dirname(__FILE__) . '/../../../Classes/Core/init.php';
+include dirname(__FILE__) . '/../../../Classes/Core/GeniSys.php';
+include dirname(__FILE__) . '/../../AI/GeniSysAI/Classes/NLU.php';
+
+$_GeniSysAi->checkSession();
+$Devices = $NLU->getDevices();
+
+?>
+
+
+
+
+
+
+
+
+
+
=$_GeniSys->_confs["meta_title"]; ?>
+
" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
GeniSysAI Natural Language Understanding Models
+
+
+
+
+
+
+
GeniSysAI Natural Language Understanding Models are a range of Natural Language Understanding models for creating AI Assistants designed to be used on constrained devices making them suitable for IoT networks. These models use a variety of programming languages, frameworks and hardware providing. You can download our GeniSysAI models from the HIAS GeniSysAI repository . Instructions for installation are provided in the tutorials.
+
+
+
+
+
+
+
GeniSysAI NLU Devices
+
+
+
+
+
+
+
+
+
+
+
+ ID
+ DETAILS
+ STATUS
+ ACTION
+
+
+
+
+ $value):
+ ?>
+
+
+ #=$value["did"]["value"];?>
+
+ Name: =$value["name"]["value"];?>
+ Zone: #=$value["zid"]["value"];?>
+
+
+ ">
+ =$value["status"]["value"] == "OFFLINE" ? "OFFLINE" : "ONLINE"; ?>
+
+
+ ">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Root/var/www/html/AI/Model.php b/Root/var/www/html/AI/Model.php
new file mode 100644
index 0000000..4d276ea
--- /dev/null
+++ b/Root/var/www/html/AI/Model.php
@@ -0,0 +1,382 @@
+ "AI",
+ "SubPageID" => "Models"
+];
+
+include dirname(__FILE__) . '/../../Classes/Core/init.php';
+include dirname(__FILE__) . '/../../Classes/Core/GeniSys.php';
+include dirname(__FILE__) . '/../iotJumpWay/Classes/iotJumpWay.php';
+include dirname(__FILE__) . '/../AI/Classes/AI.php';
+
+$_GeniSysAi->checkSession();
+
+$mid = filter_input(INPUT_GET, 'model', FILTER_SANITIZE_NUMBER_INT);
+$model = $AI->getModel($mid);
+
+?>
+
+
+
+
+
+
+
+
+
+
=$_GeniSys->_confs["meta_title"]; ?>
+
" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
AI Classifier Model #=$mid; ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Root/var/www/html/AI/Skin/Classes/Skin.js b/Root/var/www/html/AI/Skin/Classes/Skin.js
new file mode 100644
index 0000000..e71b100
--- /dev/null
+++ b/Root/var/www/html/AI/Skin/Classes/Skin.js
@@ -0,0 +1,176 @@
+var Skin = {
+ Create: function() {
+ $.post(window.location.href, $("#skin_classifier").serialize(), function(resp) {
+ console.log(resp);
+ var resp = jQuery.parseJSON(resp);
+ switch (resp.Response) {
+ case "OK":
+ GeniSys.ResetForm("skin_classifier");
+ $('.modal-title').text('Skin Classifier Devices');
+ $('.modal-body').html("HIAS Skin Classifier Device ID #" + resp.GDID + " created! Please save the API keys safely. The device's credentials are provided below. The credentials can be reset in the GeniSyAI Security Devices area.
Device ID: " + resp.DID + "
MQTT User: " + resp.MU + "
MQTT Password: " + resp.MP + "
Blockchain User: " + resp.BU + "
Blockchain Pass: " + resp.BP + "
App ID: " + resp.AppID + "
App Key: " + resp.AppKey + "
" + resp.Message);
+ $('#responsive-modal').modal('show');
+ Logging.logMessage("Core", "Forms", "Device ID #" + resp.DID + " created!");
+ break;
+ default:
+ msg = "Skin Create Failed: " + resp.Message
+ Logging.logMessage("Core", "Skin", msg);
+ $('.modal-title').text('Skin Classifier Devices');
+ $('.modal-body').text(msg);
+ $('#responsive-modal').modal('show');
+ break;
+ }
+ });
+ },
+ Update: function() {
+ $.post(window.location.href, $("#skin_classifier_update").serialize(), function(resp) {
+ console.log(resp)
+ var resp = jQuery.parseJSON(resp);
+ switch (resp.Response) {
+ case "OK":
+ var fjson = JSON.stringify(resp.Schema, null, '\t');
+ window.parent.$('#schema').html(fjson);
+ Logging.logMessage("Core", "Forms", "Device Update OK");
+ $('.modal-title').text('Skin Classifier Devices');
+ $('.modal-body').text(resp.Message);
+ $('#responsive-modal').modal('show');
+ break;
+ default:
+ msg = "Skin Update Failed: " + resp.Message
+ Logging.logMessage("Core", "Skin", msg);
+ $('.modal-title').text('Skin Classifier Devices');
+ $('.modal-body').text(msg);
+ $('#responsive-modal').modal('show');
+ break;
+ }
+ });
+ },
+ deleteData: function() {
+ $.post(window.location.href, { "deleteData": 1 }, function(resp) {
+ console.log(resp)
+ var resp = jQuery.parseJSON(resp);
+ switch (resp.Response) {
+ case "OK":
+ $('#dataBlock').empty();
+ $('#dataBlock').html("
Please upload your test dataset.
");
+ break;
+ default:
+ break;
+ }
+ });
+ },
+ prepareUploadForm: function() {
+
+ var upper = document.querySelector('#dataup'),
+ form = new FormData(),
+ xhr = new XMLHttpRequest();
+
+ form.append('uploadAllData', 1);
+
+ upper.addEventListener('change', function(event) {
+ event.preventDefault();
+
+ var files = this.files;
+ for (var i = 0, n = files.length; i < n; i++) {
+ var file = files[i];
+
+ form.append('skindata[]', file, file.name);
+
+ xhr.onload = function() {
+ if (xhr.status === 200) {
+ var resp = jQuery.parseJSON(xhr.response);
+ if (resp.Response === "OK") {
+ $('#dataBlock').empty();
+ $('#dataBlock').html(resp.Data);
+ $('.modal-title').text('Data Upload OK');
+ $('.modal-body').text(resp.Message);
+ $('#responsive-modal').modal('show');
+ Skin.setOpacity();
+ Logging.logMessage("Core", "Forms", resp.Message);
+ } else {
+ Logging.logMessage("Core", "Forms", resp.Message);
+ $('.modal-title').text('Data Upload Failed');
+ $('.modal-body').text(resp.Message);
+ $('#responsive-modal').modal('show');
+ }
+ }
+ }
+
+ xhr.open('POST', '');
+ xhr.send(form);
+ }
+ });
+ },
+ setOpacity: function() {
+ $('.classify').css("opacity", "1.0");
+ $('.classify').hover(function() {
+ $(this).stop().animate({ opacity: 0.2 }, "fast");
+ },
+ function() {
+ $(this).stop().animate({ opacity: 1.0 }, "fast");
+ });
+ },
+ classify: function(im) {
+
+ $('#imageView').html("
");
+ $("#imName").text(im);
+ var classification = '';
+ $("#imClass").html("
Diagnosis: WAITING FOR RESPONSE");
+ $("#imResult").html("
Result: WAITING FOR RESPONSE");
+ $.post(window.location.href, { "classifyData": 1, "im": im }, function(resp) {
+ var resp = jQuery.parseJSON(resp);
+ switch (resp.Response) {
+ case "OK":
+ console.log(im);
+ console.log(im.includes("_0"));
+ console.log(resp.Diagnosis);
+ if (im.includes("_0") && resp.Diagnosis == "Negative") {
+ classification = "True Negative";
+ } else if (im.includes("_0") && resp.Diagnosis == "Positive") {
+ classification = "False Positive";
+ } else if (im.includes("_1") && resp.Diagnosis == "Positive") {
+ classification = "True Positive";
+ } else if (im.includes("_1") && resp.Diagnosis == "Negative") {
+ classification = "False Negative";
+ }
+ $("#imClass").html("
Diagnosis: " + resp.Diagnosis);
+ $("#imResult").html("
Result: " + classification);
+ break;
+ default:
+ break;
+ }
+ });
+
+ }
+};
+$(document).ready(function() {
+
+ $('#skin_classifier').validator().on('submit', function(e) {
+ if (!e.isDefaultPrevented()) {
+ e.preventDefault();
+ Skin.Create();
+ }
+ });
+
+ $('#skin_classifier_update').validator().on('submit', function(e) {
+ if (!e.isDefaultPrevented()) {
+ e.preventDefault();
+ Skin.Update();
+ }
+ });
+
+ $("#GeniSysAI").on("click", "#uploadData", function(e) {
+ e.preventDefault();
+ $('#dataup').trigger('click');
+ });
+
+ $("#GeniSysAI").on("click", "#deleteData", function(e) {
+ e.preventDefault();
+ Skin.deleteData();
+ });
+
+ $("#GeniSysAI").on("click", ".classify", function(e) {
+ e.preventDefault();
+ Skin.classify($(this).attr("id"));
+ });
+
+});
\ No newline at end of file
diff --git a/Root/var/www/html/AI/Skin/Classes/Skin.php b/Root/var/www/html/AI/Skin/Classes/Skin.php
new file mode 100644
index 0000000..46eaad3
--- /dev/null
+++ b/Root/var/www/html/AI/Skin/Classes/Skin.php
@@ -0,0 +1,1687 @@
+_GeniSys = $_GeniSys;
+ $this->bcc = $this->getBlockchainConf();
+ $this->web3 = $this->blockchainConnection();
+ $this->contract = new Contract($this->web3->provider, $this->bcc["abi"]);
+ $this->icontract = new Contract($this->web3->provider, $this->bcc["iabi"]);
+ $this->checkBlockchainPermissions();
+ endif;
+ $this->cb = $this->getContextBrokerConf();
+ }
+
+ public function setClassifierConfs()
+ {
+ $TId = filter_input(INPUT_GET, 'device', FILTER_SANITIZE_NUMBER_INT);
+ $Device = $this->getDevice($TId);
+
+ $this->dataDir = "Data/" . $Device["context"]["Data"]["dataset"]["folder"] . "/";
+ $this->dataDirFull = "/fserver/var/www/html/AI/Skin//";
+ $this->dataFiles = $this->dataDir . "*.jpg";
+ $this->allowedFiles = ["jpg","JPG"];
+ $this->api = $this->_GeniSys->_helpers->oDecrypt($this->_GeniSys->_confs["domainString"])."/AI/Skin/" . $Device["context"]["Data"]["proxy"]["endpoint"] . "/Inference";
+ }
+
+ public function getContextBrokerConf()
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM contextbroker
+ ");
+ $pdoQuery->execute();
+ $response=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+ return $response;
+ }
+
+ private function createContextHeaders()
+ {
+ $basicAuth = $_SESSION["GeniSysAI"]["User"] . ":" . $this->_GeniSys->_helpers->oDecrypt($_SESSION["GeniSysAI"]["Pass"]);
+ $basicAuth = base64_encode($basicAuth);
+
+ return [
+ "Content-Type: application/json",
+ 'Authorization: Basic '. $basicAuth
+ ];
+ }
+
+ private function contextBrokerRequest($method, $endpoint, $headers, $json)
+ {
+ $path = $this->_GeniSys->_helpers->oDecrypt($this->_GeniSys->_confs["domainString"]) . "/" . $this->cb["url"] . "/" . $endpoint;
+
+ if($method == "GET"):
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ curl_setopt($ch, CURLOPT_HEADER, 1);
+ curl_setopt($ch, CURLOPT_URL, $path);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ $response = curl_exec($ch);
+ $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
+ $header = substr($response, 0, $header_size);
+ $body = substr($response, $header_size);
+ curl_close($ch);
+ elseif($method == "POST"):
+ $ch = curl_init($path);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ curl_setopt($ch, CURLOPT_HEADER, 1);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
+ $response = curl_exec($ch);
+ $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
+ $header = substr($response, 0, $header_size);
+ $body = substr($response, $header_size);
+ curl_close($ch);
+ elseif($method == "PATCH"):
+ $ch = curl_init($path);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ curl_setopt($ch, CURLOPT_HEADER, 1);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
+ $response = curl_exec($ch);
+ $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
+ $header = substr($response, 0, $header_size);
+ $body = substr($response, $header_size);
+ curl_close($ch);
+ endif;
+
+ return $body;
+ }
+
+ public function getBlockchainConf()
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT blockchain.*,
+ contracts.contract,
+ contracts.abi,
+ icontracts.contract as icontract,
+ icontracts.abi as iabi
+ FROM blockchain blockchain
+ INNER JOIN contracts contracts
+ ON contracts.id = blockchain.dc
+ INNER JOIN contracts icontracts
+ ON icontracts.id = blockchain.ic
+ ");
+ $pdoQuery->execute();
+ $response=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+ return $response;
+ }
+
+ private function blockchainConnection()
+ {
+ if(isSet($_SESSION["GeniSysAI"]["Active"])):
+ $web3 = new Web3($this->_GeniSys->_helpers->oDecrypt($this->_GeniSys->_confs["domainString"]) . "/Blockchain/API/", 30, $_SESSION["GeniSysAI"]["User"], $this->_GeniSys->_helpers->oDecrypt($_SESSION["GeniSysAI"]["Pass"]));
+ return $web3;
+ endif;
+ }
+
+ private function checkBlockchainPermissions()
+ {
+ $allowed = "";
+ $errr = "";
+ $this->contract->at($this->_GeniSys->_helpers->oDecrypt($this->bcc["contract"]))->call("identifierAllowed", "User", $_SESSION["GeniSysAI"]["Identifier"], ["from" => $_SESSION["GeniSysAI"]["BC"]["BCUser"]], function ($err, $resp) use (&$allowed, &$errr) {
+ if ($err !== null) {
+ $allowed = "FAILED";
+ $errr = $err;
+ return;
+ }
+ $allowed = $resp;
+ });
+ if(!$allowed):
+ header('Location: /Logout');
+ endif;
+ }
+
+ private function unlockBlockchainAccount()
+ {
+ $response = "";
+ $personal = $this->web3->personal;
+ $personal->unlockAccount($_SESSION["GeniSysAI"]["BC"]["BCUser"], $this->_GeniSys->_helpers->oDecrypt($_SESSION["GeniSysAI"]["BC"]["BCPass"]), function ($err, $unlocked) use (&$response) {
+ if ($err !== null) {
+ $response = "FAILED! " . $err;
+ return;
+ }
+ if ($unlocked) {
+ $response = "OK";
+ } else {
+ $response = "FAILED";
+ }
+ });
+
+ return $response;
+ }
+
+ private function lockBlockchainAccount()
+ {
+ $response = "";
+ $personal = $this->web3->personal;
+ $personal->lockAccount($_SESSION["GeniSysAI"]["BC"]["BCUser"], function ($err, $unlocked) use (&$response) {
+ if ($err !== null) {
+ $response = "FAILED! " . $err;
+ return;
+ }
+ if ($unlocked) {
+ $response = "OK";
+ } else {
+ $response = "FAILED";
+ }
+ });
+
+ return $response;
+ }
+
+ private function createBlockchainUser($pass)
+ {
+ $newAccount = "";
+ $personal = $this->web3->personal;
+ $personal->newAccount($pass, function ($err, $account) use (&$newAccount) {
+ if ($err !== null) {
+ $newAccount = "FAILED!";
+ return;
+ }
+ $newAccount = $account;
+ });
+
+ return $newAccount;
+ }
+
+ private function getBlockchainBalance()
+ {
+ $nbalance = "";
+ $this->web3->eth->getBalance($_SESSION["GeniSysAI"]["BC"]["BCUser"], function ($err, $balance) use (&$nbalance) {
+ if ($err !== null) {
+ $response = "FAILED! " . $err;
+ return;
+ }
+ $nbalance = $balance->toString();
+ });
+
+ return Utils::fromWei($nbalance, 'ether')[0];
+ }
+
+ private function addAmqpUser($username, $key)
+ {
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO amqpu (
+ `username`,
+ `pw`
+ ) VALUES (
+ :username,
+ :pw
+ )
+ ");
+ $query->execute([
+ ':username' => $username,
+ ':pw' => $this->_GeniSys->_helpers->oEncrypt($key)
+ ]);
+ $amid = $this->_GeniSys->_secCon->lastInsertId();
+ return $amid;
+ }
+
+ private function addAmqpUserVh($uid, $vhost)
+ {
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO amqpvh (
+ `uid`,
+ `vhost`
+ ) VALUES (
+ :uid,
+ :vhost
+ )
+ ");
+ $query->execute([
+ ':uid' => $uid,
+ ':vhost' => $vhost
+ ]);
+ }
+
+ private function addAmqpVhPerm($uid, $vhost, $rtype, $rname, $permission)
+ {
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO amqpvhr (
+ `uid`,
+ `vhost`,
+ `rtype`,
+ `rname`,
+ `permission`
+ ) VALUES (
+ :uid,
+ :vhost,
+ :rtype,
+ :rname,
+ :permission
+ )
+ ");
+ $query->execute([
+ ':uid' => $uid,
+ ':vhost' => $vhost,
+ ':rtype' => $rtype,
+ ':rname' => $rname,
+ ':permission' => $permission
+ ]);
+ }
+
+ private function addAmqpVhTopic($uid, $vhost, $rtype, $rname, $permission, $rkey)
+ {
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO amqpvhrt (
+ `uid`,
+ `vhost`,
+ `rtype`,
+ `rname`,
+ `permission`,
+ `rkey`
+ ) VALUES (
+ :uid,
+ :vhost,
+ :rtype,
+ :rname,
+ :permission,
+ :rkey
+ )
+ ");
+ $query->execute([
+ ':uid' => $uid,
+ ':vhost' => $vhost,
+ ':rtype' => $rtype,
+ ':rname' => $rname,
+ ':permission' => $permission,
+ ':rkey' => $rkey
+ ]);
+ }
+
+ private function storeBlockchainTransaction($action, $hash, $device = 0, $application = 0)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO transactions (
+ `uid`,
+ `did`,
+ `aid`,
+ `action`,
+ `hash`,
+ `time`
+ ) VALUES (
+ :uid,
+ :did,
+ :aid,
+ :action,
+ :hash,
+ :time
+ )
+ ");
+ $pdoQuery->execute([
+ ":uid" => $_SESSION["GeniSysAI"]["Uid"],
+ ":did" => $device,
+ ":aid" => $application,
+ ":action" => $action,
+ ':hash' => $this->_GeniSys->_helpers->oEncrypt($hash),
+ ":time" => time()
+ ]);
+ $txid = $this->_GeniSys->_secCon->lastInsertId();
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ return $txid;
+ }
+
+ private function storeUserHistory($action, $hash, $location = 0, $zone = 0, $device = 0, $sensor = 0, $application = 0)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO history (
+ `uid`,
+ `tlid`,
+ `tzid`,
+ `tdid`,
+ `tsid`,
+ `taid`,
+ `action`,
+ `hash`,
+ `time`
+ ) VALUES (
+ :uid,
+ :tlid,
+ :tzid,
+ :tdid,
+ :tsid,
+ :taid,
+ :action,
+ :hash,
+ :time
+ )
+ ");
+ $pdoQuery->execute([
+ ":uid" => $_SESSION["GeniSysAI"]["Uid"],
+ ":tlid" => $location,
+ ":tzid" => $zone,
+ ":tdid" => $device,
+ ":tsid" => $sensor,
+ ":taid" => $application,
+ ":action" => $action,
+ ":hash" => $hash,
+ ":time" => time()
+ ]);
+ $txid = $this->_GeniSys->_secCon->lastInsertId();
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ return $txid;
+ }
+
+ public function checkLocation($lid)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT id
+ FROM mqttl
+ WHERE id = :id
+ ");
+ $pdoQuery->execute([
+ ":id" => $lid
+ ]);
+ $location=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($location["id"]):
+ return True;
+ else:
+ return False;
+ endif;
+ }
+
+ public function getLocation($id, $attrs = Null)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM mqttl
+ WHERE id = :id
+ ");
+ $pdoQuery->execute([
+ ":id" => $id
+ ]);
+ $location=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($attrs):
+ $attrs="&attrs=" . $attrs;
+ endif;
+
+ $location["context"] = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "/" . $location["pub"] . "?type=Location" . $attrs, $this->createContextHeaders(), []), true);
+ return $location;
+ }
+
+ public function checkZone($zid)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT id
+ FROM mqttlz
+ WHERE id = :id
+ ");
+ $pdoQuery->execute([
+ ":id" => $zid
+ ]);
+ $location=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($location["id"]):
+ return True;
+ else:
+ return False;
+ endif;
+ }
+
+ public function getZone($id, $attrs = Null)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM mqttlz
+ WHERE id = :id
+ ORDER BY id DESC
+ ");
+ $pdoQuery->execute([
+ ":id" => $id
+ ]);
+ $zone=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($attrs):
+ $attrs="&attrs=" . $attrs;
+ endif;
+
+ $zone["context"] = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "/" . $zone["pub"] . "?type=Zone" . $attrs, $this->createContextHeaders(), []), true);
+ return $zone;
+ }
+
+ public function getDevices($limit = 0)
+ {
+ $limiter = "";
+ if($limit != 0):
+ $limiter = "&limit=" . $limit;
+ endif;
+
+ $devices = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "?type=Device&category=SkinCancerClassifier".$limiter, $this->createContextHeaders(), []), true);
+ return $devices;
+ }
+
+ public function getDevice($id, $attrs = Null)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM mqttld
+ WHERE id = :id
+ ORDER BY id DESC
+ ");
+ $pdoQuery->execute([
+ ":id" => $id
+ ]);
+ $device=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($attrs):
+ $attrs="&attrs=" . $attrs;
+ endif;
+
+ $device["context"] = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "/" . $device["apub"] . "?type=Device" . $attrs, $this->createContextHeaders(), []), true);
+ return $device;
+ }
+
+ public function getThing($id, $attrs = Null)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM things
+ WHERE id = :id
+ ");
+ $pdoQuery->execute([
+ ":id" => $id
+ ]);
+ $thing=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($attrs):
+ $attrs="&attrs=" . $attrs;
+ endif;
+
+ $thing["context"] = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "/" . $thing["pub"] . "?type=Thing" . $attrs, $this->createContextHeaders(), []), true);
+ return $thing;
+ }
+
+ public function getModel($id, $attrs = Null)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM models
+ WHERE id = :id
+ ORDER BY id DESC
+ ");
+ $pdoQuery->execute([
+ ":id" => $id
+ ]);
+ $model=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($attrs):
+ $attrs="&attrs=" . $attrs;
+ endif;
+
+ $device["context"] = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "/" . $model["pub"] . "?type=Model" . $attrs, $this->createContextHeaders(), []), true);
+ return $device;
+ }
+
+ public function createDevice()
+ {
+ if(!filter_input(INPUT_POST, "lid", FILTER_SANITIZE_NUMBER_INT)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Location ID is required"
+ ];
+ endif;
+
+ if(!$this->checkLocation(filter_input(INPUT_POST, "lid", FILTER_SANITIZE_NUMBER_INT))):
+ return [
+ "Response"=> "Failed",
+ "Message" => "iotJumpWay location does not exist"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "zid", FILTER_SANITIZE_NUMBER_INT)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Zone ID is required"
+ ];
+ endif;
+
+ if(!$this->checkZone(filter_input(INPUT_POST, "zid", FILTER_SANITIZE_NUMBER_INT))):
+ return [
+ "Response"=> "Failed",
+ "Message" => "iotJumpWay zone does not exist"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "category", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Category is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "ctype", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Model type is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "agent", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "IoT Agent is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "name", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "description", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "deviceName", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Hardware device name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "deviceManufacturer", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Hardware device manufacturer is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "deviceModel", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Hardware device model is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osName", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osManufacturer", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system manufacturer is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osVersion", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system version is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "agent", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "IoT Agent is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "coordinates", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Coordinates entity is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "ip", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "IP is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "mac", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "MAC is required"
+ ];
+ endif;
+
+ if(!count($_POST["protocols"])):
+ return [
+ "Response"=> "Failed",
+ "Message" => "At least one M2M protocol is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "datasetUsed", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Dataset used is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "datasetLink", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Dataset link is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "datasetAuthor", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Dataset author is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "datasetFolder", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Dataset folder is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "relatedPaper", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Related paper is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "sport", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Device server port is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "endpoint", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Proxy endpoint is required"
+ ];
+ endif;
+
+ $unlocked = $this->unlockBlockchainAccount();
+
+ if($unlocked == "FAILED"):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Unlocking HIAS Blockhain Account Failed!"
+ ];
+ endif;
+
+ $mqttUser = $this->_GeniSys->_helpers->generate_uuid();
+ $mqttPass = $this->_GeniSys->_helpers->password();
+ $mqttHash = create_hash($mqttPass);
+
+ $pubKey = $this->_GeniSys->_helpers->generate_uuid();
+ $privKey = $this->_GeniSys->_helpers->generateKey(32);
+ $privKeyHash = $this->_GeniSys->_helpers->createPasswordHash($privKey);
+
+ $amqppubKey = $this->_GeniSys->_helpers->generate_uuid();
+ $amqpprvKey = $this->_GeniSys->_helpers->generateKey(32);
+ $amqpKeyHash = $this->_GeniSys->_helpers->createPasswordHash($amqpprvKey);
+
+ $bcPass = $this->_GeniSys->_helpers->password();
+
+ $lid = filter_input(INPUT_POST, 'lid', FILTER_SANITIZE_NUMBER_INT);
+ $location = $this->getLocation($lid);
+
+ $zid = filter_input(INPUT_POST, 'zid', FILTER_SANITIZE_NUMBER_INT);
+ $zone = $this->getZone($zid);
+
+ $ip = filter_input(INPUT_POST, "ip", FILTER_SANITIZE_STRING);
+ $mac = filter_input(INPUT_POST, "mac", FILTER_SANITIZE_STRING);
+ $bluetooth = filter_input(INPUT_POST, "bluetooth", FILTER_SANITIZE_STRING);
+ $name = filter_input(INPUT_POST, "name", FILTER_SANITIZE_STRING);
+ $coords = explode(",", filter_input(INPUT_POST, "coordinates", FILTER_SANITIZE_STRING));
+
+ mkdir("Data/" . filter_input(INPUT_POST, "datasetFolder", FILTER_SANITIZE_STRING), 0777, true);
+
+ $protocols = [];
+ foreach($_POST["protocols"] AS $key => $value):
+ $protocols[] = $value;
+ endforeach;
+
+ $models = [];
+ if(isSet($_POST["ai"])):
+ foreach($_POST["ai"] AS $key => $value):
+ $model = $this->getModel($value)["context"]["Data"];
+ $mname = $model["name"]["value"];
+ unset($model["id"]);
+ unset($model["type"]);
+ unset($model["mid"]);
+ unset($model["name"]);
+ unset($model["description"]);
+ unset($model["network"]);
+ unset($model["language"]);
+ unset($model["framework"]);
+ unset($model["toolkit"]);
+ unset($model["dateCreated"]);
+ unset($model["dateModified"]);
+ $models[$mname] = $model;
+ endforeach;
+ endif;
+
+ $sensors = [];
+ if(isSet($_POST["sensors"])):
+ foreach($_POST["sensors"] AS $key => $value):
+ $sensor = $this->getThing($value)["context"]["Data"];
+ unset($sensor["id"]);
+ unset($sensor["type"]);
+ unset($sensor["category"]);
+ unset($sensor["description"]);
+ unset($sensor["thing"]);
+ unset($sensor["properties"]["image"]);
+ unset($sensor["dateCreated"]);
+ unset($sensor["dateModified"]);
+ $sensors[] = $sensor;
+ endforeach;
+ endif;
+
+ $actuators = [];
+ if(isSet($_POST["actuators"])):
+ foreach($_POST["actuators"] AS $key => $value):
+ $actuator = $this->getThing($value)["context"]["Data"];
+ unset($actuator["id"]);
+ unset($actuator["type"]);
+ unset($actuator["category"]);
+ unset($actuator["description"]);
+ unset($actuator["thing"]);
+ unset($actuator["properties"]["image"]);
+ unset($actuator["dateCreated"]);
+ unset($actuator["dateModeified"]);
+ $actuators[] = $actuator;
+ endforeach;
+ endif;
+
+ $newBcUser = $this->createBlockchainUser($bcPass);
+
+ if($newBcUser == "FAILED"):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Creating New HIAS Blockhain Account Failed!"
+ ];
+ endif;
+
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO mqttld (
+ `apub`
+ ) VALUES (
+ :apub
+ )
+ ");
+ $query->execute([
+ ':apub' => $pubKey
+ ]);
+ $did = $this->_GeniSys->_secCon->lastInsertId();
+
+ $data = [
+ "id" => $pubKey,
+ "type" => "Device",
+ "category" => [
+ "value" => [filter_input(INPUT_POST, "category", FILTER_SANITIZE_STRING)]
+ ],
+ "name" => [
+ "value" => $name
+ ],
+ "description" => [
+ "value" => filter_input(INPUT_POST, "description", FILTER_SANITIZE_STRING)
+ ],
+ "lid" => [
+ "value" => $lid,
+ "entity" => $location["context"]["Data"]["id"]
+ ],
+ "zid" => [
+ "value" => $zid,
+ "entity" => $zone["context"]["Data"]["id"]
+ ],
+ "did" => [
+ "value" => $did
+ ],
+ "location" => [
+ "type" => "geo:json",
+ "value" => [
+ "type" => "Point",
+ "coordinates" => [floatval($coords[0]), floatval($coords[1])]
+ ]
+ ],
+ "agent" => [
+ "url" => filter_input(INPUT_POST, "agent", FILTER_SANITIZE_STRING)
+ ],
+ "paper" => [
+ "title" => filter_input(INPUT_POST, "relatedPaper", FILTER_SANITIZE_STRING),
+ "author" => filter_input(INPUT_POST, "relatedPaperAuthor", FILTER_SANITIZE_STRING),
+ "doi" => filter_input(INPUT_POST, "relatedPaperDOI", FILTER_SANITIZE_STRING),
+ "link" => filter_input(INPUT_POST, "relatedPaperLink", FILTER_SANITIZE_STRING)
+ ],
+ "dataset" => [
+ "name" => filter_input(INPUT_POST, "datasetUsed", FILTER_SANITIZE_STRING),
+ "author" => filter_input(INPUT_POST, "datasetAuthor", FILTER_SANITIZE_STRING),
+ "url" => filter_input(INPUT_POST, "datasetLink", FILTER_SANITIZE_STRING),
+ "folder" => filter_input(INPUT_POST, "datasetFolder", FILTER_SANITIZE_STRING)
+ ],
+ "device" => [
+ "type" => filter_input(INPUT_POST, "ctype", FILTER_SANITIZE_STRING),
+ "name" => filter_input(INPUT_POST, "deviceName", FILTER_SANITIZE_STRING),
+ "manufacturer" => filter_input(INPUT_POST, "deviceManufacturer", FILTER_SANITIZE_STRING),
+ "model" => filter_input(INPUT_POST, "deviceModel", FILTER_SANITIZE_STRING)
+ ],
+ "proxy" => [
+ "endpoint" => filter_input(INPUT_POST, "endpoint", FILTER_SANITIZE_STRING)
+ ],
+ "stream" => [
+ "port" => filter_input(INPUT_POST, "sport", FILTER_SANITIZE_STRING),
+ "file" => ""
+ ],
+ "socket" => [
+ "port" => ""
+ ],
+ "os" => [
+ "name" => filter_input(INPUT_POST, "osName", FILTER_SANITIZE_STRING),
+ "manufacturer" => filter_input(INPUT_POST, "osManufacturer", FILTER_SANITIZE_STRING),
+ "version" => filter_input(INPUT_POST, "osVersion", FILTER_SANITIZE_STRING)
+ ],
+ "protocols" => $protocols,
+ "status" => [
+ "value" => "OFFLINE",
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "keys" => [
+ "public" => $pubKey,
+ "private" => $this->_GeniSys->_helpers->oEncrypt($privKeyHash),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "blockchain" => [
+ "address" => $newBcUser,
+ "password" => $this->_GeniSys->_helpers->oEncrypt($bcPass)
+ ],
+ "mqtt" => [
+ "username" => $this->_GeniSys->_helpers->oEncrypt($mqttUser),
+ "password" => $this->_GeniSys->_helpers->oEncrypt($mqttPass),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "coap" => [
+ "username" => "",
+ "password" => ""
+ ],
+ "amqp" => [
+ "username" => $this->_GeniSys->_helpers->oEncrypt($amqppubKey),
+ "password" => $this->_GeniSys->_helpers->oEncrypt($amqpprvKey),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "batteryLevel" => [
+ "value" => 0.00
+ ],
+ "cpuUsage" => [
+ "value" => 0.00
+ ],
+ "memoryUsage" => [
+ "value" => 0.00
+ ],
+ "hddUsage" => [
+ "value" => 0.00
+ ],
+ "temperature" => [
+ "value" => 0.00
+ ],
+ "ip" => [
+ "value" => $this->_GeniSys->_helpers->oEncrypt($ip),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "mac" => [
+ "value" => $this->_GeniSys->_helpers->oEncrypt($mac),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "bluetooth" => [
+ "address" => $bluetooth ? $this->_GeniSys->_helpers->oEncrypt($bluetooth) : "",
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "ai" => $models,
+ "sensors" => $sensors,
+ "actuators" => $actuators,
+ "dateCreated" => [
+ "type" => "DateTime",
+ "value" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "dateFirstUsed" => [
+ "type" => "DateTime",
+ "value" => ""
+ ],
+ "dateModified" => [
+ "type" => "DateTime",
+ "value" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ]
+ ];
+
+ $response = json_decode($this->contextBrokerRequest("POST", $this->cb["entities_url"] . "?type=Device", $this->createContextHeaders(), json_encode($data)), true);
+
+ if($response["Response"]=="OK"):
+
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO mqttu (
+ `lid`,
+ `zid`,
+ `did`,
+ `uname`,
+ `pw`
+ ) VALUES (
+ :lid,
+ :zid,
+ :did,
+ :uname,
+ :pw
+ )
+ ");
+ $query->execute([
+ ':lid' => $lid,
+ ':zid' => $zid,
+ ':did' => $did,
+ ':uname' => $mqttUser,
+ ':pw' => $mqttHash
+ ]);
+
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO mqttua (
+ `lid`,
+ `zid`,
+ `did`,
+ `username`,
+ `topic`,
+ `rw`
+ ) VALUES (
+ :lid,
+ :zid,
+ :did,
+ :username,
+ :topic,
+ :rw
+ )
+ ");
+ $query->execute(array(
+ ':lid' => $lid,
+ ':zid' => $zid,
+ ':did' => $did,
+ ':username' => $mqttUser,
+ ':topic' => $location["context"]["Data"]["id"] . "/Devices/" . $zone["context"]["Data"]["id"] . "/" . $pubKey . "/#",
+ ':rw' => 4
+ ));
+
+ $amid = $this->addAmqpUser($amqppubKey, $amqpKeyHash);
+ $this->addAmqpUserVh($amid, "iotJumpWay");
+ $this->addAmqpVhPerm($amid, "iotJumpWay", "exchange", "Core", "read");
+ $this->addAmqpVhPerm($amid, "iotJumpWay", "exchange", "Core", "write");
+ $this->addAmqpVhPerm($amid, "iotJumpWay", "queue", "Life", "read");
+ $this->addAmqpVhPerm($amid, "iotJumpWay", "queue", "Life", "write");
+ $this->addAmqpVhPerm($amid, "iotJumpWay", "queue", "Statuses", "read");
+ $this->addAmqpVhPerm($amid, "iotJumpWay", "queue", "Statuses", "write");
+ $this->addAmqpVhTopic($amid, "iotJumpWay", "topic", "Core", "read", "Life");
+ $this->addAmqpVhTopic($amid, "iotJumpWay", "topic", "Core", "write", "Life");
+ $this->addAmqpVhTopic($amid, "iotJumpWay", "topic", "Core", "read", "Statuses");
+ $this->addAmqpVhTopic($amid, "iotJumpWay", "topic", "Core", "write", "Statuses");
+
+ $hash = "";
+ $msg = "";
+ $actionMsg = "";
+ $balanceMessage = "";
+ $this->contract->at($this->_GeniSys->_helpers->oDecrypt($this->bcc["contract"]))->send("registerDevice", $pubKey, $newBcUser, $lid, $zid, $did, $name, $_SESSION["GeniSysAI"]["Uid"], time(), ["from" => $_SESSION["GeniSysAI"]["BC"]["BCUser"]], function ($err, $resp) use (&$hash, &$msg) {
+ if ($err !== null) {
+ $hash = "FAILED";
+ $msg = $err;
+ return;
+ }
+ $hash = $resp;
+ });
+
+ if($hash == "FAILED"):
+ $actionMsg = " HIAS Blockchain registerDevice failed!\n" . $msg;
+ else:
+ $txid = $this->storeBlockchainTransaction("Register Device", $hash, $did);
+ $this->storeUserHistory("Register Device", $txid, $lid, $zid, $did);
+ $balance = $this->getBlockchainBalance();
+ $actionMsg = " HIAS Blockchain registerDevice OK!\n";
+ $balanceMessage = " You were rewarded for this action! Your balance is now: " . $balance . " HIAS Ether!";
+ endif;
+
+ $this->icontract->at($this->_GeniSys->_helpers->oDecrypt($this->bcc["icontract"]))->send("registerAuthorized", $newBcUser, ["from" => $_SESSION["GeniSysAI"]["BC"]["BCUser"]], function ($err, $resp) use (&$hash, &$msg) {
+ if ($err !== null) {
+ $hash = "FAILED";
+ $msg = $err;
+ return;
+ }
+ $hash = $resp;
+ });
+
+ if($hash == "FAILED"):
+ $actionMsg .= " HIAS Blockchain registerAuthorized failed! " . $msg;
+ else:
+ $txid = $this->storeBlockchainTransaction("iotJumpWay Register Authorized", $hash, $did);
+ $this->storeUserHistory("Register Authorized", $txid, $lid, $zid, $did);
+ $balance = $this->getBlockchainBalance();
+ $actionMsg .= " HIAS Blockchain registerAuthorized OK!\n";
+ $balanceMessage = " You were rewarded for this action! Your balance is now: " . $balance . " HIAS Ether!";
+ endif;
+
+ return [
+ "Response"=> "OK",
+ "Message" => "Device created!" . $actionMsg . $balanceMessage,
+ "LID" => filter_input(INPUT_POST, "lid", FILTER_SANITIZE_NUMBER_INT),
+ "ZID" => filter_input(INPUT_POST, "zid", FILTER_SANITIZE_NUMBER_INT),
+ "DID" => $did,
+ "MU" => $mqttUser,
+ "MP" => $mqttPass,
+ "BU" => $newBcUser,
+ "BP" => $bcPass,
+ "AppID" => $pubKey,
+ "AppKey" => $privKey
+ ];
+ else:
+ return [
+ "Response"=> "FAILED",
+ "Message" => "Device creating failed"
+ ];
+ endif;
+ }
+
+ public function updateDevice()
+ {
+ if(!filter_input(INPUT_POST, "lid", FILTER_SANITIZE_NUMBER_INT)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Location ID is required"
+ ];
+ endif;
+
+ if(!$this->checkLocation(filter_input(INPUT_POST, "lid", FILTER_SANITIZE_NUMBER_INT))):
+ return [
+ "Response"=> "Failed",
+ "Message" => "iotJumpWay location does not exist"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "zid", FILTER_SANITIZE_NUMBER_INT)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Zone ID is required"
+ ];
+ endif;
+
+ if(!$this->checkZone(filter_input(INPUT_POST, "zid", FILTER_SANITIZE_NUMBER_INT))):
+ return [
+ "Response"=> "Failed",
+ "Message" => "iotJumpWay zone does not exist"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "category", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Category is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "ctype", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Model type is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "agent", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "IoT Agent is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "name", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "description", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "deviceName", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Hardware device name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "deviceManufacturer", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Hardware device manufacturer is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "deviceModel", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Hardware device model is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osName", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osManufacturer", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system manufacturer is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osVersion", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system version is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "agent", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "IoT Agent is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "coordinates", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Coordinates entity is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "ip", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "IP is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "mac", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "MAC is required"
+ ];
+ endif;
+
+ if(!count($_POST["protocols"])):
+ return [
+ "Response"=> "Failed",
+ "Message" => "At least one M2M protocol is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "datasetUsed", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Dataset used is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "datasetLink", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Dataset link is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "datasetAuthor", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Dataset author is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "datasetFolder", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Dataset folder is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "relatedPaper", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Related paper is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "sport", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Device server port is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "endpoint", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Proxy endpoint is required"
+ ];
+ endif;
+
+ $unlocked = $this->unlockBlockchainAccount();
+
+ if($unlocked == "FAILED"):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Unlocking HIAS Blockhain Account Failed!"
+ ];
+ endif;
+
+ $ip = filter_input(INPUT_POST, "ip", FILTER_SANITIZE_STRING);
+ $mac = filter_input(INPUT_POST, "mac", FILTER_SANITIZE_STRING);
+ $bluetooth = filter_input(INPUT_POST, "bluetooth", FILTER_SANITIZE_STRING);
+ $name = filter_input(INPUT_POST, "name", FILTER_SANITIZE_STRING);
+ $status = filter_input(INPUT_POST, "status", FILTER_SANITIZE_STRING);
+ $coords = explode(",", filter_input(INPUT_POST, "coordinates", FILTER_SANITIZE_STRING));
+
+ $did = filter_input(INPUT_GET, "device", FILTER_SANITIZE_NUMBER_INT);
+ $device = $this->getDevice($did);
+
+ $lid = filter_input(INPUT_POST, 'lid', FILTER_SANITIZE_NUMBER_INT);
+ $location = $this->getLocation($lid);
+
+ $zid = filter_input(INPUT_POST, 'zid', FILTER_SANITIZE_NUMBER_INT);
+ $zone = $this->getZone($zid);
+
+ $protocols = [];
+ foreach($_POST["protocols"] AS $key => $value):
+ $protocols[] = $value;
+ endforeach;
+
+ $models = [];
+ if(isSet($_POST["ai"])):
+ foreach($_POST["ai"] AS $key => $value):
+ $model = $this->getModel($value)["context"]["Data"];
+ $mname = $model["name"]["value"];
+ unset($model["id"]);
+ unset($model["type"]);
+ unset($model["mid"]);
+ unset($model["name"]);
+ unset($model["description"]);
+ unset($model["network"]);
+ unset($model["language"]);
+ unset($model["framework"]);
+ unset($model["toolkit"]);
+ unset($model["dateCreated"]);
+ unset($model["dateModified"]);
+ $models[$mname] = $model;
+ endforeach;
+ endif;
+
+ $sensors = [];
+ if(isSet($_POST["sensors"])):
+ foreach($_POST["sensors"] AS $key => $value):
+ $sensor = $this->getThing($value)["context"]["Data"];
+ unset($sensor["id"]);
+ unset($sensor["type"]);
+ unset($sensor["category"]);
+ unset($sensor["description"]);
+ unset($sensor["thing"]);
+ unset($sensor["properties"]["image"]);
+ unset($sensor["dateCreated"]);
+ unset($sensor["dateModified"]);
+ $sensors[] = $sensor;
+ endforeach;
+ endif;
+
+ $actuators = [];
+ if(isSet($_POST["actuators"])):
+ foreach($_POST["actuators"] AS $key => $value):
+ $actuator = $this->getThing($value)["context"]["Data"];
+ unset($actuator["id"]);
+ unset($actuator["type"]);
+ unset($actuator["category"]);
+ unset($actuator["description"]);
+ unset($actuator["thing"]);
+ unset($actuator["properties"]["image"]);
+ unset($actuator["dateCreated"]);
+ unset($actuator["dateModeified"]);
+ $actuators[] = $actuator;
+ endforeach;
+ endif;
+
+ if($device["context"]["Data"]["lid"]["value"] != $lid):
+ $query = $this->_GeniSys->_secCon->prepare("
+ UPDATE mqttu
+ SET lid = :lid
+ WHERE did = :did
+ ");
+ $query->execute([
+ ':lid' => $lid,
+ ':did' => $did
+ ]);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ $query = $this->_GeniSys->_secCon->prepare("
+ UPDATE mqttua
+ SET lid = :lid
+ WHERE did = :did
+ ");
+ $query->execute([
+ ':lid' => $lid,
+ ':did' => $did
+ ]);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ $query = $this->_GeniSys->_secCon->prepare("
+ UPDATE mqttua
+ SET topic = :topicN
+ WHERE did = :did
+ & topic = :topic
+ ");
+ $query->execute([
+ ':topicN' => $device["context"]["Data"]["lid"]["entity"] . "/ " . $device["context"]["Data"]["zid"]["entity"] . "/Devices/" . $device["context"]["Data"]["id"] . "/#",
+ ':did' => $did,
+ ':topic' => $location["context"]["Data"]["id"] . "/Devices/" . $zone["context"]["Data"]["id"] . "/Devices/" . $device["context"]["Data"]["id"] . "/#"
+ ]);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+ endif;
+
+ $data = [
+ "category" => [
+ "value" => [filter_input(INPUT_POST, "category", FILTER_SANITIZE_STRING)]
+ ],
+ "name" => [
+ "value" => $name
+ ],
+ "description" => [
+ "value" => filter_input(INPUT_POST, "description", FILTER_SANITIZE_STRING)
+ ],
+ "lid" => [
+ "value" => $lid,
+ "entity" => $location["context"]["Data"]["id"]
+ ],
+ "zid" => [
+ "value" => $zid,
+ "entity" => $zone["context"]["Data"]["id"]
+ ],
+ "location" => [
+ "type" => "geo:json",
+ "value" => [
+ "type" => "Point",
+ "coordinates" => [floatval($coords[0]), floatval($coords[1])]
+ ]
+ ],
+ "agent" => [
+ "url" => filter_input(INPUT_POST, "agent", FILTER_SANITIZE_STRING)
+ ],
+ "paper" => [
+ "title" => filter_input(INPUT_POST, "relatedPaper", FILTER_SANITIZE_STRING),
+ "author" => filter_input(INPUT_POST, "relatedPaperAuthor", FILTER_SANITIZE_STRING),
+ "doi" => filter_input(INPUT_POST, "relatedPaperDOI", FILTER_SANITIZE_STRING),
+ "link" => filter_input(INPUT_POST, "relatedPaperLink", FILTER_SANITIZE_STRING)
+ ],
+ "dataset" => [
+ "name" => filter_input(INPUT_POST, "datasetUsed", FILTER_SANITIZE_STRING),
+ "author" => filter_input(INPUT_POST, "datasetAuthor", FILTER_SANITIZE_STRING),
+ "url" => filter_input(INPUT_POST, "datasetLink", FILTER_SANITIZE_STRING),
+ "folder" => filter_input(INPUT_POST, "datasetFolder", FILTER_SANITIZE_STRING)
+ ],
+ "device" => [
+ "type" => filter_input(INPUT_POST, "ctype", FILTER_SANITIZE_STRING),
+ "name" => filter_input(INPUT_POST, "deviceName", FILTER_SANITIZE_STRING),
+ "manufacturer" => filter_input(INPUT_POST, "deviceManufacturer", FILTER_SANITIZE_STRING),
+ "model" => filter_input(INPUT_POST, "deviceModel", FILTER_SANITIZE_STRING)
+ ],
+ "proxy" => [
+ "endpoint" => filter_input(INPUT_POST, "endpoint", FILTER_SANITIZE_STRING)
+ ],
+ "stream" => [
+ "port" => filter_input(INPUT_POST, "sport", FILTER_SANITIZE_STRING),
+ "file" => ""
+ ],
+ "socket" => [
+ "port" => ""
+ ],
+ "os" => [
+ "name" => filter_input(INPUT_POST, "osName", FILTER_SANITIZE_STRING),
+ "manufacturer" => filter_input(INPUT_POST, "osManufacturer", FILTER_SANITIZE_STRING),
+ "version" => filter_input(INPUT_POST, "osVersion", FILTER_SANITIZE_STRING)
+ ],
+ "protocols" => $protocols,
+ "ip" => [
+ "value" => $this->_GeniSys->_helpers->oEncrypt($ip),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "mac" => [
+ "value" => $this->_GeniSys->_helpers->oEncrypt($mac),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "bluetooth" => [
+ "address" => $bluetooth ? $this->_GeniSys->_helpers->oEncrypt($bluetooth) : "",
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "ai" => $models,
+ "sensors" => $sensors,
+ "actuators" => $actuators,
+ "dateModified" => [
+ "type" => "DateTime",
+ "value" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ]
+ ];
+
+ $response = json_decode($this->contextBrokerRequest("PATCH", $this->cb["entities_url"] . "/" . $device["context"]["Data"]["id"] . "/attrs?type=Device", $this->createContextHeaders(), json_encode($data)), true);
+
+ if($response["Response"]=="OK"):
+
+ $hash = "";
+ $msg = "";
+ $this->contract->at($this->_GeniSys->_helpers->oDecrypt($this->bcc["contract"]))->send("updateDevice", $device["context"]["Data"]["id"], "Device", $lid, $zid, $did, $name, $device["context"]["Data"]["status"]["value"], time(), ["from" => $_SESSION["GeniSysAI"]["BC"]["BCUser"]], function ($err, $resp) use (&$hash, &$msg) {
+ if ($err !== null) {
+ $hash = "FAILED";
+ $msg = $err;
+ return;
+ }
+ $hash = $resp;
+ });
+
+ $balance = "";
+ $balanceMessage = "";
+ $actionMsg = "";
+ if($hash == "FAILED"):
+ $actionMsg = " HIAS Blockchain updateDevice failed! " . $msg;
+ else:
+ $txid = $this->storeBlockchainTransaction("Update Device", $hash, $did);
+ $this->storeUserHistory("Updated Device", $txid, $lid, $zid, $did);
+ $balance = $this->getBlockchainBalance();
+ $balanceMessage = " You were rewarded for this action! Your balance is now: " . $balance . " HIAS Ether!";
+ endif;
+
+ $device = $this->getDevice($did);
+
+ return [
+ "Response"=> "OK",
+ "Message" => "Device updated!" . $actionMsg . $balanceMessage,
+ "Schema" => $device["context"]["Data"]
+ ];
+ else:
+ return [
+ "Response"=> "Failed",
+ "Message" => "There was a problem updating this device context data!"
+ ];
+ endif;
+ }
+
+ public function deleteData()
+ {
+ $images = glob($this->dataFiles);
+ foreach( $images as $image ):
+ unlink($image);
+ endforeach;
+
+ return [
+ "Response" => "OK",
+ "Message" => "Deleted Acute Lymphoblastic Leukemia Image Database for Image Processing Dataset"
+ ];
+
+ }
+
+ public function uploadData()
+ {
+ $dataCells = '';
+ if(is_array($_FILES) && !empty($_FILES['skindata'])):
+ foreach($_FILES['skindata']['name'] as $key => $filename):
+ $file_name = explode(".", $filename);
+ if(in_array($file_name[1], $this->allowedFiles)):
+ $sourcePath = $_FILES["skindata"]["tmp_name"][$key];
+ $targetPath = $this->dataDir . $filename;
+ if(!move_uploaded_file($sourcePath, $targetPath)):
+ return [
+ "Response" => "FAILED",
+ "Message" => "Upload failed " . $targetPath
+ ];
+ endif;
+ else:
+ return [
+ "Response" => "FAILED",
+ "Message" => "Please upload jpg files"
+ ];
+ endif;
+ endforeach;
+
+ $images = glob($this->dataFiles);
+ $count = 1;
+ foreach($images as $image):
+ $dataCells .= "
";
+ if($count%6 == 0):
+ $dataCells .= "
";
+ endif;
+ $count++;
+ endforeach;
+
+ else:
+ return [
+ "Response" => "FAILED",
+ "Message" => "You must upload some images (jpg)"
+ ];
+ endif;
+
+ return [
+ "Response" => "OK",
+ "Message" => "Data upload OK!",
+ "Data" => $dataCells
+ ];
+
+ }
+
+ public function classifyData()
+ {
+ $file = $this->dataDirFull . filter_input(INPUT_POST, "im", FILTER_SANITIZE_STRING);
+ $mime = mime_content_type($file);
+ $info = pathinfo($file);
+ $name = $info['basename'];
+ $toSend = new CURLFile($file, $mime, $name);
+
+ $headers = [
+ 'Authorization: Basic '. base64_encode($_SESSION["GeniSysAI"]["User"] . ":" . $this->_GeniSys->_helpers->oDecrypt($_SESSION["GeniSysAI"]["Pass"]))
+ ];
+
+ $ch = curl_init($this->api);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_POST, true);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, [
+ 'file'=> $toSend,
+ ]);
+
+ $resp = curl_exec($ch);
+
+ return json_decode($resp, true);
+
+ }
+
+ }
+
+ $Skin = new Skin($_GeniSys);
+
+ if(filter_input(INPUT_POST, "create_skin_classifier", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($Skin->createDevice()));
+ endif;
+
+ if(filter_input(INPUT_POST, "update_skin_classifier", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($Skin->updateDevice()));
+ endif;
+
+ if(filter_input(INPUT_POST, "reset_mqtt", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($Skin->resetMqtt()));
+ endif;
+
+ if(filter_input(INPUT_POST, "reset_key", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($Skin->resetDvcKey()));
+ endif;
+
+ if(filter_input(INPUT_POST, "get_tlife", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($Skin->getLife()));
+ endif;
+
+ if(filter_input(INPUT_POST, "deleteData", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($Skin->deleteData()));
+ endif;
+
+ if(filter_input(INPUT_POST, "uploadAllData", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($Skin->uploadData()));
+ endif;
+
+ if(filter_input(INPUT_POST, "classifyData", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($Skin->classifyData()));
+ endif;
diff --git a/Root/var/www/html/AI/Skin/Classify.php b/Root/var/www/html/AI/Skin/Classify.php
new file mode 100644
index 0000000..406ab26
--- /dev/null
+++ b/Root/var/www/html/AI/Skin/Classify.php
@@ -0,0 +1,202 @@
+ "AI",
+ "SubPageID" => "AISkin"
+];
+
+include dirname(__FILE__) . '/../../../Classes/Core/init.php';
+include dirname(__FILE__) . '/../../../Classes/Core/GeniSys.php';
+include dirname(__FILE__) . '/../../iotJumpWay/Classes/iotJumpWay.php';
+include dirname(__FILE__) . '/../../AI/Skin/Classes/Skin.php';
+
+$_GeniSysAi->checkSession();
+
+$Locations = $iotJumpWay->getLocations();
+$Zones = $iotJumpWay->getZones();
+$Devices = $Skin->getDevices();
+
+$TId = filter_input(INPUT_GET, 'device', FILTER_SANITIZE_NUMBER_INT);
+$Device = $iotJumpWay->getDevice($TId);
+
+list($dev1On, $dev1Off) = $iotJumpWay->getStatusShow($Device["context"]["Data"]["status"]["value"]);
+
+$Skin->setClassifierConfs();
+
+?>
+
+
+
+
+
+
+
+
+
+
=$_GeniSys->_confs["meta_title"]; ?>
+
" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Skin Classifier #=$TId; ?>
+
+
+
+
+
+
+
+
+
+
+
+ dataFiles);
+ $count = 1;
+ if(count($images)):
+ foreach( $images as $image ):
+ echo "
";
+ if($count%6 == 0):
+ echo"
";
+ endif;
+ $count++;
+ endforeach;
+ else:
+ echo "
Please upload your test dataset.
";
+ endif;
+ ?>
+
+
+
+
+
+
+
+
+
+
+
+
Diagnosis Results
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Root/var/www/html/AI/Skin/Create.php b/Root/var/www/html/AI/Skin/Create.php
new file mode 100644
index 0000000..f6c6c6e
--- /dev/null
+++ b/Root/var/www/html/AI/Skin/Create.php
@@ -0,0 +1,422 @@
+ "AI",
+ "SubPageID" => "AISkin"
+];
+
+include dirname(__FILE__) . '/../../../Classes/Core/init.php';
+include dirname(__FILE__) . '/../../../Classes/Core/GeniSys.php';
+include dirname(__FILE__) . '/../../iotJumpWay/Classes/iotJumpWay.php';
+include dirname(__FILE__) . '/../../AI/Skin/Classes/Skin.php';
+include dirname(__FILE__) . '/../../AI/Classes/AI.php';
+
+$_GeniSysAi->checkSession();
+
+$Zones = $iotJumpWay->getZones();
+$Devices = $iotJumpWay->getDevices();
+
+?>
+
+
+
+
+
+
+
+
+
=$_GeniSys->_confs["meta_title"]; ?>
+
" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Create Skin Classifier Device
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Root/var/www/html/Security/GeniSysAI/Live/index.php b/Root/var/www/html/AI/Skin/Data/.keep
similarity index 100%
rename from Root/var/www/html/Security/GeniSysAI/Live/index.php
rename to Root/var/www/html/AI/Skin/Data/.keep
diff --git a/Root/var/www/html/AI/Skin/Device.php b/Root/var/www/html/AI/Skin/Device.php
new file mode 100644
index 0000000..e3b2063
--- /dev/null
+++ b/Root/var/www/html/AI/Skin/Device.php
@@ -0,0 +1,955 @@
+ "AI",
+ "SubPageID" => "AISkin"
+];
+
+include dirname(__FILE__) . '/../../../Classes/Core/init.php';
+include dirname(__FILE__) . '/../../../Classes/Core/GeniSys.php';
+include dirname(__FILE__) . '/../../iotJumpWay/Classes/iotJumpWay.php';
+include dirname(__FILE__) . '/../../AI/Skin/Classes/Skin.php';
+include dirname(__FILE__) . '/../../AI/Classes/AI.php';
+
+$_GeniSysAi->checkSession();
+
+$Locations = $iotJumpWay->getLocations();
+$Zones = $iotJumpWay->getZones();
+$Devices = $Skin->getDevices();
+
+$TId = filter_input(INPUT_GET, 'device', FILTER_SANITIZE_NUMBER_INT);
+$Device = $iotJumpWay->getDevice($TId);
+
+list($dev1On, $dev1Off) = $iotJumpWay->getStatusShow($Device["context"]["Data"]["status"]["value"]);
+
+?>
+
+
+
+
+
+
+
+
+
+
=$_GeniSys->_confs["meta_title"]; ?>
+
" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Skin Classifier Device #=$TId; ?>
+
+
+
+
+
+
+
+
+
+
Device Schema
+
+
+
+
+
+
+
+
+
+
Device History
+
+
+
+
+
+
+
+
+
+
Device Transactions
+
+
+
+
+
+
+
+
+
+
Device iotJumpWay Statuses
+
+
+
+
+
+
+
+
+
+
+
+ ID
+ Status
+ Time
+
+
+
+
+ retrieveDeviceStatuses($Device["context"]["Data"]["did"]["value"], 5);
+ if($Statuses["Response"] == "OK"):
+ foreach($Statuses["ResponseData"] as $key => $value):
+ ?>
+
+
+ #=$value->_id;?>
+ =$value->Status;?>
+ =$value->Time;?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Device iotJumpWay Life
+
+
+
+
+
+
+
+
+
+
+
+ ID
+ Details
+ Time
+
+
+
+
+ retrieveDeviceLife($Device["context"]["Data"]["did"]["value"], 5);
+ if($Statuses["Response"] == "OK"):
+ foreach($Statuses["ResponseData"] as $key => $value):
+ ?>
+
+
+ #=$value->_id;?>
+
+ CPU : =$value->Data->CPU;?>%
+ Memory : =$value->Data->Memory;?>%
+ Diskspace : =$value->Data->Diskspace;?>%
+ Temperature : =$value->Data->Temperature;?>°C
+ Latitude : =$value->Data->Latitude;?>
+ Longitude : =$value->Data->Longitude;?>
+
+ =$value->Time;?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Device iotJumpWay Sensors
+
+
+
+
+
+
+
+
+
+
+
+ ID
+ Type
+ Sensor
+ Value
+ Message
+ Time
+
+
+
+
+ retrieveDeviceSensors($Device["context"]["Data"]["did"]["value"], 5);
+ if($Statuses["Response"] == "OK"):
+ foreach($Statuses["ResponseData"] as $key => $value):
+ $location = $iotJumpWay->getLocation($value->Location);
+ ?>
+
+ #=$value->_id;?>
+ =$value->Type;?>
+ =$value->Sensor;?>
+
+ Sensor == "Facial API" || $value->Sensor == "Foscam Camera" || $value->Sensor == "USB Camera") && is_array($value->Value)):
+ foreach($value->Value AS $key => $val):
+ echo $val[0] == 0 ? "Identification: Intruder " :"Identification: User #" . $val[0] . " ";
+ echo "Distance: " . $val[1] . " ";
+ echo "Message: " . $val[2] . " ";
+ endforeach;
+ else:
+ echo $value->Value;
+ endif;
+ ?>
+
+
+ =$value->Message;?>
+ =$value->Time;?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Device iotJumpWay Commands
+
+
+
+
+
+
+
+
+
+
+
+ ID
+ Details
+ Status
+ Time
+
+
+
+
+ retrieveDeviceCommands($Device["context"]["Data"]["did"]["value"], 5);
+ if($Statuses["Response"] == "OK"):
+ foreach($Statuses["ResponseData"] as $key => $value):
+ $location = $iotJumpWay->getLocation($value->Location);
+ ?>
+
+
+ #=$value->_id;?>
+ Location: #=$value->Location;?> - =$location["name"]; ?>
+ =$value->Status;?>
+ =$value->Time;?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Root/var/www/html/AI/Skin/index.php b/Root/var/www/html/AI/Skin/index.php
new file mode 100644
index 0000000..528803f
--- /dev/null
+++ b/Root/var/www/html/AI/Skin/index.php
@@ -0,0 +1,178 @@
+ "AI",
+ "SubPageID" => "AISkin"
+];
+
+include dirname(__FILE__) . '/../../../Classes/Core/init.php';
+include dirname(__FILE__) . '/../../../Classes/Core/GeniSys.php';
+include dirname(__FILE__) . '/../../iotJumpWay/Classes/iotJumpWay.php';
+include dirname(__FILE__) . '/../../AI/Skin/Classes/Skin.php';
+
+$_GeniSysAi->checkSession();
+$Devices = $Skin->getDevices();
+
+?>
+
+
+
+
+
+
+
+
+
+
=$_GeniSys->_confs["meta_title"]; ?>
+
" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Skin Cancer Models
+
+
+
+
+
+
+
The Skin Cancer are a range of computer vision models for detecting skin cancer, designed by the Peter Leukemia AI Research team in collaboration with Melanoscan . The models are designed to be used on constrained devices making them suitable for IoT networks. These models use a variety of programming languages, frameworks and hardware providing.
+
+
+
+
+
+
+
In addition to using Skin Cancer detection models created by the Peter Leukemia AI Research team, you can develop your own models and connect them up to the HIAS network.
+
+
+
+
+
+
+
Skin Cancer Devices
+
+
+
+
+
+
+
+
+
+
+
+ ID
+ DETAILS
+ STATUS
+ ACTION
+
+
+
+
+ $value):
+ ?>
+
+
+ #=$value["did"]["value"];?>
+
+ Name: =$value["name"]["value"];?>
+ Zone: #=$value["zid"]["value"];?>
+
+
+ ">
+ =$value["status"]["value"] == "OFFLINE" ? "OFFLINE" : "ONLINE"; ?>
+
+
+ "> Edit | /Classify"> Classify
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Root/var/www/html/AI/TassAI/Classes/TassAI.js b/Root/var/www/html/AI/TassAI/Classes/TassAI.js
new file mode 100644
index 0000000..1dd10a1
--- /dev/null
+++ b/Root/var/www/html/AI/TassAI/Classes/TassAI.js
@@ -0,0 +1,56 @@
+var GeniSysAI = {
+ Create: function() {
+ $.post(window.location.href, $("#genisysai_create").serialize(), function(resp) {
+ var resp = jQuery.parseJSON(resp);
+ switch (resp.Response) {
+ case "OK":
+ GeniSys.ResetForm("genisysai_create");
+ $('.modal-title').text('GeniSyAI Security Devices');
+ $('.modal-body').html("HIAS GeniSyAI Security Device ID #" + resp.GDID + " created! Please save the API keys safely. The device's credentials are provided below. The credentials can be reset in the GeniSyAI Security Devices area.
Device ID: " + resp.DID + "
MQTT User: " + resp.MU + "
MQTT Password: " + resp.MP + "
Blockchain User: " + resp.BU + "
Blockchain Pass: " + resp.BP + "
App ID: " + resp.AppID + "
App Key: " + resp.AppKey + "
" + resp.Message);
+ $('#responsive-modal').modal('show');
+ Logging.logMessage("Core", "Forms", "Device ID #" + resp.DID + " created!");
+ break;
+ default:
+ msg = "GeniSysAI Create Failed: " + resp.Message
+ Logging.logMessage("Core", "GeniSysAI", msg);
+ break;
+ }
+ });
+ },
+ Update: function() {
+ $.post(window.location.href, $("#genisysai_update").serialize(), function(resp) {
+ var resp = jQuery.parseJSON(resp);
+ switch (resp.Response) {
+ case "OK":
+ var fjson = JSON.stringify(resp.Schema, null, '\t');
+ window.parent.$('#schema').html(fjson);
+ Logging.logMessage("Core", "Forms", "Device Update OK");
+ $('.modal-title').text('Device Update');
+ $('.modal-body').text(resp.Message);
+ $('#responsive-modal').modal('show');
+ break;
+ default:
+ msg = "GeniSysAI Update Failed: " + resp.Message
+ Logging.logMessage("Core", "GeniSysAI", msg);
+ break;
+ }
+ });
+ }
+};
+$(document).ready(function() {
+
+ $('#genisysai_create').validator().on('submit', function(e) {
+ if (!e.isDefaultPrevented()) {
+ e.preventDefault();
+ GeniSysAI.Create();
+ }
+ });
+
+ $('#genisysai_update').validator().on('submit', function(e) {
+ if (!e.isDefaultPrevented()) {
+ e.preventDefault();
+ GeniSysAI.Update();
+ }
+ });
+
+});
\ No newline at end of file
diff --git a/Root/var/www/html/AI/TassAI/Classes/TassAI.php b/Root/var/www/html/AI/TassAI/Classes/TassAI.php
new file mode 100644
index 0000000..59821f5
--- /dev/null
+++ b/Root/var/www/html/AI/TassAI/Classes/TassAI.php
@@ -0,0 +1,1527 @@
+_GeniSys = $_GeniSys;
+ $this->bcc = $this->getBlockchainConf();
+ $this->web3 = $this->blockchainConnection();
+ $this->contract = new Contract($this->web3->provider, $this->bcc["abi"]);
+ $this->icontract = new Contract($this->web3->provider, $this->bcc["iabi"]);
+ $this->checkBlockchainPermissions();
+ endif;
+ $this->cb = $this->getContextBrokerConf();
+ }
+
+ public function getContextBrokerConf()
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM contextbroker
+ ");
+ $pdoQuery->execute();
+ $response=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+ return $response;
+ }
+
+ private function createContextHeaders()
+ {
+ $basicAuth = $_SESSION["GeniSysAI"]["User"] . ":" . $this->_GeniSys->_helpers->oDecrypt($_SESSION["GeniSysAI"]["Pass"]);
+ $basicAuth = base64_encode($basicAuth);
+
+ return [
+ "Content-Type: application/json",
+ 'Authorization: Basic '. $basicAuth
+ ];
+ }
+
+ private function contextBrokerRequest($method, $endpoint, $headers, $json)
+ {
+ $path = $this->_GeniSys->_helpers->oDecrypt($this->_GeniSys->_confs["domainString"]) . "/" . $this->cb["url"] . "/" . $endpoint;
+
+ if($method == "GET"):
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ curl_setopt($ch, CURLOPT_HEADER, 1);
+ curl_setopt($ch, CURLOPT_URL, $path);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ $response = curl_exec($ch);
+ $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
+ $header = substr($response, 0, $header_size);
+ $body = substr($response, $header_size);
+ curl_close($ch);
+ elseif($method == "POST"):
+ $ch = curl_init($path);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ curl_setopt($ch, CURLOPT_HEADER, 1);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
+ $response = curl_exec($ch);
+ $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
+ $header = substr($response, 0, $header_size);
+ $body = substr($response, $header_size);
+ curl_close($ch);
+ elseif($method == "PATCH"):
+ $ch = curl_init($path);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ curl_setopt($ch, CURLOPT_HEADER, 1);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
+ $response = curl_exec($ch);
+ $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
+ $header = substr($response, 0, $header_size);
+ $body = substr($response, $header_size);
+ curl_close($ch);
+ endif;
+
+ return $body;
+ }
+
+ public function getBlockchainConf()
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT blockchain.*,
+ contracts.contract,
+ contracts.abi,
+ icontracts.contract as icontract,
+ icontracts.abi as iabi
+ FROM blockchain blockchain
+ INNER JOIN contracts contracts
+ ON contracts.id = blockchain.dc
+ INNER JOIN contracts icontracts
+ ON icontracts.id = blockchain.ic
+ ");
+ $pdoQuery->execute();
+ $response=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+ return $response;
+ }
+
+ private function blockchainConnection()
+ {
+ if(isSet($_SESSION["GeniSysAI"]["Active"])):
+ $web3 = new Web3($this->_GeniSys->_helpers->oDecrypt($this->_GeniSys->_confs["domainString"]) . "/Blockchain/API/", 30, $_SESSION["GeniSysAI"]["User"], $this->_GeniSys->_helpers->oDecrypt($_SESSION["GeniSysAI"]["Pass"]));
+ return $web3;
+ endif;
+ }
+
+ private function checkBlockchainPermissions()
+ {
+ $allowed = "";
+ $errr = "";
+ $this->contract->at($this->_GeniSys->_helpers->oDecrypt($this->bcc["contract"]))->call("identifierAllowed", "User", $_SESSION["GeniSysAI"]["Identifier"], ["from" => $_SESSION["GeniSysAI"]["BC"]["BCUser"]], function ($err, $resp) use (&$allowed, &$errr) {
+ if ($err !== null) {
+ $allowed = "FAILED";
+ $errr = $err;
+ return;
+ }
+ $allowed = $resp;
+ });
+ if(!$allowed):
+ header('Location: /Logout');
+ endif;
+ }
+
+ private function unlockBlockchainAccount()
+ {
+ $response = "";
+ $personal = $this->web3->personal;
+ $personal->unlockAccount($_SESSION["GeniSysAI"]["BC"]["BCUser"], $this->_GeniSys->_helpers->oDecrypt($_SESSION["GeniSysAI"]["BC"]["BCPass"]), function ($err, $unlocked) use (&$response) {
+ if ($err !== null) {
+ $response = "FAILED! " . $err;
+ return;
+ }
+ if ($unlocked) {
+ $response = "OK";
+ } else {
+ $response = "FAILED";
+ }
+ });
+
+ return $response;
+ }
+
+ private function lockBlockchainAccount()
+ {
+ $response = "";
+ $personal = $this->web3->personal;
+ $personal->lockAccount($_SESSION["GeniSysAI"]["BC"]["BCUser"], function ($err, $unlocked) use (&$response) {
+ if ($err !== null) {
+ $response = "FAILED! " . $err;
+ return;
+ }
+ if ($unlocked) {
+ $response = "OK";
+ } else {
+ $response = "FAILED";
+ }
+ });
+
+ return $response;
+ }
+
+ private function createBlockchainUser($pass)
+ {
+ $newAccount = "";
+ $personal = $this->web3->personal;
+ $personal->newAccount($pass, function ($err, $account) use (&$newAccount) {
+ if ($err !== null) {
+ $newAccount = "FAILED!";
+ return;
+ }
+ $newAccount = $account;
+ });
+
+ return $newAccount;
+ }
+
+ private function getBlockchainBalance()
+ {
+ $nbalance = "";
+ $this->web3->eth->getBalance($_SESSION["GeniSysAI"]["BC"]["BCUser"], function ($err, $balance) use (&$nbalance) {
+ if ($err !== null) {
+ $response = "FAILED! " . $err;
+ return;
+ }
+ $nbalance = $balance->toString();
+ });
+
+ return Utils::fromWei($nbalance, 'ether')[0];
+ }
+
+ private function addAmqpUser($username, $key)
+ {
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO amqpu (
+ `username`,
+ `pw`
+ ) VALUES (
+ :username,
+ :pw
+ )
+ ");
+ $query->execute([
+ ':username' => $username,
+ ':pw' => $this->_GeniSys->_helpers->oEncrypt($key)
+ ]);
+ $amid = $this->_GeniSys->_secCon->lastInsertId();
+ return $amid;
+ }
+
+ private function addAmqpUserVh($uid, $vhost)
+ {
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO amqpvh (
+ `uid`,
+ `vhost`
+ ) VALUES (
+ :uid,
+ :vhost
+ )
+ ");
+ $query->execute([
+ ':uid' => $uid,
+ ':vhost' => $vhost
+ ]);
+ }
+
+ private function addAmqpVhPerm($uid, $vhost, $rtype, $rname, $permission)
+ {
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO amqpvhr (
+ `uid`,
+ `vhost`,
+ `rtype`,
+ `rname`,
+ `permission`
+ ) VALUES (
+ :uid,
+ :vhost,
+ :rtype,
+ :rname,
+ :permission
+ )
+ ");
+ $query->execute([
+ ':uid' => $uid,
+ ':vhost' => $vhost,
+ ':rtype' => $rtype,
+ ':rname' => $rname,
+ ':permission' => $permission
+ ]);
+ }
+
+ private function addAmqpVhTopic($uid, $vhost, $rtype, $rname, $permission, $rkey)
+ {
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO amqpvhrt (
+ `uid`,
+ `vhost`,
+ `rtype`,
+ `rname`,
+ `permission`,
+ `rkey`
+ ) VALUES (
+ :uid,
+ :vhost,
+ :rtype,
+ :rname,
+ :permission,
+ :rkey
+ )
+ ");
+ $query->execute([
+ ':uid' => $uid,
+ ':vhost' => $vhost,
+ ':rtype' => $rtype,
+ ':rname' => $rname,
+ ':permission' => $permission,
+ ':rkey' => $rkey
+ ]);
+ }
+
+ private function storeBlockchainTransaction($action, $hash, $device = 0, $application = 0)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO transactions (
+ `uid`,
+ `did`,
+ `aid`,
+ `action`,
+ `hash`,
+ `time`
+ ) VALUES (
+ :uid,
+ :did,
+ :aid,
+ :action,
+ :hash,
+ :time
+ )
+ ");
+ $pdoQuery->execute([
+ ":uid" => $_SESSION["GeniSysAI"]["Uid"],
+ ":did" => $device,
+ ":aid" => $application,
+ ":action" => $action,
+ ':hash' => $this->_GeniSys->_helpers->oEncrypt($hash),
+ ":time" => time()
+ ]);
+ $txid = $this->_GeniSys->_secCon->lastInsertId();
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ return $txid;
+ }
+
+ private function storeUserHistory($action, $hash, $location = 0, $zone = 0, $device = 0, $sensor = 0, $application = 0)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO history (
+ `uid`,
+ `tlid`,
+ `tzid`,
+ `tdid`,
+ `tsid`,
+ `taid`,
+ `action`,
+ `hash`,
+ `time`
+ ) VALUES (
+ :uid,
+ :tlid,
+ :tzid,
+ :tdid,
+ :tsid,
+ :taid,
+ :action,
+ :hash,
+ :time
+ )
+ ");
+ $pdoQuery->execute([
+ ":uid" => $_SESSION["GeniSysAI"]["Uid"],
+ ":tlid" => $location,
+ ":tzid" => $zone,
+ ":tdid" => $device,
+ ":tsid" => $sensor,
+ ":taid" => $application,
+ ":action" => $action,
+ ":hash" => $hash,
+ ":time" => time()
+ ]);
+ $txid = $this->_GeniSys->_secCon->lastInsertId();
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ return $txid;
+ }
+
+ public function checkLocation($lid)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT id
+ FROM mqttl
+ WHERE id = :id
+ ");
+ $pdoQuery->execute([
+ ":id" => $lid
+ ]);
+ $location=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($location["id"]):
+ return True;
+ else:
+ return False;
+ endif;
+ }
+
+ public function getLocation($id, $attrs = Null)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM mqttl
+ WHERE id = :id
+ ");
+ $pdoQuery->execute([
+ ":id" => $id
+ ]);
+ $location=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($attrs):
+ $attrs="&attrs=" . $attrs;
+ endif;
+
+ $location["context"] = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "/" . $location["pub"] . "?type=Location" . $attrs, $this->createContextHeaders(), []), true);
+ return $location;
+ }
+
+ public function checkZone($zid)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT id
+ FROM mqttlz
+ WHERE id = :id
+ ");
+ $pdoQuery->execute([
+ ":id" => $zid
+ ]);
+ $location=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($location["id"]):
+ return True;
+ else:
+ return False;
+ endif;
+ }
+
+ public function getZone($id, $attrs = Null)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM mqttlz
+ WHERE id = :id
+ ORDER BY id DESC
+ ");
+ $pdoQuery->execute([
+ ":id" => $id
+ ]);
+ $zone=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($attrs):
+ $attrs="&attrs=" . $attrs;
+ endif;
+
+ $zone["context"] = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "/" . $zone["pub"] . "?type=Zone" . $attrs, $this->createContextHeaders(), []), true);
+ return $zone;
+ }
+
+ public function getDevices($limit = 0)
+ {
+ $limiter = "";
+ if($limit != 0):
+ $limiter = "&limit=" . $limit;
+ endif;
+
+ $devices = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "?type=Device&category=TassAI".$limiter, $this->createContextHeaders(), []), true);
+ return $devices;
+ }
+
+ public function getDevice($id, $attrs = Null)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM mqttld
+ WHERE id = :id
+ ORDER BY id DESC
+ ");
+ $pdoQuery->execute([
+ ":id" => $id
+ ]);
+ $device=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($attrs):
+ $attrs="&attrs=" . $attrs;
+ endif;
+
+ $device["context"] = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "/" . $device["apub"] . "?type=Device" . $attrs, $this->createContextHeaders(), []), true);
+ return $device;
+ }
+
+ public function getThing($id, $attrs = Null)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM things
+ WHERE id = :id
+ ");
+ $pdoQuery->execute([
+ ":id" => $id
+ ]);
+ $thing=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($attrs):
+ $attrs="&attrs=" . $attrs;
+ endif;
+
+ $thing["context"] = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "/" . $thing["pub"] . "?type=Thing" . $attrs, $this->createContextHeaders(), []), true);
+ return $thing;
+ }
+
+ public function getModel($id, $attrs = Null)
+ {
+ $pdoQuery = $this->_GeniSys->_secCon->prepare("
+ SELECT *
+ FROM models
+ WHERE id = :id
+ ORDER BY id DESC
+ ");
+ $pdoQuery->execute([
+ ":id" => $id
+ ]);
+ $model=$pdoQuery->fetch(PDO::FETCH_ASSOC);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ if($attrs):
+ $attrs="&attrs=" . $attrs;
+ endif;
+
+ $device["context"] = json_decode($this->contextBrokerRequest("GET", $this->cb["entities_url"] . "/" . $model["pub"] . "?type=Model" . $attrs, $this->createContextHeaders(), []), true);
+ return $device;
+ }
+
+ public function createDevice()
+ {
+ if(!filter_input(INPUT_POST, "lid", FILTER_SANITIZE_NUMBER_INT)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Location ID is required"
+ ];
+ endif;
+
+ if(!$this->checkLocation(filter_input(INPUT_POST, "lid", FILTER_SANITIZE_NUMBER_INT))):
+ return [
+ "Response"=> "Failed",
+ "Message" => "iotJumpWay location does not exist"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "zid", FILTER_SANITIZE_NUMBER_INT)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Zone ID is required"
+ ];
+ endif;
+
+ if(!$this->checkZone(filter_input(INPUT_POST, "zid", FILTER_SANITIZE_NUMBER_INT))):
+ return [
+ "Response"=> "Failed",
+ "Message" => "iotJumpWay zone does not exist"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "category", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Category is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "name", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "description", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "coordinates", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Coordinates entity is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "deviceName", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Hardware device name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "deviceManufacturer", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Hardware device manufacturer is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "deviceModel", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Hardware device model is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osName", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osManufacturer", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system manufacturer is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osVersion", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system version is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "agent", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "IoT Agent is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "ip", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "IP is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "mac", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "MAC is required"
+ ];
+ endif;
+
+ if(!count($_POST["protocols"])):
+ return [
+ "Response"=> "Failed",
+ "Message" => "At least one M2M protocol is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "sport", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Device stream port is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "sportf", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Device stream file is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "strdir", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Device stream directory is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "sckport", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Device socket port is required"
+ ];
+ endif;
+
+ $unlocked = $this->unlockBlockchainAccount();
+
+ if($unlocked == "FAILED"):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Unlocking HIAS Blockhain Account Failed!"
+ ];
+ endif;
+
+ $mqttUser = $this->_GeniSys->_helpers->generate_uuid();
+ $mqttPass = $this->_GeniSys->_helpers->password();
+ $mqttHash = create_hash($mqttPass);
+
+ $pubKey = $this->_GeniSys->_helpers->generate_uuid();
+ $privKey = $this->_GeniSys->_helpers->generateKey(32);
+ $privKeyHash = $this->_GeniSys->_helpers->createPasswordHash($privKey);
+
+ $amqppubKey = $this->_GeniSys->_helpers->generate_uuid();
+ $amqpprvKey = $this->_GeniSys->_helpers->generateKey(32);
+ $amqpKeyHash = $this->_GeniSys->_helpers->createPasswordHash($amqpprvKey);
+
+ $bcPass = $this->_GeniSys->_helpers->password();
+
+ $lid = filter_input(INPUT_POST, 'lid', FILTER_SANITIZE_NUMBER_INT);
+ $location = $this->getLocation($lid);
+
+ $zid = filter_input(INPUT_POST, 'zid', FILTER_SANITIZE_NUMBER_INT);
+ $zone = $this->getZone($zid);
+
+ $ip = filter_input(INPUT_POST, "ip", FILTER_SANITIZE_STRING);
+ $mac = filter_input(INPUT_POST, "mac", FILTER_SANITIZE_STRING);
+ $bluetooth = filter_input(INPUT_POST, "bluetooth", FILTER_SANITIZE_STRING);
+ $name = filter_input(INPUT_POST, "name", FILTER_SANITIZE_STRING);
+ $coords = explode(",", filter_input(INPUT_POST, "coordinates", FILTER_SANITIZE_STRING));
+
+ $protocols = [];
+ foreach($_POST["protocols"] AS $key => $value):
+ $protocols[] = $value;
+ endforeach;
+
+ $models = [];
+ if(isSet($_POST["ai"])):
+ foreach($_POST["ai"] AS $key => $value):
+ $model = $this->getModel($value)["context"]["Data"];
+ $mname = $model["name"]["value"];
+ unset($model["id"]);
+ unset($model["type"]);
+ unset($model["mid"]);
+ unset($model["name"]);
+ unset($model["description"]);
+ unset($model["network"]);
+ unset($model["language"]);
+ unset($model["framework"]);
+ unset($model["toolkit"]);
+ unset($model["dateCreated"]);
+ unset($model["dateModified"]);
+ $models[$mname] = $model;
+ endforeach;
+ endif;
+
+ $sensors = [];
+ if(isSet($_POST["sensors"])):
+ foreach($_POST["sensors"] AS $key => $value):
+ $sensor = $this->getThing($value)["context"]["Data"];
+ unset($sensor["id"]);
+ unset($sensor["type"]);
+ unset($sensor["category"]);
+ unset($sensor["description"]);
+ unset($sensor["thing"]);
+ unset($sensor["properties"]["image"]);
+ unset($sensor["dateCreated"]);
+ unset($sensor["dateModified"]);
+ $sensors[] = $sensor;
+ endforeach;
+ endif;
+
+ $actuators = [];
+ if(isSet($_POST["actuators"])):
+ foreach($_POST["actuators"] AS $key => $value):
+ $actuator = $this->getThing($value)["context"]["Data"];
+ unset($actuator["id"]);
+ unset($actuator["type"]);
+ unset($actuator["category"]);
+ unset($actuator["description"]);
+ unset($actuator["thing"]);
+ unset($actuator["properties"]["image"]);
+ unset($actuator["dateCreated"]);
+ unset($actuator["dateModeified"]);
+ $actuators[] = $actuator;
+ endforeach;
+ endif;
+
+ $newBcUser = $this->createBlockchainUser($bcPass);
+
+ if($newBcUser == "FAILED"):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Creating New HIAS Blockhain Account Failed!"
+ ];
+ endif;
+
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO mqttld (
+ `id`
+ ) VALUES (
+ :id
+ )
+ ");
+ $query->execute([
+ ':id' => 0
+ ]);
+ $did = $this->_GeniSys->_secCon->lastInsertId();
+
+ $data = [
+ "id" => $pubKey,
+ "type" => "Device",
+ "category" => [
+ "value" => [filter_input(INPUT_POST, "category", FILTER_SANITIZE_STRING)]
+ ],
+ "name" => [
+ "value" => $name
+ ],
+ "description" => [
+ "value" => filter_input(INPUT_POST, "description", FILTER_SANITIZE_STRING)
+ ],
+ "lid" => [
+ "value" => $lid,
+ "entity" => $location["context"]["Data"]["id"]
+ ],
+ "zid" => [
+ "value" => $zid,
+ "entity" => $zone["context"]["Data"]["id"]
+ ],
+ "did" => [
+ "value" => $did
+ ],
+ "location" => [
+ "type" => "geo:json",
+ "value" => [
+ "type" => "Point",
+ "coordinates" => [floatval($coords[0]), floatval($coords[1])]
+ ]
+ ],
+ "agent" => [
+ "url" => filter_input(INPUT_POST, "agent", FILTER_SANITIZE_STRING)
+ ],
+ "device" => [
+ "type" => filter_input(INPUT_POST, "type", FILTER_SANITIZE_STRING),
+ "name" => filter_input(INPUT_POST, "deviceName", FILTER_SANITIZE_STRING),
+ "manufacturer" => filter_input(INPUT_POST, "deviceManufacturer", FILTER_SANITIZE_STRING),
+ "model" => filter_input(INPUT_POST, "deviceModel", FILTER_SANITIZE_STRING)
+ ],
+ "proxy" => [
+ "endpoint" => filter_input(INPUT_POST, "strdir", FILTER_SANITIZE_STRING)
+ ],
+ "stream" => [
+ "port" => filter_input(INPUT_POST, "sport", FILTER_SANITIZE_STRING),
+ "file" => filter_input(INPUT_POST, "sportf", FILTER_SANITIZE_STRING)
+ ],
+ "socket" => [
+ "port" => filter_input(INPUT_POST, "sckport", FILTER_SANITIZE_STRING)
+ ],
+ "os" => [
+ "name" => filter_input(INPUT_POST, "osName", FILTER_SANITIZE_STRING),
+ "manufacturer" => filter_input(INPUT_POST, "osManufacturer", FILTER_SANITIZE_STRING),
+ "version" => filter_input(INPUT_POST, "osVersion", FILTER_SANITIZE_STRING)
+ ],
+ "protocols" => $protocols,
+ "status" => [
+ "value" => "OFFLINE",
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "keys" => [
+ "public" => $pubKey,
+ "private" => $this->_GeniSys->_helpers->oEncrypt($privKeyHash),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "blockchain" => [
+ "address" => $newBcUser,
+ "password" => $this->_GeniSys->_helpers->oEncrypt($bcPass)
+ ],
+ "mqtt" => [
+ "username" => $this->_GeniSys->_helpers->oEncrypt($mqttUser),
+ "password" => $this->_GeniSys->_helpers->oEncrypt($mqttPass),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "coap" => [
+ "username" => "",
+ "password" => ""
+ ],
+ "amqp" => [
+ "username" => $this->_GeniSys->_helpers->oEncrypt($amqppubKey),
+ "password" => $this->_GeniSys->_helpers->oEncrypt($amqpprvKey),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "batteryLevel" => [
+ "value" => 0.00
+ ],
+ "cpuUsage" => [
+ "value" => 0.00
+ ],
+ "memoryUsage" => [
+ "value" => 0.00
+ ],
+ "hddUsage" => [
+ "value" => 0.00
+ ],
+ "temperature" => [
+ "value" => 0.00
+ ],
+ "ip" => [
+ "value" => $this->_GeniSys->_helpers->oEncrypt($ip),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "mac" => [
+ "value" => $this->_GeniSys->_helpers->oEncrypt($mac),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "bluetooth" => [
+ "address" => $bluetooth ? $this->_GeniSys->_helpers->oEncrypt($bluetooth) : "",
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "ai" => $models,
+ "sensors" => $sensors,
+ "actuators" => $actuators,
+ "dateCreated" => [
+ "type" => "DateTime",
+ "value" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "dateFirstUsed" => [
+ "type" => "DateTime",
+ "value" => ""
+ ],
+ "dateModified" => [
+ "type" => "DateTime",
+ "value" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ]
+ ];
+
+ $response = json_decode($this->contextBrokerRequest("POST", $this->cb["entities_url"] . "?type=Device", $this->createContextHeaders(), json_encode($data)), true);
+
+ if($response["Response"]=="OK"):
+
+ $query = $this->_GeniSys->_secCon->prepare("
+ UPDATE mqttld
+ SET apub = :apub
+ WHERE id = :id
+ ");
+ $query->execute(array(
+ ':apub'=> $response["Entity"]["id"],
+ ':id'=> $did
+ ));
+
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO mqttu (
+ `lid`,
+ `zid`,
+ `did`,
+ `uname`,
+ `pw`
+ ) VALUES (
+ :lid,
+ :zid,
+ :did,
+ :uname,
+ :pw
+ )
+ ");
+ $query->execute([
+ ':lid' => $lid,
+ ':zid' => $zid,
+ ':did' => $did,
+ ':uname' => $mqttUser,
+ ':pw' => $mqttHash
+ ]);
+
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO mqttua (
+ `lid`,
+ `zid`,
+ `did`,
+ `username`,
+ `topic`,
+ `rw`
+ ) VALUES (
+ :lid,
+ :zid,
+ :did,
+ :username,
+ :topic,
+ :rw
+ )
+ ");
+ $query->execute(array(
+ ':lid' => $lid,
+ ':zid' => $zid,
+ ':did' => $did,
+ ':username' => $mqttUser,
+ ':topic' => $location["context"]["Data"]["id"] . "/Devices/" . $zone["context"]["Data"]["id"] . "/" . $pubKey . "/#",
+ ':rw' => 4
+ ));
+
+ $amid = $this->addAmqpUser($amqppubKey, $amqpKeyHash);
+ $this->addAmqpUserVh($amid, "iotJumpWay");
+ $this->addAmqpVhPerm($amid, "iotJumpWay", "exchange", "Core", "read");
+ $this->addAmqpVhPerm($amid, "iotJumpWay", "exchange", "Core", "write");
+ $this->addAmqpVhPerm($amid, "iotJumpWay", "queue", "Life", "read");
+ $this->addAmqpVhPerm($amid, "iotJumpWay", "queue", "Life", "write");
+ $this->addAmqpVhPerm($amid, "iotJumpWay", "queue", "Statuses", "read");
+ $this->addAmqpVhPerm($amid, "iotJumpWay", "queue", "Statuses", "write");
+ $this->addAmqpVhTopic($amid, "iotJumpWay", "topic", "Core", "read", "Life");
+ $this->addAmqpVhTopic($amid, "iotJumpWay", "topic", "Core", "write", "Life");
+ $this->addAmqpVhTopic($amid, "iotJumpWay", "topic", "Core", "read", "Statuses");
+ $this->addAmqpVhTopic($amid, "iotJumpWay", "topic", "Core", "write", "Statuses");
+
+ $query = $this->_GeniSys->_secCon->prepare("
+ INSERT INTO tassai (
+ `pub`
+ ) VALUES (
+ :pub
+ )
+ ");
+ $query->execute([
+ ':pub' => $pubKey
+ ]);
+
+ $hash = "";
+ $msg = "";
+ $actionMsg = "";
+ $balanceMessage = "";
+ $this->contract->at($this->_GeniSys->_helpers->oDecrypt($this->bcc["contract"]))->send("registerDevice", $pubKey, $newBcUser, $lid, $zid, $did, $name, $_SESSION["GeniSysAI"]["Uid"], time(), ["from" => $_SESSION["GeniSysAI"]["BC"]["BCUser"]], function ($err, $resp) use (&$hash, &$msg) {
+ if ($err !== null) {
+ $hash = "FAILED";
+ $msg = $err;
+ return;
+ }
+ $hash = $resp;
+ });
+
+ if($hash == "FAILED"):
+ $actionMsg = " HIAS Blockchain registerDevice failed!\n" . $msg;
+ else:
+ $txid = $this->storeBlockchainTransaction("Register Device", $hash, $did);
+ $this->storeUserHistory("Register Device", $txid, $lid, $zid, $did);
+ $balance = $this->getBlockchainBalance();
+ $actionMsg = " HIAS Blockchain registerDevice OK!\n";
+ $balanceMessage = " You were rewarded for this action! Your balance is now: " . $balance . " HIAS Ether!";
+ endif;
+
+ $this->icontract->at($this->_GeniSys->_helpers->oDecrypt($this->bcc["icontract"]))->send("registerAuthorized", $newBcUser, ["from" => $_SESSION["GeniSysAI"]["BC"]["BCUser"]], function ($err, $resp) use (&$hash, &$msg) {
+ if ($err !== null) {
+ $hash = "FAILED";
+ $msg = $err;
+ return;
+ }
+ $hash = $resp;
+ });
+
+ if($hash == "FAILED"):
+ $actionMsg .= " HIAS Blockchain registerAuthorized failed! " . $msg;
+ else:
+ $txid = $this->storeBlockchainTransaction("iotJumpWay Register Authorized", $hash, $did);
+ $this->storeUserHistory("Register Authorized", $txid, $lid, $zid, $did);
+ $balance = $this->getBlockchainBalance();
+ $actionMsg .= " HIAS Blockchain registerAuthorized OK!\n";
+ $balanceMessage = " You were rewarded for this action! Your balance is now: " . $balance . " HIAS Ether!";
+ endif;
+
+ return [
+ "Response"=> "OK",
+ "Message" => "Device created!" . $actionMsg . $balanceMessage,
+ "LID" => filter_input(INPUT_POST, "lid", FILTER_SANITIZE_NUMBER_INT),
+ "ZID" => filter_input(INPUT_POST, "zid", FILTER_SANITIZE_NUMBER_INT),
+ "DID" => $did,
+ "MU" => $mqttUser,
+ "MP" => $mqttPass,
+ "BU" => $newBcUser,
+ "BP" => $bcPass,
+ "AppID" => $pubKey,
+ "AppKey" => $privKey
+ ];
+ else:
+ return [
+ "Response"=> "FAILED",
+ "Message" => "Device creating failed"
+ ];
+ endif;
+ }
+
+ public function updateDevice()
+ {
+ $did = filter_input(INPUT_GET, "device", FILTER_SANITIZE_NUMBER_INT);
+
+ if(!filter_input(INPUT_POST, "identifier", FILTER_SANITIZE_NUMBER_INT)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Device identifier is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "lid", FILTER_SANITIZE_NUMBER_INT)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Location ID is required"
+ ];
+ endif;
+
+ if(!$this->checkLocation(filter_input(INPUT_POST, "lid", FILTER_SANITIZE_NUMBER_INT))):
+ return [
+ "Response"=> "Failed",
+ "Message" => "iotJumpWay location does not exist"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "zid", FILTER_SANITIZE_NUMBER_INT)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Zone ID is required"
+ ];
+ endif;
+
+ if(!$this->checkZone(filter_input(INPUT_POST, "zid", FILTER_SANITIZE_NUMBER_INT))):
+ return [
+ "Response"=> "Failed",
+ "Message" => "iotJumpWay zone does not exist"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "category", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Category is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "name", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "description", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Description is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "coordinates", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Coordinates entity is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "deviceName", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Hardware device name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "deviceManufacturer", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Hardware device manufacturer is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "deviceModel", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Hardware device model is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osName", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system name is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osManufacturer", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system manufacturer is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osVersion", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system version is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "osVersion", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Operating system version is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "agent", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "IoT Agent is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "ip", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "IP is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "mac", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "MAC is required"
+ ];
+ endif;
+
+ if(!count($_POST["protocols"])):
+ return [
+ "Response"=> "Failed",
+ "Message" => "At least one M2M protocol is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "sport", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Device stream port is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "sportf", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Device stream file is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "strdir", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Device stream directory is required"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "sckport", FILTER_SANITIZE_STRING)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Device socket port is required"
+ ];
+ endif;
+
+ $unlocked = $this->unlockBlockchainAccount();
+
+ if($unlocked == "FAILED"):
+ return [
+ "Response"=> "Failed",
+ "Message" => "Unlocking HIAS Blockhain Account Failed!"
+ ];
+ endif;
+
+ $ip = filter_input(INPUT_POST, "ip", FILTER_SANITIZE_STRING);
+ $mac = filter_input(INPUT_POST, "mac", FILTER_SANITIZE_STRING);
+ $bluetooth = filter_input(INPUT_POST, "bluetooth", FILTER_SANITIZE_STRING);
+ $name = filter_input(INPUT_POST, "name", FILTER_SANITIZE_STRING);
+ $status = filter_input(INPUT_POST, "status", FILTER_SANITIZE_STRING);
+ $coords = explode(",", filter_input(INPUT_POST, "coordinates", FILTER_SANITIZE_STRING));
+
+ $did = filter_input(INPUT_GET, "device", FILTER_SANITIZE_NUMBER_INT);
+ $device = $this->getDevice($did);
+
+ $lid = filter_input(INPUT_POST, 'lid', FILTER_SANITIZE_NUMBER_INT);
+ $location = $this->getLocation($lid);
+
+ $zid = filter_input(INPUT_POST, 'zid', FILTER_SANITIZE_NUMBER_INT);
+ $zone = $this->getZone($zid);
+
+ $protocols = [];
+ foreach($_POST["protocols"] AS $key => $value):
+ $protocols[] = $value;
+ endforeach;
+
+ $models = [];
+ if(isSet($_POST["ai"])):
+ foreach($_POST["ai"] AS $key => $value):
+ $model = $this->getModel($value)["context"]["Data"];
+ $mname = $model["name"]["value"];
+ unset($model["id"]);
+ unset($model["type"]);
+ unset($model["mid"]);
+ unset($model["name"]);
+ unset($model["description"]);
+ unset($model["network"]);
+ unset($model["language"]);
+ unset($model["framework"]);
+ unset($model["toolkit"]);
+ unset($model["dateCreated"]);
+ unset($model["dateModified"]);
+ $models[$mname] = $model;
+ endforeach;
+ endif;
+
+ $sensors = [];
+ if(isSet($_POST["sensors"])):
+ foreach($_POST["sensors"] AS $key => $value):
+ $sensor = $this->getThing($value)["context"]["Data"];
+ unset($sensor["id"]);
+ unset($sensor["type"]);
+ unset($sensor["category"]);
+ unset($sensor["description"]);
+ unset($sensor["thing"]);
+ unset($sensor["properties"]["image"]);
+ unset($sensor["dateCreated"]);
+ unset($sensor["dateModified"]);
+ $sensors[] = $sensor;
+ endforeach;
+ endif;
+
+ $actuators = [];
+ if(isSet($_POST["actuators"])):
+ foreach($_POST["actuators"] AS $key => $value):
+ $actuator = $this->getThing($value)["context"]["Data"];
+ unset($actuator["id"]);
+ unset($actuator["type"]);
+ unset($actuator["category"]);
+ unset($actuator["description"]);
+ unset($actuator["thing"]);
+ unset($actuator["properties"]["image"]);
+ unset($actuator["dateCreated"]);
+ unset($actuator["dateModeified"]);
+ $actuators[] = $actuator;
+ endforeach;
+ endif;
+
+ if($device["context"]["Data"]["lid"]["value"] != $lid):
+ $query = $this->_GeniSys->_secCon->prepare("
+ UPDATE mqttu
+ SET lid = :lid
+ WHERE did = :did
+ ");
+ $query->execute([
+ ':lid' => $lid,
+ ':did' => $did
+ ]);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ $query = $this->_GeniSys->_secCon->prepare("
+ UPDATE mqttua
+ SET lid = :lid
+ WHERE did = :did
+ ");
+ $query->execute([
+ ':lid' => $lid,
+ ':did' => $did
+ ]);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+
+ $query = $this->_GeniSys->_secCon->prepare("
+ UPDATE mqttua
+ SET topic = :topicN
+ WHERE did = :did
+ & topic = :topic
+ ");
+ $query->execute([
+ ':topicN' => $device["context"]["Data"]["lid"]["entity"] . "/ " . $device["context"]["Data"]["zid"]["entity"] . "/Devices/" . $device["context"]["Data"]["id"] . "/#",
+ ':did' => $did,
+ ':topic' => $location["context"]["Data"]["id"] . "/Devices/" . $zone["context"]["Data"]["id"] . "/Devices/" . $device["context"]["Data"]["id"] . "/#"
+ ]);
+ $pdoQuery->closeCursor();
+ $pdoQuery = null;
+ endif;
+
+ $data = [
+ "type" => "Device",
+ "category" => [
+ "value" => [filter_input(INPUT_POST, "category", FILTER_SANITIZE_STRING)]
+ ],
+ "name" => [
+ "value" => $name
+ ],
+ "description" => [
+ "value" => filter_input(INPUT_POST, "description", FILTER_SANITIZE_STRING)
+ ],
+ "lid" => [
+ "value" => $lid,
+ "entity" => $location["context"]["Data"]["id"]
+ ],
+ "zid" => [
+ "value" => $zid,
+ "entity" => $zone["context"]["Data"]["id"]
+ ],
+ "did" => [
+ "value" => $did
+ ],
+ "location" => [
+ "type" => "geo:json",
+ "value" => [
+ "type" => "Point",
+ "coordinates" => [floatval($coords[0]), floatval($coords[1])]
+ ]
+ ],
+ "agent" => [
+ "url" => filter_input(INPUT_POST, "agent", FILTER_SANITIZE_STRING)
+ ],
+ "device" => [
+ "type" => filter_input(INPUT_POST, "type", FILTER_SANITIZE_STRING),
+ "name" => filter_input(INPUT_POST, "deviceName", FILTER_SANITIZE_STRING),
+ "manufacturer" => filter_input(INPUT_POST, "deviceManufacturer", FILTER_SANITIZE_STRING),
+ "model" => filter_input(INPUT_POST, "deviceModel", FILTER_SANITIZE_STRING)
+ ],
+ "proxy" => [
+ "endpoint" => filter_input(INPUT_POST, "strdir", FILTER_SANITIZE_STRING)
+ ],
+ "stream" => [
+ "port" => filter_input(INPUT_POST, "sport", FILTER_SANITIZE_STRING),
+ "file" => filter_input(INPUT_POST, "sportf", FILTER_SANITIZE_STRING)
+ ],
+ "socket" => [
+ "port" => filter_input(INPUT_POST, "sckport", FILTER_SANITIZE_STRING)
+ ],
+ "os" => [
+ "name" => filter_input(INPUT_POST, "osName", FILTER_SANITIZE_STRING),
+ "manufacturer" => filter_input(INPUT_POST, "osManufacturer", FILTER_SANITIZE_STRING),
+ "version" => filter_input(INPUT_POST, "osVersion", FILTER_SANITIZE_STRING)
+ ],
+ "protocols" => $protocols,
+ "status" => [
+ "value" => $status,
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "states" => [
+ "detected",
+ "ok"
+ ],
+ "state" => [
+ "value" => "",
+ "timestamp" => ""
+ ],
+ "ip" => [
+ "value" => $this->_GeniSys->_helpers->oEncrypt($ip),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "mac" => [
+ "value" => $this->_GeniSys->_helpers->oEncrypt($mac),
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "bluetooth" => [
+ "address" => $bluetooth ? $this->_GeniSys->_helpers->oEncrypt($bluetooth) : "",
+ "timestamp" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ],
+ "ai" => $models,
+ "sensors" => $sensors,
+ "actuators" => $actuators,
+ "dateModified" => [
+ "type" => "DateTime",
+ "value" => date('Y-m-d\TH:i:s.Z\Z', time())
+ ]
+ ];
+
+ $response = json_decode($this->contextBrokerRequest("PATCH", $this->cb["entities_url"] . "/" . $device["context"]["Data"]["id"] . "/attrs?type=Device", $this->createContextHeaders(), json_encode($data)), true);
+
+ if($response["Response"]=="OK"):
+
+ $hash = "";
+ $msg = "";
+ $this->contract->at($this->_GeniSys->_helpers->oDecrypt($this->bcc["contract"]))->send("updateDevice", $device["context"]["Data"]["id"], "Device", $lid, $zid, $did, $name, $status, time(), ["from" => $_SESSION["GeniSysAI"]["BC"]["BCUser"]], function ($err, $resp) use (&$hash, &$msg) {
+ if ($err !== null) {
+ $hash = "FAILED";
+ $msg = $err;
+ return;
+ }
+ $hash = $resp;
+ });
+
+ $balance = "";
+ $balanceMessage = "";
+ $actionMsg = "";
+ if($hash == "FAILED"):
+ $actionMsg = " HIAS Blockchain updateDevice failed! " . $msg;
+ else:
+ $txid = $this->storeBlockchainTransaction("Update Device", $hash, $did);
+ $this->storeUserHistory("Updated Device", $txid, $lid, $zid, $did);
+ $balance = $this->getBlockchainBalance();
+ $balanceMessage = " You were rewarded for this action! Your balance is now: " . $balance . " HIAS Ether!";
+ endif;
+
+ $device = $this->getDevice($did);
+
+ return [
+ "Response"=> "OK",
+ "Message" => "Device updated!" . $actionMsg . $balanceMessage,
+ "Schema" => $device["context"]["Data"]
+ ];
+ else:
+ return [
+ "Response"=> "Failed",
+ "Message" => "There was a problem updating this device context data!"
+ ];
+ endif;
+ }
+
+ }
+
+ $TassAI = new TassAI($_GeniSys);
+
+ if(filter_input(INPUT_POST, "update_genisysai", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($TassAI->updateDevice()));
+ endif;
+ if(filter_input(INPUT_POST, "create_genisysai", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($TassAI->createDevice()));
+ endif;
+ if(filter_input(INPUT_POST, "reset_mqtt", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($TassAI->resetMqtt()));
+ endif;
+ if(filter_input(INPUT_POST, "reset_key", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($TassAI->resetDvcKey()));
+ endif;
+ if(filter_input(INPUT_POST, "get_tlife", FILTER_SANITIZE_NUMBER_INT)):
+ die(json_encode($TassAI->getLife()));
+ endif;
diff --git a/Root/var/www/html/AI/TassAI/Create.php b/Root/var/www/html/AI/TassAI/Create.php
new file mode 100644
index 0000000..eda1b1b
--- /dev/null
+++ b/Root/var/www/html/AI/TassAI/Create.php
@@ -0,0 +1,397 @@
+ "AI",
+ "SubPageID" => "TassAI"
+];
+
+include dirname(__FILE__) . '/../../../Classes/Core/init.php';
+include dirname(__FILE__) . '/../../../Classes/Core/GeniSys.php';
+include dirname(__FILE__) . '/../../iotJumpWay/Classes/iotJumpWay.php';
+include dirname(__FILE__) . '/../../AI/TassAI/Classes/TassAI.php';
+include dirname(__FILE__) . '/../../AI/Classes/AI.php';
+
+$_GeniSysAi->checkSession();
+
+$Zones = $iotJumpWay->getZones();
+$Devices = $iotJumpWay->getDevices();
+
+?>
+
+
+
+
+
+
+
+
+
=$_GeniSys->_confs["meta_title"]; ?>
+
" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Create TassAI Security Camera Device
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Root/var/www/html/AI/TassAI/Device.php b/Root/var/www/html/AI/TassAI/Device.php
new file mode 100644
index 0000000..0128280
--- /dev/null
+++ b/Root/var/www/html/AI/TassAI/Device.php
@@ -0,0 +1,938 @@
+ "AI",
+ "SubPageID" => "TassAI"
+];
+
+include dirname(__FILE__) . '/../../../Classes/Core/init.php';
+include dirname(__FILE__) . '/../../../Classes/Core/GeniSys.php';
+include dirname(__FILE__) . '/../../iotJumpWay/Classes/iotJumpWay.php';
+include dirname(__FILE__) . '/../../AI/TassAI/Classes/TassAI.php';
+include dirname(__FILE__) . '/../../AI/Classes/AI.php';
+
+$_GeniSysAi->checkSession();
+
+$Locations = $iotJumpWay->getLocations();
+$Zones = $iotJumpWay->getZones();
+$Devices = $TassAI->getDevices();
+
+$TId = filter_input(INPUT_GET, 'device', FILTER_SANITIZE_NUMBER_INT);
+$Device = $iotJumpWay->getDevice($TId);
+
+list($dev1On, $dev1Off) = $iotJumpWay->getStatusShow($Device["context"]["Data"]["status"]["value"]);
+
+?>
+
+
+
+
+
+
+
+
+
+
=$_GeniSys->_confs["meta_title"]; ?>
+
" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
TassAI Facial Recognition Device #=$TId; ?>
+
+
+
+
+
+
+
+
+
+
Device Schema
+
+
+
+
+
+
+
+
+
+
Device History
+
+
+
+
+
+
+
+
+
+
Device Transactions
+
+
+
+
+
+
+
+
+
+
Device iotJumpWay Statuses
+
+
+
+
+
+
+
+
+
+
+
+ ID
+ Status
+ Time
+
+
+
+
+ retrieveDeviceStatuses($Device["context"]["Data"]["did"]["value"], 5);
+ if($Statuses["Response"] == "OK"):
+ foreach($Statuses["ResponseData"] as $key => $value):
+ ?>
+
+
+ #=$value->_id;?>
+ =$value->Status;?>
+ =$value->Time;?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Device iotJumpWay Life
+
+
+
+
+
+
+
+
+
+
+
+ ID
+ Details
+ Time
+
+
+
+
+ retrieveDeviceLife($Device["context"]["Data"]["did"]["value"], 5);
+ if($Statuses["Response"] == "OK"):
+ foreach($Statuses["ResponseData"] as $key => $value):
+ ?>
+
+
+ #=$value->_id;?>
+
+ CPU : =$value->Data->CPU;?>%
+ Memory : =$value->Data->Memory;?>%
+ Diskspace : =$value->Data->Diskspace;?>%
+ Temperature : =$value->Data->Temperature;?>°C
+ Latitude : =$value->Data->Latitude;?>
+ Longitude : =$value->Data->Longitude;?>
+
+ =$value->Time;?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Device iotJumpWay Sensors
+
+
+
+
+
+
+
+
+
+
+
+ ID
+ Type
+ Sensor
+ Value
+ Message
+ Time
+
+
+
+
+ retrieveDeviceSensors($Device["context"]["Data"]["did"]["value"], 5);
+ if($Statuses["Response"] == "OK"):
+ foreach($Statuses["ResponseData"] as $key => $value):
+ $location = $iotJumpWay->getLocation($value->Location);
+ ?>
+
+ #=$value->_id;?>
+ =$value->Type;?>
+ =$value->Sensor;?>
+
+ Sensor == "Facial API" || $value->Sensor == "Foscam Camera" || $value->Sensor == "USB Camera") && is_array($value->Value)):
+ foreach($value->Value AS $key => $val):
+ echo $val[0] == 0 ? "Identification: Intruder " :"Identification: User #" . $val[0] . " ";
+ echo "Distance: " . $val[1] . " ";
+ echo "Message: " . $val[2] . " ";
+ endforeach;
+ else:
+ echo $value->Value;
+ endif;
+ ?>
+
+
+ =$value->Message;?>
+ =$value->Time;?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Device iotJumpWay Commands
+
+
+
+
+
+
+
+
+
+
+
+ ID
+ Details
+ Status
+ Time
+
+
+
+
+ retrieveDeviceCommands($Device["context"]["Data"]["did"]["value"], 5);
+ if($Statuses["Response"] == "OK"):
+ foreach($Statuses["ResponseData"] as $key => $value):
+ $location = $iotJumpWay->getLocation($value->Location);
+ ?>
+
+
+ #=$value->_id;?>
+ Location: #=$value->Location;?> - =$location["name"]; ?>
+ =$value->Status;?>
+ =$value->Time;?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
">
+
+
+
/=$Device["context"]["Data"]["stream"]["file"]; ?>" style="width: 100%;" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Root/var/www/html/iotJumpWay/Media/Images/Sensors/.htaccess b/Root/var/www/html/AI/TassAI/Live/index.php
similarity index 100%
rename from Root/var/www/html/iotJumpWay/Media/Images/Sensors/.htaccess
rename to Root/var/www/html/AI/TassAI/Live/index.php
diff --git a/Root/var/www/html/AI/TassAI/View.php b/Root/var/www/html/AI/TassAI/View.php
new file mode 100644
index 0000000..271db6f
--- /dev/null
+++ b/Root/var/www/html/AI/TassAI/View.php
@@ -0,0 +1,123 @@
+ "AI",
+ "SubPageID" => "TassAI"
+];
+
+include dirname(__FILE__) . '/../../../Classes/Core/init.php';
+include dirname(__FILE__) . '/../../../Classes/Core/GeniSys.php';
+include dirname(__FILE__) . '/../../iotJumpWay/Classes/iotJumpWay.php';
+include dirname(__FILE__) . '/../../AI/TassAI/Classes/TassAI.php';
+
+$_GeniSysAi->checkSession();
+$Devices = $TassAI->getDevices();
+
+?>
+
+
+
+
+
+
+
+
+
+
=$_GeniSys->_confs["meta_title"]; ?>
+
" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $value):
+ if($value["category"]["value"] != "API" && $value["status"]["value"] == "ONLINE"):
+ ?>
+
+
+
+
+
+
/=$value["stream"]["file"]; ?>" style="width: 100%;" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Root/var/www/html/AI/TassAI/index.php b/Root/var/www/html/AI/TassAI/index.php
new file mode 100644
index 0000000..6b10c72
--- /dev/null
+++ b/Root/var/www/html/AI/TassAI/index.php
@@ -0,0 +1,172 @@
+ "AI",
+ "SubPageID" => "TassAI"
+];
+
+include dirname(__FILE__) . '/../../../Classes/Core/init.php';
+include dirname(__FILE__) . '/../../../Classes/Core/GeniSys.php';
+include dirname(__FILE__) . '/../../iotJumpWay/Classes/iotJumpWay.php';
+include dirname(__FILE__) . '/../../AI/TassAI/Classes/TassAI.php';
+
+$_GeniSysAi->checkSession();
+$Devices = $TassAI->getDevices();
+
+?>
+
+
+
+
+
+
+
+
+
+
=$_GeniSys->_confs["meta_title"]; ?>
+
" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
TassAI Facial Recognition Models
+
+
+
+
+
+
+
TassAI Facial Recognition Models are a range of computer vision models for facial recognition designed to be used on constrained devices making them suitable for IoT networks. These models use a variety of programming languages, frameworks and hardware providing. You can download our TassAI models from the HIAS TassAI repository . Instructions for installation are provided in the tutorials.
+
+
+
+
+
+
+
TassAI Security Camera Devices
+
+
+
+
+
+
+
+
+
+
+
+ ID
+ DETAILS
+ STATUS
+ ACTION
+
+
+
+
+ $value):
+ ?>
+
+
+ #=$value["did"]["value"];?>
+
+ Name: =$value["name"]["value"];?>
+ Zone: #=$value["zid"]["value"];?>
+
+
+ ">
+ =$value["status"]["value"] == "OFFLINE" ? "OFFLINE" : "ONLINE"; ?>
+
+
+ "> Edit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Root/var/www/html/AI/index.php b/Root/var/www/html/AI/index.php
new file mode 100644
index 0000000..becd01b
--- /dev/null
+++ b/Root/var/www/html/AI/index.php
@@ -0,0 +1,171 @@
+ "AI",
+ "SubPageID" => "Models"
+];
+
+include dirname(__FILE__) . '/../../Classes/Core/init.php';
+include dirname(__FILE__) . '/../../Classes/Core/GeniSys.php';
+include dirname(__FILE__) . '/../iotJumpWay/Classes/iotJumpWay.php';
+include dirname(__FILE__) . '/../AI/Classes/AI.php';
+
+$_GeniSysAi->checkSession();
+$Models = $AI->getModels();
+
+?>
+
+
+
+
+
+
+
+
+
+
=$_GeniSys->_confs["meta_title"]; ?>
+
" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
HIAS Artificial Intelligence Models
+
+
+
+
+
+
+
+
+
+
In addition to using Leukemia AI Research AI Models, you can develop your own models and add them to the HIAS network for use in AI devices.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Root/var/www/html/Blockchain/CCreate.php b/Root/var/www/html/Blockchain/CCreate.php
index b21ef3c..8feb2d6 100644
--- a/Root/var/www/html/Blockchain/CCreate.php
+++ b/Root/var/www/html/Blockchain/CCreate.php
@@ -33,7 +33,7 @@
-
+
diff --git a/Root/var/www/html/Blockchain/Classes/Blockchain.js b/Root/var/www/html/Blockchain/Classes/Blockchain.js
index 1c9545a..58c0a88 100644
--- a/Root/var/www/html/Blockchain/Classes/Blockchain.js
+++ b/Root/var/www/html/Blockchain/Classes/Blockchain.js
@@ -229,7 +229,7 @@ var Blockchain = {
});
},
updateConfig: function() {
- $.post(window.location.href, $("#bc_config").serialize(), function(resp) {
+ $.post(window.location.href, $("#blockchain_update").serialize(), function(resp) {
var resp = jQuery.parseJSON(resp);
switch (resp.Response) {
case "OK":
@@ -270,7 +270,6 @@ var Blockchain = {
},
transfer: function() {
$.post(window.location.href, $("#send").serialize(), function(resp) {
- console.log(resp);
var resp = jQuery.parseJSON(resp);
switch (resp.Response) {
case "OK":
diff --git a/Root/var/www/html/Blockchain/Classes/Blockchain.php b/Root/var/www/html/Blockchain/Classes/Blockchain.php
index 2a9975e..c7ee279 100644
--- a/Root/var/www/html/Blockchain/Classes/Blockchain.php
+++ b/Root/var/www/html/Blockchain/Classes/Blockchain.php
@@ -246,30 +246,38 @@ public function updateConfig()
$contract = new Contract($this->web3->provider, $this->bcc["abi"]);
$allowed = $this->checkBlockchainPermissions($contract);
- if(!filter_input(INPUT_POST, "address", FILTER_SANITIZE_STRING)):
+ if(!filter_input(INPUT_POST, "dc", FILTER_SANITIZE_NUMBER_INT)):
return [
"Response"=> "Failed",
- "Message" => "HIAS Blockchain account password is required"
+ "Message" => "You must select the HIAS Smart Contract"
];
endif;
- if(!filter_input(INPUT_POST, "pw", FILTER_SANITIZE_STRING)):
+ if(!filter_input(INPUT_POST, "ic", FILTER_SANITIZE_NUMBER_INT)):
return [
"Response"=> "Failed",
- "Message" => "HIAS Blockchain account address is required"
+ "Message" => "You must select the iotJumpWay Smart Contract"
+ ];
+ endif;
+
+ if(!filter_input(INPUT_POST, "pc", FILTER_SANITIZE_NUMBER_INT)):
+ return [
+ "Response"=> "Failed",
+ "Message" => "You must select the Patients Smart Contract"
];
endif;
$query = $this->_GeniSys->_secCon->prepare("
UPDATE blockchain
- SET bcaddress = :address,
- pw = :pw
+ SET dc = :dc,
+ ic = :ic,
+ pc = :pc
");
$query->execute([
- ':address' => $this->_GeniSys->_helpers->oEncrypt(filter_input(INPUT_POST, "address", FILTER_SANITIZE_STRING)),
- ':pw' => $this->_GeniSys->_helpers->oEncrypt(filter_input(INPUT_POST, "pw", FILTER_SANITIZE_STRING))
+ ':dc' => filter_input(INPUT_POST, "dc", FILTER_SANITIZE_NUMBER_INT),
+ ':ic' => filter_input(INPUT_POST, "ic", FILTER_SANITIZE_NUMBER_INT),
+ ':pc' => filter_input(INPUT_POST, "pc", FILTER_SANITIZE_NUMBER_INT)
]);
- $id = $this->_GeniSys->_secCon->lastInsertId();
$this->storeUserHistory("Update Blockchain Settings");
diff --git a/Root/var/www/html/Blockchain/Contract.php b/Root/var/www/html/Blockchain/Contract.php
index 6bc8e7a..4641583 100644
--- a/Root/var/www/html/Blockchain/Contract.php
+++ b/Root/var/www/html/Blockchain/Contract.php
@@ -34,7 +34,7 @@
-
+
diff --git a/Root/var/www/html/Blockchain/Contracts.php b/Root/var/www/html/Blockchain/Contracts.php
index 584e049..2495a8a 100644
--- a/Root/var/www/html/Blockchain/Contracts.php
+++ b/Root/var/www/html/Blockchain/Contracts.php
@@ -33,7 +33,7 @@
-
+
@@ -83,6 +83,32 @@
HIAS Blockchain Smart Contracts
+
+
+
+
+
+
+
@@ -150,7 +176,7 @@
-
+
-