diff --git a/README.md b/README.md index ecbb72c..fa767fc 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,21 @@ # Asociación de Investigacion en Inteligencia Artificial Para la Leucemia Peter Moss -# HIAS - Hospital Intelligent Automation Server -## HIASCDI - HIAS Contextual Data Interface +# HIASCDI - HIAS Contextual Data Interface ![HIAS - Hospital Intelligent Automation Server](assets/images/project-banner.jpg) -[![CURRENT RELEASE](https://img.shields.io/badge/CURRENT%20RELEASE-0.1.0-blue.svg)](https://github.com/AIIAL/HIASCDI/tree/0.1.0) -[![UPCOMING RELEASE](https://img.shields.io/badge/CURRENT%20DEV%20BRANCH-1.0.0-blue.svg)](https://github.com/AIIAL/HIASCDI/tree/1.0.0) [![LICENSE](https://img.shields.io/badge/LICENSE-MIT-blue.svg)](LICENSE) ![SemVer](https://img.shields.io/badge/semver-2.0.0-blue) +[![CURRENT RELEASE](https://img.shields.io/badge/CURRENT%20RELEASE-1.0.0-blue.svg)](https://github.com/AIIAL/HIASCDI/tree/1.0.0) +[![UPCOMING RELEASE](https://img.shields.io/badge/CURRENT%20DEV%20BRANCH-2.0.0-blue.svg)](https://github.com/AIIAL/HIASCDI/tree/2.0.0) ![SemVer](https://img.shields.io/badge/semver-2.0.0-blue) [![Contributions Welcome!](https://img.shields.io/badge/Contributions-Welcome-lightgrey.svg)](CONTRIBUTING.md) [![Issues](https://img.shields.io/badge/Issues-Welcome-lightgrey.svg)](issues) + +[![Documentation Status](https://readthedocs.org/projects/hiascdi/badge/?version=latest)](https://hiascdi.readthedocs.io/en/latest/?badge=latest) +[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/5002/badge)](https://bestpractices.coreinfrastructure.org/projects/5002) [![PEP8](https://img.shields.io/badge/code%20style-pep8-orange.svg)](https://www.python.org/dev/peps/pep-0008/) ![Compliance Tests](https://img.shields.io/badge/Compliance%20Tests-TODO-red) ![Unit Tests](https://img.shields.io/badge/Unit%20Tests-TODO-red) ![Functional Tests](https://img.shields.io/badge/Functional%20Tests-TODO-red) -[![Documentation Status](https://readthedocs.org/projects/hiascdi/badge/?version=latest)](https://hiascdi.readthedocs.io/en/latest/?badge=latest) -[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/5002/badge)](https://bestpractices.coreinfrastructure.org/projects/5002) [![PEP8](https://img.shields.io/badge/code%20style-pep8-orange.svg)](https://www.python.org/dev/peps/pep-0008/) [![PEP8](https://img.shields.io/badge/code%20style-pep8-orange.svg)](https://www.python.org/dev/peps/pep-0008/) +[![LICENSE](https://img.shields.io/badge/LICENSE-MIT-blue.svg)](LICENSE) + -[![Contributions Welcome!](https://img.shields.io/badge/Contributions-Welcome-lightgrey.svg)](CONTRIBUTING.md) [![Issues](https://img.shields.io/badge/Issues-Welcome-lightgrey.svg)](issues)   diff --git a/assets/images/fiware.jpg b/assets/images/fiware.jpg index 45deff4..8ed1321 100644 Binary files a/assets/images/fiware.jpg and b/assets/images/fiware.jpg differ diff --git a/configuration/config.json b/configuration/config.json index 0cfb394..df54b4e 100644 --- a/configuration/config.json +++ b/configuration/config.json @@ -1,9 +1,4 @@ { - "program": "HIASCDI", - "version": "v1", - "address": "hiascdi/v1", - "host": "", - "port": 3524, "acceptTypes": [ "application/json", "text/plain" diff --git a/configuration/credentials.json b/configuration/credentials.json index 9e26dfe..d71074f 100644 --- a/configuration/credentials.json +++ b/configuration/credentials.json @@ -1 +1 @@ -{} \ No newline at end of file +{ "iotJumpWay": { "host": "", "port": 0, "location": "", "zone": "", "entity": "", "name": "", "un": "", "up": "", "ipinfo": "" }, "server": { "host": "", "ip": "", "port": 0 }, "hiascdi": { "name": "", "version": "v1", "endpoint": "hiascdi/v1" }, "mongodb": { "host": "localhost", "db": "", "un": "", "up": "" } } \ No newline at end of file diff --git a/docs/installation/ubuntu.md b/docs/installation/ubuntu.md index 7236331..a390999 100644 --- a/docs/installation/ubuntu.md +++ b/docs/installation/ubuntu.md @@ -12,15 +12,7 @@ For this project you will need to ensure you have the following prerequisites in ## HIAS Core -**HIASCDI** is a core component of the [HIAS - Hospital Intelligent Automation Server](https://github.com/AIIAL/HIAS-Core). Before beginning this tutorial you should complete the HIAS installation guide and have your HIAS server online. The HIAS Core installation installs the core components of the HIAS server: [HIASBCH](https://github.com/AIIAL/HIASBCH), [HIASHDI](https://github.com/AIIAL/HIASHDI) and [HIASCDI](https://github.com/AIIAL/HIASCDI). - -## HIAS IoT Agent - -You will need a [HIAS MQTT IoT Agent](https://github.com/AIIAL/HIAS-MQTT-IoT-Agent) installed on your HIAS Network. IoT Agents receive data sent from HIAS Network devices and applications and store the data in HIASCDI and HIASHDI. - -## HIASBCH Blockchain Agent - -You will need a [HIASBCH MQTT Blockchain Agent](https://github.com/AIIAL/HIASBCH-MQTT-Blockchain-Agent) installed on your HIAS Network. Blockchain Agents receive data from the IoT Agents and store immutable hashes of the data they receive. Please note, there is currently no Blockchain Agent for the AMQP protocol. +**HIASCDI** is a core component of the [HIAS - Hospital Intelligent Automation Server](https://github.com/AIIAL/HIAS-Core). Before beginning this tutorial you should complete the HIAS installation guide and have your HIAS server online.   diff --git a/hiascdi.py b/hiascdi.py index 350452c..9f562b8 100644 --- a/hiascdi.py +++ b/hiascdi.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 """ HIASCDI NGSIV2 Context Broker. The HIASCDI Context Broker handles contextual data for all HIAS @@ -42,24 +42,19 @@ import threading import urllib -import os.path -sys.path.append( - os.path.abspath(os.path.join(__file__, "..", "..", ".."))) - from bson import json_util, ObjectId from flask import Flask, request, Response from threading import Thread +from modules.helpers import helpers +from modules.broker import broker +from modules.entities import entities from modules.mongodb import mongodb from modules.mqtt import mqtt +from modules.types import types +from modules.subscriptions import subscriptions -from components.hiascdi.modules.helpers import helpers -from components.hiascdi.modules.broker import broker -from components.hiascdi.modules.entities import entities -from components.hiascdi.modules.types import types -from components.hiascdi.modules.subscriptions import subscriptions - -class HIASCDI(): +class hiascdi(): """ HIASCDI NGSIV2 Context Broker. The HIASCDI Context Broker handles contextual data for all HIAS @@ -72,9 +67,10 @@ def __init__(self): self.helpers = helpers("HIASCDI") self.confs = self.helpers.confs + self.credentials = self.helpers.credentials - self.component = self.confs["program"] - self.version = self.confs["version"] + self.component = self.credentials["hiascdi"]["name"] + self.version = self.credentials["hiascdi"]["version"] self.err406 = self.confs["errorMessages"]["406"] @@ -84,7 +80,7 @@ def __init__(self): def mongoDbConnection(self): """ Initiates the mongodb connection class. """ - self.mongodb = mongodb(self.helpers, True) + self.mongodb = mongodb(self.helpers) self.mongodb.start() def hiascdiConnection(self): @@ -96,14 +92,14 @@ def iotConnection(self): """ Initiates the iotJumpWay connection. """ self.mqtt = mqtt(self.helpers, "HIASCDI", { - "host": self.helpers.credentials["iotJumpWay"]["host"], - "port": self.helpers.credentials["iotJumpWay"]["mqtt"]["port"], - "location": self.helpers.credentials["iotJumpWay"]["location"], - "zone": self.helpers.credentials["iotJumpWay"]["zone"], - "entity": self.helpers.credentials["iotJumpWay"]["mqtt"]["entity"], - "name": self.helpers.credentials["iotJumpWay"]["mqtt"]["name"], - "un": self.helpers.credentials["iotJumpWay"]["mqtt"]["un"], - "up": self.helpers.credentials["iotJumpWay"]["mqtt"]["up"] + "host": self.credentials["iotJumpWay"]["host"], + "port": self.credentials["iotJumpWay"]["port"], + "location": self.credentials["iotJumpWay"]["location"], + "zone": self.credentials["iotJumpWay"]["zone"], + "entity": self.credentials["iotJumpWay"]["entity"], + "name": self.credentials["iotJumpWay"]["name"], + "un": self.credentials["iotJumpWay"]["un"], + "up": self.credentials["iotJumpWay"]["up"] }) self.mqtt.configure() self.mqtt.start() @@ -173,7 +169,7 @@ def life(self): hdd = psutil.disk_usage('/').percent tmp = psutil.sensors_temperatures()['coretemp'][0].current r = requests.get('http://ipinfo.io/json?token=' + - self.helpers.credentials["iotJumpWay"]["ipinfo"]) + self.credentials["iotJumpWay"]["ipinfo"]) data = r.json() location = data["loc"].split(',') @@ -195,60 +191,60 @@ def signal_handler(self, signal, frame): sys.exit(1) -HIASCDI = HIASCDI() -app = Flask(HIASCDI.component) +hiascdi = hiascdi() +app = Flask(hiascdi.component) @app.route('/', methods=['GET']) def about(): """ Responds to GET requests sent to the /v1/ API endpoint. """ - accepted, content_type = HIASCDI.processHeaders(request) + accepted, content_type = hiascdi.processHeaders(request) if accepted is False: - return HIASCDI.respond(406, HIASCDI.confs["errorMessages"][str(406)], "application/json") + return hiascdi.respond(406, hiascdi.confs["errorMessages"][str(406)], "application/json") if content_type is False: - return HIASCDI.respond(415, HIASCDI.confs["errorMessages"][str(415)], "application/json") + return hiascdi.respond(415, hiascdi.confs["errorMessages"][str(415)], "application/json") - return HIASCDI.respond(200, json.dumps(json.loads(json_util.dumps(HIASCDI.getBroker())), indent=4), accepted) + return hiascdi.respond(200, json.dumps(json.loads(json_util.dumps(hiascdi.getBroker())), indent=4), accepted) @app.route('/entities', methods=['POST']) def entitiesPost(): """ Responds to POST requests sent to the /v1/entities API endpoint. """ - accepted, content_type = HIASCDI.processHeaders(request) + accepted, content_type = hiascdi.processHeaders(request) - query = HIASCDI.checkBody(request) + query = hiascdi.checkBody(request) if query is False: - return HIASCDI.respond(400, HIASCDI.helpers.confs["errorMessages"]["400p"], accepted) + return hiascdi.respond(400, hiascdi.confs["errorMessages"]["400p"], accepted) if query["id"] is None: - return HIASCDI.respond(400, HIASCDI.helpers.confs["errorMessages"]["400b"], accepted) + return hiascdi.respond(400, hiascdi.confs["errorMessages"]["400b"], accepted) - return HIASCDI.entities.createEntity(query, accepted) + return hiascdi.entities.createEntity(query, accepted) @app.route('/entities', methods=['GET']) def entitiesGet(): """ Responds to GET requests sent to the /v1/entities API endpoint. """ - accepted, content_type = HIASCDI.processHeaders(request) + accepted, content_type = hiascdi.processHeaders(request) if accepted is False: - return HIASCDI.respond(406, HIASCDI.confs["errorMessages"][str(406)], "application/json") + return hiascdi.respond(406, hiascdi.confs["errorMessages"][str(406)], "application/json") if content_type is False: - return HIASCDI.respond(415, HIASCDI.confs["errorMessages"][str(415)], "application/json") + return hiascdi.respond(415, hiascdi.confs["errorMessages"][str(415)], "application/json") - return HIASCDI.entities.getEntities(request.args, accepted) + return hiascdi.entities.getEntities(request.args, accepted) @app.route('/entities/<_id>', methods=['GET']) def entityGet(_id): """ Responds to GET requests sent to the /v1/entities/<_id> API endpoint. """ - accepted, content_type = HIASCDI.processHeaders(request) + accepted, content_type = hiascdi.processHeaders(request) if accepted is False: - return HIASCDI.respond(406, HIASCDI.confs["errorMessages"][str(406)], "application/json") + return hiascdi.respond(406, hiascdi.confs["errorMessages"][str(406)], "application/json") if content_type is False: - return HIASCDI.respond(415, HIASCDI.confs["errorMessages"][str(415)], "application/json") + return hiascdi.respond(415, hiascdi.confs["errorMessages"][str(415)], "application/json") if _id is None: - return HIASCDI.respond(400, HIASCDI.helpers.confs["errorMessages"]["400b"], accepted) + return hiascdi.respond(400, hiascdi.confs["errorMessages"]["400b"], accepted) if request.args.get('type') is None: typeof = None @@ -270,20 +266,20 @@ def entityGet(_id): else: metadata = request.args.get('metadata') - return HIASCDI.entities.getEntity(typeof, _id, attrs, options, metadata, False, accepted) + return hiascdi.entities.getEntity(typeof, _id, attrs, options, metadata, False, accepted) @app.route('/entities/<_id>/attrs', methods=['GET']) def entityAttrsGet(_id): """ Responds to GET requests sent to the /v1/entities/<_id>/attrs API endpoint. """ - accepted, content_type = HIASCDI.processHeaders(request) + accepted, content_type = hiascdi.processHeaders(request) if accepted is False: - return HIASCDI.respond(406, HIASCDI.confs["errorMessages"][str(406)], "application/json") + return hiascdi.respond(406, hiascdi.confs["errorMessages"][str(406)], "application/json") if content_type is False: - return HIASCDI.respond(415, HIASCDI.confs["errorMessages"][str(415)], "application/json") + return hiascdi.respond(415, hiascdi.confs["errorMessages"][str(415)], "application/json") if _id is None: - return HIASCDI.respond(400, HIASCDI.helpers.confs["errorMessages"]["400b"], accepted) + return hiascdi.respond(400, hiascdi.confs["errorMessages"]["400b"], accepted) if request.args.get('type') is None: typeof = None @@ -305,24 +301,24 @@ def entityAttrsGet(_id): else: metadata = request.args.get('metadata') - return HIASCDI.entities.getEntity(typeof, _id, attrs, options, metadata, True, accepted) + return hiascdi.entities.getEntity(typeof, _id, attrs, options, metadata, True, accepted) @app.route('/entities/<_id>/attrs', methods=['POST']) def entityPost(_id): """ Responds to POST requests sent to the /v1/entities/<_id>/attrs API endpoint. """ - accepted, content_type = HIASCDI.processHeaders(request) + accepted, content_type = hiascdi.processHeaders(request) if accepted is False: - return HIASCDI.respond(406, HIASCDI.confs["errorMessages"][str(406)], "application/json") + return hiascdi.respond(406, hiascdi.confs["errorMessages"][str(406)], "application/json") if content_type is False: - return HIASCDI.respond(415, HIASCDI.confs["errorMessages"][str(415)], "application/json") + return hiascdi.respond(415, hiascdi.confs["errorMessages"][str(415)], "application/json") if _id is None: - return HIASCDI.respond(400, HIASCDI.helpers.confs["errorMessages"]["400b"], accepted) + return hiascdi.respond(400, hiascdi.confs["errorMessages"]["400b"], accepted) - query = HIASCDI.checkBody(request) + query = hiascdi.checkBody(request) if query is False: - return HIASCDI.respond(400, HIASCDI.helpers.confs["errorMessages"]["400p"], accepted) + return hiascdi.respond(400, hiascdi.confs["errorMessages"]["400p"], accepted) if request.args.get('type') is None: typeof = None @@ -334,25 +330,25 @@ def entityPost(_id): else: options = request.args.get('options') - return HIASCDI.entities.updateEntityPost(_id, typeof, query, options, accepted) + return hiascdi.entities.updateEntityPost(_id, typeof, query, options, accepted) @app.route('/entities/<_id>/attrs', methods=['PATCH']) def entityPatch(_id): """ Responds to PATCH requests sent to the /v1/entities/<_id>/attrs API endpoint. """ - accepted, content_type = HIASCDI.processHeaders(request) + accepted, content_type = hiascdi.processHeaders(request) if accepted is False: - return HIASCDI.respond(406, HIASCDI.confs["errorMessages"][str(406)], "application/json") + return hiascdi.respond(406, hiascdi.confs["errorMessages"][str(406)], "application/json") if content_type is False: - return HIASCDI.respond(415, HIASCDI.confs["errorMessages"][str(415)], "application/json") + return hiascdi.respond(415, hiascdi.confs["errorMessages"][str(415)], "application/json") if _id is None: - return HIASCDI.respond(400, HIASCDI.helpers.confs["errorMessages"]["400b"], accepted) + return hiascdi.respond(400, hiascdi.confs["errorMessages"]["400b"], accepted) - query = HIASCDI.checkBody(request) + query = hiascdi.checkBody(request) print(query) if query is False: - return HIASCDI.respond(400, HIASCDI.helpers.confs["errorMessages"]["400p"], accepted) + return hiascdi.respond(400, hiascdi.confs["errorMessages"]["400p"], accepted) if request.args.get('type') is None: typeof = None @@ -365,26 +361,26 @@ def entityPatch(_id): options = request.args.get('options') if request.args.get('type') is None: - return HIASCDI.respond(400, HIASCDI.helpers.confs["errorMessages"]["400b"], accepted) + return hiascdi.respond(400, hiascdi.confs["errorMessages"]["400b"], accepted) - return HIASCDI.entities.updateEntityPatch(_id, typeof, query, options, accepted) + return hiascdi.entities.updateEntityPatch(_id, typeof, query, options, accepted) @app.route('/entities/<_id>/attrs', methods=['PUT']) def entityPut(_id): """ Responds to PUT requests sent to the /v1/entities/<_id>/attrs API endpoint. """ - accepted, content_type = HIASCDI.processHeaders(request) + accepted, content_type = hiascdi.processHeaders(request) if accepted is False: - return HIASCDI.respond(406, HIASCDI.confs["errorMessages"][str(406)], "application/json") + return hiascdi.respond(406, hiascdi.confs["errorMessages"][str(406)], "application/json") if content_type is False: - return HIASCDI.respond(415, HIASCDI.confs["errorMessages"][str(415)], "application/json") + return hiascdi.respond(415, hiascdi.confs["errorMessages"][str(415)], "application/json") if _id is None: - return HIASCDI.respond(400, HIASCDI.helpers.confs["errorMessages"]["400b"], accepted) + return hiascdi.respond(400, hiascdi.confs["errorMessages"]["400b"], accepted) - query = HIASCDI.checkBody(request) + query = hiascdi.checkBody(request) if query is False: - return HIASCDI.respond(400, HIASCDI.helpers.confs["errorMessages"]["400p"], accepted) + return hiascdi.respond(400, hiascdi.confs["errorMessages"]["400p"], accepted) if request.args.get('type') is None: typeof = None @@ -396,38 +392,38 @@ def entityPut(_id): else: options = request.args.get('options') - return HIASCDI.entities.updateEntityPut(_id, typeof, query, options, accepted) + return hiascdi.entities.updateEntityPut(_id, typeof, query, options, accepted) @app.route('/entities/<_id>', methods=['DELETE']) def entityDelete(_id): """ Responds to DELETE requests sent to the /v1/entities/<_id> API endpoint. """ - accepted, content_type = HIASCDI.processHeaders(request) + accepted, content_type = hiascdi.processHeaders(request) if accepted is False: - return HIASCDI.respond(406, HIASCDI.confs["errorMessages"][str(406)], "application/json") + return hiascdi.respond(406, hiascdi.confs["errorMessages"][str(406)], "application/json") if content_type is False: - return HIASCDI.respond(415, HIASCDI.confs["errorMessages"][str(415)], "application/json") + return hiascdi.respond(415, hiascdi.confs["errorMessages"][str(415)], "application/json") if _id is None: - return HIASCDI.respond(400, HIASCDI.helpers.confs["errorMessages"]["400b"], accepted) + return hiascdi.respond(400, hiascdi.confs["errorMessages"]["400b"], accepted) - return HIASCDI.entities.deleteEntity(request.args.get('type'), _id, accepted) + return hiascdi.entities.deleteEntity(request.args.get('type'), _id, accepted) @app.route('/entities/<_id>/attrs/<_attr>', methods=['GET']) def entityAttrsGetAttr(_id, _attr): """ Responds to GET requests sent to the /v1/entities/<_id>/attrs/<_attr> API endpoint. """ - accepted, content_type = HIASCDI.processHeaders(request) + accepted, content_type = hiascdi.processHeaders(request) if accepted is False: - return HIASCDI.respond(406, HIASCDI.confs["errorMessages"][str(406)], "application/json") + return hiascdi.respond(406, hiascdi.confs["errorMessages"][str(406)], "application/json") if content_type is False: - return HIASCDI.respond(415, HIASCDI.confs["errorMessages"][str(415)], "application/json") + return hiascdi.respond(415, hiascdi.confs["errorMessages"][str(415)], "application/json") if _id is None: - return HIASCDI.respond(400, HIASCDI.helpers.confs["errorMessages"]["400b"], accepted) + return hiascdi.respond(400, hiascdi.confs["errorMessages"]["400b"], accepted) if _attr is None: - return HIASCDI.respond(400, HIASCDI.helpers.confs["errorMessages"]["400b"], accepted) + return hiascdi.respond(400, hiascdi.confs["errorMessages"]["400b"], accepted) if request.args.get('type') is None: typeof = None @@ -444,259 +440,259 @@ def entityAttrsGetAttr(_id, _attr): else: metadata = request.args.get('metadata') - return HIASCDI.entities.getEntityAttribute(typeof, _id, _attr, metadata, False, accepted) + return hiascdi.entities.getEntityAttribute(typeof, _id, _attr, metadata, False, accepted) @app.route('/entities/<_id>/attrs/<_attr>', methods=['PUT']) def entityAttrPut(_id, _attr): """ Responds to PUT requests sent to the /v1/entities/<_id>/attrs/<_attr> API endpoint. """ - accepted, content_type = HIASCDI.processHeaders(request) + accepted, content_type = hiascdi.processHeaders(request) if accepted is False: - return HIASCDI.respond(406, HIASCDI.confs["errorMessages"][str(406)], "application/json") + return hiascdi.respond(406, hiascdi.confs["errorMessages"][str(406)], "application/json") if content_type is False: - return HIASCDI.respond(415, HIASCDI.confs["errorMessages"][str(415)], "application/json") + return hiascdi.respond(415, hiascdi.confs["errorMessages"][str(415)], "application/json") if _id is None: - return HIASCDI.respond(400, HIASCDI.helpers.confs["errorMessages"]["400b"], accepted) + return hiascdi.respond(400, hiascdi.confs["errorMessages"]["400b"], accepted) if _attr is None: - return HIASCDI.respond(400, HIASCDI.helpers.confs["errorMessages"]["400b"], accepted) + return hiascdi.respond(400, hiascdi.confs["errorMessages"]["400b"], accepted) - query = HIASCDI.checkBody(request) + query = hiascdi.checkBody(request) if query is False: - return HIASCDI.respond(400, HIASCDI.helpers.confs["errorMessages"]["400p"], accepted) + return hiascdi.respond(400, hiascdi.confs["errorMessages"]["400p"], accepted) if request.args.get('type') is None: typeof = None else: typeof = request.args.get('type') - return HIASCDI.entities.updateEntityAttrPut(_id, _attr, typeof, query, accepted) + return hiascdi.entities.updateEntityAttrPut(_id, _attr, typeof, query, accepted) @app.route('/entities/<_id>/attrs/<_attr>', methods=['DELETE']) def entityAttrDelete(_id,_attr): """ Responds to DELETE requests sent to the /v1/entities/<_id>/attrs/<_attr> API endpoint. """ - accepted, content_type = HIASCDI.processHeaders(request) + accepted, content_type = hiascdi.processHeaders(request) if accepted is False: - return HIASCDI.respond(406, HIASCDI.confs["errorMessages"][str(406)], "application/json") + return hiascdi.respond(406, hiascdi.confs["errorMessages"][str(406)], "application/json") if content_type is False: - return HIASCDI.respond(415, HIASCDI.confs["errorMessages"][str(415)], "application/json") + return hiascdi.respond(415, hiascdi.confs["errorMessages"][str(415)], "application/json") if _id is None: - return HIASCDI.respond(400, HIASCDI.helpers.confs["errorMessages"]["400b"], accepted) + return hiascdi.respond(400, hiascdi.confs["errorMessages"]["400b"], accepted) if _attr is None: - return HIASCDI.respond(400, HIASCDI.helpers.confs["errorMessages"]["400b"], accepted) + return hiascdi.respond(400, hiascdi.confs["errorMessages"]["400b"], accepted) if request.args.get('type') is None: typeof = None else: typeof = request.args.get('type') - return HIASCDI.entities.deleteEntityAttribute(_id, _attr, typeof, accepted) + return hiascdi.entities.deleteEntityAttribute(_id, _attr, typeof, accepted) @app.route('/entities/<_id>/attrs/<_attr>/value', methods=['GET']) def entityAttrsGetAttrValue(_id, _attr): """ Responds to GET requests sent to the /v1/entities/<_id>/attrs/<_attr>/value API endpoint. """ - accepted, content_type = HIASCDI.processHeaders(request) + accepted, content_type = hiascdi.processHeaders(request) if accepted is False: - return HIASCDI.respond(406, HIASCDI.confs["errorMessages"][str(406)], "application/json") + return hiascdi.respond(406, hiascdi.confs["errorMessages"][str(406)], "application/json") if content_type is False: - return HIASCDI.respond(415, HIASCDI.confs["errorMessages"][str(415)], "application/json") + return hiascdi.respond(415, hiascdi.confs["errorMessages"][str(415)], "application/json") if _id is None: - return HIASCDI.respond(400, HIASCDI.helpers.confs["errorMessages"]["400b"], accepted) + return hiascdi.respond(400, hiascdi.confs["errorMessages"]["400b"], accepted) if _attr is None: - return HIASCDI.respond(400, HIASCDI.helpers.confs["errorMessages"]["400b"], accepted) + return hiascdi.respond(400, hiascdi.confs["errorMessages"]["400b"], accepted) if request.args.get('type') is None: typeof = None else: typeof = request.args.get('type') - return HIASCDI.entities.getEntityAttribute(typeof, _id, _attr, None, True, accepted) + return hiascdi.entities.getEntityAttribute(typeof, _id, _attr, None, True, accepted) @app.route('/entities/<_id>/attrs/<_attr>/value', methods=['PUT']) def entityAttrsPutAttrValue(_id, _attr): """ Responds to PUT requests sent to the /v1/entities/<_id>/attrs/<_attr>/value API endpoint. """ - accepted, content_type = HIASCDI.processHeaders(request) + accepted, content_type = hiascdi.processHeaders(request) if accepted is False: - return HIASCDI.respond(406, HIASCDI.confs["errorMessages"][str(406)], "application/json") + return hiascdi.respond(406, hiascdi.confs["errorMessages"][str(406)], "application/json") if content_type is False: - return HIASCDI.respond(415, HIASCDI.confs["errorMessages"][str(415)], "application/json") + return hiascdi.respond(415, hiascdi.confs["errorMessages"][str(415)], "application/json") if _id is None: - return HIASCDI.respond(400, HIASCDI.helpers.confs["errorMessages"]["400b"], accepted) + return hiascdi.respond(400, hiascdi.confs["errorMessages"]["400b"], accepted) if _attr is None: - return HIASCDI.respond(400, HIASCDI.helpers.confs["errorMessages"]["400b"], accepted) + return hiascdi.respond(400, hiascdi.confs["errorMessages"]["400b"], accepted) - query = HIASCDI.checkBody(request, True) + query = hiascdi.checkBody(request, True) if query is False: - return HIASCDI.respond(400, HIASCDI.helpers.confs["errorMessages"]["400p"], accepted) + return hiascdi.respond(400, hiascdi.confs["errorMessages"]["400p"], accepted) if request.args.get('type') is None: typeof = None else: typeof = request.args.get('type') - return HIASCDI.entities.updateEntityAttrPut(_id, _attr, typeof, query, True, accepted, content_type) + return hiascdi.entities.updateEntityAttrPut(_id, _attr, typeof, query, True, accepted, content_type) @app.route('/types', methods=['GET']) def typesGet(): """ Responds to GET requests sent to the /v1/types API endpoint. """ - accepted, content_type = HIASCDI.processHeaders(request) + accepted, content_type = hiascdi.processHeaders(request) if accepted is False: - return HIASCDI.respond(406, HIASCDI.confs["errorMessages"][str(406)], "application/json") + return hiascdi.respond(406, hiascdi.confs["errorMessages"][str(406)], "application/json") if content_type is False: - return HIASCDI.respond(415, HIASCDI.confs["errorMessages"][str(415)], "application/json") + return hiascdi.respond(415, hiascdi.confs["errorMessages"][str(415)], "application/json") - return HIASCDI.types.getTypes(request.args, accepted) + return hiascdi.types.getTypes(request.args, accepted) @app.route('/types', methods=['POST']) def typesPost(): """ Responds to POST requests sent to the /v1/types API endpoint. """ - accepted, content_type = HIASCDI.processHeaders(request) + accepted, content_type = hiascdi.processHeaders(request) if accepted is False: - return HIASCDI.respond(406, HIASCDI.confs["errorMessages"][str(406)], "application/json") + return hiascdi.respond(406, hiascdi.confs["errorMessages"][str(406)], "application/json") if content_type is False: - return HIASCDI.respond(415, HIASCDI.confs["errorMessages"][str(415)], "application/json") + return hiascdi.respond(415, hiascdi.confs["errorMessages"][str(415)], "application/json") - query = HIASCDI.checkBody(request) + query = hiascdi.checkBody(request) if query is False: - return HIASCDI.respond(400, HIASCDI.helpers.confs["errorMessages"]["400p"], accepted) + return hiascdi.respond(400, hiascdi.confs["errorMessages"]["400p"], accepted) - return HIASCDI.types.createType(query, accepted) + return hiascdi.types.createType(query, accepted) @app.route('/types/<_type>', methods=['PATCH']) def typesPatch(_type): """ Responds to PATCH requests sent to the /v1/types/<_types> API endpoint. """ - accepted, content_type = HIASCDI.processHeaders(request) + accepted, content_type = hiascdi.processHeaders(request) if accepted is False: - return HIASCDI.respond(406, HIASCDI.confs["errorMessages"][str(406)], "application/json") + return hiascdi.respond(406, hiascdi.confs["errorMessages"][str(406)], "application/json") if content_type is False: - return HIASCDI.respond(415, HIASCDI.confs["errorMessages"][str(415)], "application/json") + return hiascdi.respond(415, hiascdi.confs["errorMessages"][str(415)], "application/json") - query = HIASCDI.checkBody(request) + query = hiascdi.checkBody(request) if query is False: - return HIASCDI.respond(400, HIASCDI.helpers.confs["errorMessages"]["400p"], accepted) + return hiascdi.respond(400, hiascdi.confs["errorMessages"]["400p"], accepted) - return HIASCDI.types.updateTypePatch(_type, query, accepted) + return hiascdi.types.updateTypePatch(_type, query, accepted) @app.route('/types/<_type>', methods=['GET']) def typeGet(_type): """ Responds to GET requests sent to the /v1/types/<_id> API endpoint. """ - accepted, content_type = HIASCDI.processHeaders(request) + accepted, content_type = hiascdi.processHeaders(request) if accepted is False: - return HIASCDI.respond(406, HIASCDI.confs["errorMessages"][str(406)], "application/json") + return hiascdi.respond(406, hiascdi.confs["errorMessages"][str(406)], "application/json") if content_type is False: - return HIASCDI.respond(415, HIASCDI.confs["errorMessages"][str(415)], "application/json") + return hiascdi.respond(415, hiascdi.confs["errorMessages"][str(415)], "application/json") if _type is None: - return HIASCDI.respond(400, HIASCDI.helpers.confs["errorMessages"]["400b"], accepted) + return hiascdi.respond(400, hiascdi.confs["errorMessages"]["400b"], accepted) - return HIASCDI.types.getType(_type, accepted) + return hiascdi.types.getType(_type, accepted) @app.route('/subscriptions', methods=['GET']) def subscriptionsGet(): """ Responds to GET requests sent to the /v1/subscriptions API endpoint. """ - accepted, content_type = HIASCDI.processHeaders(request) + accepted, content_type = hiascdi.processHeaders(request) if accepted is False: - return HIASCDI.respond(406, HIASCDI.confs["errorMessages"][str(406)], "application/json") + return hiascdi.respond(406, hiascdi.confs["errorMessages"][str(406)], "application/json") if content_type is False: - return HIASCDI.respond(415, HIASCDI.confs["errorMessages"][str(415)], "application/json") + return hiascdi.respond(415, hiascdi.confs["errorMessages"][str(415)], "application/json") - return HIASCDI.subscriptions.getSubscriptions(request.args, accepted) + return hiascdi.subscriptions.getSubscriptions(request.args, accepted) @app.route('/subscriptions', methods=['POST']) def subscriptionsPost(): """ Responds to POST requests sent to the /v1/subscriptions API endpoint. """ - accepted, content_type = HIASCDI.processHeaders(request) + accepted, content_type = hiascdi.processHeaders(request) if accepted is False: - return HIASCDI.respond(406, HIASCDI.confs["errorMessages"][str(406)], "application/json") + return hiascdi.respond(406, hiascdi.confs["errorMessages"][str(406)], "application/json") if content_type is False: - return HIASCDI.respond(415, HIASCDI.confs["errorMessages"][str(415)], "application/json") + return hiascdi.respond(415, hiascdi.confs["errorMessages"][str(415)], "application/json") - query = HIASCDI.checkBody(request) + query = hiascdi.checkBody(request) if query is False: - return HIASCDI.respond(400, HIASCDI.helpers.confs["errorMessages"]["400p"], accepted) + return hiascdi.respond(400, hiascdi.confs["errorMessages"]["400p"], accepted) - return HIASCDI.subscriptions.createSubscription(query, accepted) + return hiascdi.subscriptions.createSubscription(query, accepted) @app.route('/subscriptions/<_subscription>', methods=['GET']) def subscriptionGet(_subscription): """ Responds to GET requests sent to the /v1/subscriptions/<_subscription> API endpoint. """ - accepted, content_type = HIASCDI.processHeaders(request) + accepted, content_type = hiascdi.processHeaders(request) if accepted is False: - return HIASCDI.respond(406, HIASCDI.confs["errorMessages"][str(406)], "application/json") + return hiascdi.respond(406, hiascdi.confs["errorMessages"][str(406)], "application/json") if content_type is False: - return HIASCDI.respond(415, HIASCDI.confs["errorMessages"][str(415)], "application/json") + return hiascdi.respond(415, hiascdi.confs["errorMessages"][str(415)], "application/json") if _subscription is None: - return HIASCDI.respond(400, HIASCDI.helpers.confs["errorMessages"]["400b"], accepted) + return hiascdi.respond(400, hiascdi.confs["errorMessages"]["400b"], accepted) - return HIASCDI.subscriptions.getSubscription(_subscription, accepted) + return hiascdi.subscriptions.getSubscription(_subscription, accepted) @app.route('/subscriptions/<_subscription>', methods=['PATCH']) def subscriptionPatch(_subscription): """ Responds to PATCH requests sent to the /v1/subscriptions/<_subscription> API endpoint. """ - accepted, content_type = HIASCDI.processHeaders(request) + accepted, content_type = hiascdi.processHeaders(request) if accepted is False: - return HIASCDI.respond(406, HIASCDI.confs["errorMessages"][str(406)], "application/json") + return hiascdi.respond(406, hiascdi.confs["errorMessages"][str(406)], "application/json") if content_type is False: - return HIASCDI.respond(415, HIASCDI.confs["errorMessages"][str(415)], "application/json") + return hiascdi.respond(415, hiascdi.confs["errorMessages"][str(415)], "application/json") if _subscription is None: - return HIASCDI.respond(400, HIASCDI.helpers.confs["errorMessages"]["400b"], accepted) + return hiascdi.respond(400, hiascdi.confs["errorMessages"]["400b"], accepted) - query = HIASCDI.checkBody(request) + query = hiascdi.checkBody(request) if query is False: - return HIASCDI.respond(400, HIASCDI.helpers.confs["errorMessages"]["400p"], accepted) + return hiascdi.respond(400, hiascdi.confs["errorMessages"]["400p"], accepted) - return HIASCDI.subscriptions.updateSubscription(_subscription, query, accepted) + return hiascdi.subscriptions.updateSubscription(_subscription, query, accepted) @app.route('/subscriptions/<_subscription>', methods=['DELETE']) def subscriptionDelete(_subscription): """ Responds to DELETE requests sent to the /v1/subscriptions/<_subscription> API endpoint. """ - accepted, content_type = HIASCDI.processHeaders(request) + accepted, content_type = hiascdi.processHeaders(request) if accepted is False: - return HIASCDI.respond(406, HIASCDI.confs["errorMessages"][str(406)], "application/json") + return hiascdi.respond(406, hiascdi.confs["errorMessages"][str(406)], "application/json") if content_type is False: - return HIASCDI.respond(415, HIASCDI.confs["errorMessages"][str(415)], "application/json") + return hiascdi.respond(415, hiascdi.confs["errorMessages"][str(415)], "application/json") if _subscription is None: - return HIASCDI.respond(400, HIASCDI.helpers.confs["errorMessages"]["400b"], accepted) + return hiascdi.respond(400, hiascdi.confs["errorMessages"]["400b"], accepted) - return HIASCDI.subscriptions.deleteSubscription(_subscription, accepted) + return hiascdi.subscriptions.deleteSubscription(_subscription, accepted) def main(): - signal.signal(signal.SIGINT, HIASCDI.signal_handler) - signal.signal(signal.SIGTERM, HIASCDI.signal_handler) + signal.signal(signal.SIGINT, hiascdi.signal_handler) + signal.signal(signal.SIGTERM, hiascdi.signal_handler) - HIASCDI.iotConnection() - HIASCDI.mongoDbConnection() - HIASCDI.hiascdiConnection() - HIASCDI.configureEntities() - HIASCDI.configureTypes() - HIASCDI.configureSubscriptions() + hiascdi.iotConnection() + hiascdi.mongoDbConnection() + hiascdi.hiascdiConnection() + hiascdi.configureEntities() + hiascdi.configureTypes() + hiascdi.configureSubscriptions() - Thread(target=HIASCDI.life, args=(), daemon=True).start() + Thread(target=hiascdi.life, args=(), daemon=True).start() - app.run(host=HIASCDI.helpers.confs["host"], - port=HIASCDI.helpers.confs["port"]) + app.run(host=hiascdi.credentials["server"]["ip"], + port=hiascdi.credentials["server"]["port"]) if __name__ == "__main__": main() diff --git a/modules/broker.py b/modules/broker.py index b2bdc0c..9427959 100644 --- a/modules/broker.py +++ b/modules/broker.py @@ -57,9 +57,6 @@ def __init__(self, helpers, mongodb): "content-type": self.helpers.confs["contentType"] } - self.auth = (self.helpers.credentials["identifier"], - self.helpers.credentials["auth"]) - self.helpers.logger.info("HIASCDI initialization complete.") def checkAcceptsType(self, headers): @@ -113,6 +110,14 @@ def checkBody(self, payload, text=False): return response + def checkBool(self, value): + """ Checks if a value is a bool. """ + + boolList = ['True', 'False', 'true', 'false'] + if value in boolList: + return True + return False + def checkFloat(self, value): """ Checks if a value is a float. """ @@ -130,7 +135,9 @@ def checkInteger(self, value): def cast(self, val): """ Casts relevant values as float or int. """ - if self.checkFloat(val): + if self.checkBool(val): + val = True if val.lower() == "true" else False + elif self.checkFloat(val): val = float(val) elif self.checkInteger(val): val = int(val) diff --git a/modules/entities.py b/modules/entities.py index 88e47b7..3903614 100644 --- a/modules/entities.py +++ b/modules/entities.py @@ -39,7 +39,7 @@ from mgoquery import Parser -from subscriptions import subscriptions +from modules.subscriptions import subscriptions class entities(): """ HIASCDI Entities Module. @@ -57,6 +57,8 @@ def __init__(self, helpers, mongodb, broker): self.mongodb = mongodb self.broker = broker + self.subscriptions = subscriptions(self.helpers, self.mongodb, self.broker) + self.helpers.logger.info(self.program + " initialization complete.") def getEntities(self, arguments, accepted=[]): @@ -661,6 +663,8 @@ def updateEntityPost(self, _id, typeof, data, options, accepted=[]): - Update or Append Entity Attributes """ + #self.subscriptions.checkForSubscription(_id) + updated = False error = False _append = False diff --git a/modules/helpers.py b/modules/helpers.py index 7f08572..1b40a85 100644 --- a/modules/helpers.py +++ b/modules/helpers.py @@ -65,17 +65,17 @@ def __init__(self, ltype, log=True): '%(asctime)s - %(name)s - %(levelname)s - %(message)s') allLogHandler = handlers.TimedRotatingFileHandler( - os.path.dirname(os.path.abspath(__file__)) + '/../../../logs/all.log', when='H', interval=1, backupCount=0) + os.path.dirname(os.path.abspath(__file__)) + '/../logs/all.log', when='H', interval=1, backupCount=0) allLogHandler.setLevel(logging.INFO) allLogHandler.setFormatter(formatter) errorLogHandler = handlers.TimedRotatingFileHandler( - os.path.dirname(os.path.abspath(__file__)) + '/../../../logs/error.log', when='H', interval=1, backupCount=0) + os.path.dirname(os.path.abspath(__file__)) + '/../logs/error.log', when='H', interval=1, backupCount=0) errorLogHandler.setLevel(logging.ERROR) errorLogHandler.setFormatter(formatter) warningLogHandler = handlers.TimedRotatingFileHandler( - os.path.dirname(os.path.abspath(__file__)) + '/../../../logs/warning.log', when='H', interval=1, backupCount=0) + os.path.dirname(os.path.abspath(__file__)) + '/../logs/warning.log', when='H', interval=1, backupCount=0) warningLogHandler.setLevel(logging.WARNING) warningLogHandler.setFormatter(formatter) @@ -98,7 +98,4 @@ def loadConfs(self): self.confs = json.loads(confs.read()) with open(os.path.dirname(os.path.abspath(__file__)) + '/../configuration/credentials.json') as confs: - self.credentials = json.loads(confs.read()) - - with open(os.path.dirname(os.path.abspath(__file__)) + '/../../../configuration/config.json') as confs: - self.confs_core = json.loads(confs.read()) + self.credentials = json.loads(confs.read()) \ No newline at end of file diff --git a/modules/mongodb.py b/modules/mongodb.py new file mode 100644 index 0000000..ba8b205 --- /dev/null +++ b/modules/mongodb.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python3 +""" HIASCDI MongoDB Helper Module. + +The HIASCDI MongoDB Helper Module provides MongoDB helper +functions to the HIASCDI application. + +MIT License + +Copyright (c) 2021 Asociación de Investigacion en Inteligencia Artificial +Para la Leucemia Peter Moss + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +Contributors: +- Adam Milton-Barker + +""" + +import sys + +from pymongo import MongoClient + +class mongodb(): + """ HIASCDI MongoDB Helper Module. + + The HIASCDI MongoDB Helper Module provides MongoDB helper + functions to the HIASCDI application. + """ + + def __init__(self, helpers): + """ Initializes the class. """ + + self.program = "MongoDB Helper Module" + + self.helpers = helpers + self.confs = self.helpers.confs + self.credentials = self.helpers.credentials + + self.helpers.logger.info(self.program + " initialization complete.") + + def start(self): + """ Connects to HIAS MongoDB database. """ + + self.mongoCon = MongoClient( + self.credentials["mongodb"]["host"]) + + self.mongoConn = self.mongoCon[self.credentials["mongodb"]["db"]] + + self.mongoConn.authenticate(self.credentials["mongodb"]["un"], + self.credentials["mongodb"]["up"]) + + self.collextions = { + "Actuator": self.mongoConn.Actuators, + "Agent": self.mongoConn.Entities, + "Application": self.mongoConn.Entities, + "ApplicationZone": self.mongoConn.ApplicationZones, + "Automation": self.mongoConn.Automation, + "HIASCDI": self.mongoConn.Entities, + "HIASHDI": self.mongoConn.Entities, + "Device": self.mongoConn.Entities, + "Location": self.mongoConn.Entities, + "Model": self.mongoConn.Entities, + "Robotics": self.mongoConn.Entities, + "Patient": self.mongoConn.Entities, + "Sensors": self.mongoConn.Sensors, + "Staff": self.mongoConn.Entities, + "Thing": self.mongoConn.Entities, + "Zone": self.mongoConn.Entities + } diff --git a/modules/mqtt.py b/modules/mqtt.py new file mode 100644 index 0000000..ffbf444 --- /dev/null +++ b/modules/mqtt.py @@ -0,0 +1,282 @@ +#!/usr/bin/env python3 +""" HIAS iotJumpWay MQTT Module + +This module connects devices, applications, robots and software to the HIAS +iotJumpWay MQTT Broker. + +MIT License + +Copyright (c) 2021 Asociación de Investigacion en Inteligencia Artificial +Para la Leucemia Peter Moss + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +Contributors: +- Adam Milton-Barker + +""" + +import json + +import paho.mqtt.client as pmqtt + +class mqtt(): + """HIAS iotJumpWay MQTT Module + + This module connects devices, applications, robots and software to + the HIAS iotJumpWay MQTT Broker. + """ + + def __init__(self, + helpers, + client_type, + configs): + """ Initializes the class. """ + + self.configs = configs + self.client_type = client_type + self.isConnected = False + + self.helpers = helpers + self.program = "HIAS iotJumpWay MQTT Module" + + self.mqtt_config = {} + self.module_topics = {} + + self.hiascdi = [ + 'host', + 'port', + 'location', + 'zone', + 'entity', + 'name', + 'un', + 'up' + ] + + self.helpers.logger.info(self.program + " initialization complete.") + + def configure(self): + """ Connection configuration. + + Configures the HIAS iotJumpWay MQTT connnection. + """ + + # Checks required parameters + self.client_id = self.configs['name'] + for param in self.hiascdi: + if self.configs[param] is None: + raise ConfigurationException(param + " parameter is required!") + + # Sets MQTT connection configuration + self.mqtt_config["tls"] = "/etc/ssl/certs/DST_Root_CA_X3.pem" + self.mqtt_config["host"] = self.configs['host'] + self.mqtt_config["port"] = self.configs['port'] + + # Sets MQTT topics + self.module_topics["statusTopic"] = '%s/HIASCDI/%s/%s/Status' % ( + self.configs['location'], self.configs['zone'], self.configs['entity']) + + # Sets MQTT callbacks + self.actuatorCallback = None + self.bciCallback = None + self.commandsCallback = None + self.integrityCallback = None + self.lifeCallback = None + self.modelCallback = None + self.sensorsCallback = None + self.stateCallback = None + self.statusCallback = None + self.zoneCallback = None + + self.helpers.logger.info( + "iotJumpWay " + self.client_type + " connection configured.") + + def start(self): + """ Connection + + Starts the HIAS iotJumpWay MQTT connection. + """ + + self.mClient = pmqtt.Client(client_id=self.client_id, clean_session=True) + self.mClient.will_set(self.module_topics["statusTopic"], "OFFLINE", 0, False) + self.mClient.tls_set(self.mqtt_config["tls"], certfile=None, keyfile=None) + self.mClient.on_connect = self.on_connect + self.mClient.on_message = self.on_message + self.mClient.on_publish = self.on_publish + self.mClient.on_subscribe = self.on_subscribe + self.mClient.username_pw_set(str(self.configs['un']), str(self.configs['up'])) + self.mClient.connect(self.mqtt_config["host"], self.mqtt_config["port"], 10) + self.mClient.loop_start() + + self.helpers.logger.info( + "iotJumpWay " + self.client_type + " connection started.") + + def on_connect(self, client, obj, flags, rc): + """ On connection + + On connection callback. + """ + + if self.isConnected != True: + self.isConnected = True + + self.helpers.logger.info("iotJumpWay " + self.client_type + " connection successful.") + self.helpers.logger.info("rc: " + str(rc)) + + self.statusPublish("ONLINE") + + def statusPublish(self, data): + """ Status publish + + Publishes a status. + """ + + self.mClient.publish(self.module_topics["statusTopic"], data) + self.helpers.logger.info("Published to " + self.client_type + " status.") + + def on_subscribe(self, client, obj, mid, granted_qos): + """ On subscribe + + On subscription callback. + """ + + self.helpers.logger.info("iotJumpWay " + self.client_type + " subscription") + + def on_message(self, client, obj, msg): + """ On message + + On message callback. + """ + + splitTopic = msg.topic.split("/") + connType = splitTopic[1] + + topic = splitTopic[4] + + self.helpers.logger.info(msg.payload) + self.helpers.logger.info("iotJumpWay " + connType + " " + msg.topic + " communication received.") + + if topic == 'Actuators': + if self.actuatorCallback == None: + self.helpers.logger.info( + connType + " actuator callback required (actuatorCallback) !") + else: + self.actuatorCallback(msg.topic, msg.payload) + elif topic == 'BCI': + if self.bciCallback == None: + self.helpers.logger.info( + connType + " BCI callback required (bciCallback) !") + else: + self.bciCallback(msg.topic, msg.payload) + elif topic == 'Commands': + if self.commandsCallback == None: + self.helpers.logger.info( + connType + " comands callback required (commandsCallback) !") + else: + self.commandsCallback(msg.topic, msg.payload) + elif topic == 'Integrity': + if self.integrityCallback == None: + self.helpers.logger.info( + connType + " Integrity callback required (integrityCallback) !") + else: + self.integrityCallback(msg.topic, msg.payload) + elif topic == 'Life': + if self.lifeCallback == None: + self.helpers.logger.info( + connType + " life callback required (lifeCallback) !") + else: + self.lifeCallback(msg.topic, msg.payload) + elif topic == 'Sensors': + if self.sensorsCallback == None: + self.helpers.logger.info( + connType + " status callback required (sensorsCallback) !") + else: + self.sensorsCallback(msg.topic, msg.payload) + elif topic == 'State': + if self.stateCallback == None: + self.helpers.logger.info( + connType + " life callback required (stateCallback) !") + else: + self.stateCallback(msg.topic, msg.payload) + elif topic == 'Status': + if self.statusCallback == None: + self.helpers.logger.info( + connType + " status callback required (statusCallback) !") + else: + self.statusCallback(msg.topic, msg.payload) + elif topic == 'Zone': + if self.zoneCallback == None: + self.helpers.logger.info( + connType + " status callback required (zoneCallback) !") + else: + self.zoneCallback(msg.topic, msg.payload) + + def publish(self, channel, data, channelPath = ""): + """ Publish + + Publishes a iotJumpWay MQTT payload. + """ + + if channel == "Custom": + channel = channelPath + else: + channel = '%s/HIASCDI/%s/%s/%s' % ( + self.configs['location'], self.configs['zone'], self.configs['entity'], channel) + + self.mClient.publish(channel, json.dumps(data)) + self.helpers.logger.info("Published to " + channel) + return True + + def subscribe(self, application = None, channelID = None, qos=0): + """ Subscribe + + Subscribes to an iotJumpWay MQTT channel. + """ + + channel = '%s/#' % (self.configs['location']) + self.mClient.subscribe(channel, qos=qos) + self.helpers.logger.info("-- Agent subscribed to all channels") + return True + + def on_publish(self, client, obj, mid): + """ On publish + + On publish callback. + """ + + self.helpers.logger.info("Published: "+str(mid)) + + def on_log(self, client, obj, level, string): + """ On log + + On log callback. + """ + + print(string) + + def disconnect(self): + """ Disconnect + + Disconnects from the HIAS iotJumpWay MQTT Broker. + """ + + self.statusPublish("OFFLINE") + self.mClient.disconnect() + self.mClient.loop_stop() diff --git a/modules/subscriptions.py b/modules/subscriptions.py index 4c4196b..3a79a0c 100644 --- a/modules/subscriptions.py +++ b/modules/subscriptions.py @@ -38,7 +38,6 @@ import sys from bson import json_util, ObjectId - from flask import Response @@ -229,4 +228,14 @@ def deleteSubscription(self, subscription, accepted=[]): else: self.helpers.logger.info("Mongo data delete FAILED") return self.broker.respond(400, self.helpers.confs["errorMessages"]["400b"], - {}, False, accepted) \ No newline at end of file + {}, False, accepted) + + def checkForSubscription(self, subscription): + """ Checks for subscriptions in an list """ + + self.helpers.logger.info("Checking for subscriptions") + subscriptions = self.mongodb.mongoConn.Subscriptions.find() + + for sub in subscriptions: + cursub = self.getSubscription(sub) + print(cursub) diff --git a/scripts/services.sh b/scripts/services.sh new file mode 100644 index 0000000..e69de29