diff --git a/app/__init__.py b/app/__init__.py index 0dc6025..8220f6d 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -26,9 +26,11 @@ def setup_blueprints(app): from .devices import devices_bp from .accounts import accounts_bp from .api import api_bp + from .mqtt import mqtt_bp app.register_blueprint(devices_bp) app.register_blueprint(accounts_bp) + app.register_blueprint(mqtt_bp) app.register_blueprint(api_bp, url_prefix='/api') diff --git a/app/devices/__init__.py b/app/devices/__init__.py index 0de869f..c7b5012 100644 --- a/app/devices/__init__.py +++ b/app/devices/__init__.py @@ -1,26 +1,11 @@ -import atexit +import sys from flask import Blueprint -from .mqtt_client import MqttClient from .models import Device, Recording +from app import app devices_bp = Blueprint('devices', __name__) -# When app dies, stop mqtt connection -def on_stop(): - MqttClient.tear_down() - - -atexit.register(on_stop) - - -# Setup -@devices_bp.record -def __on_blueprint_setup(setup_state): - print('Blueprint setup') - MqttClient.setup(setup_state.app) - - # Public interface def create_device(name, device_type=1): """ @@ -69,3 +54,33 @@ def get_device(device_id): raise ValueError("Device with id %s does not exist" % device_id) return Device.get(id=device_id) + + +def create_recording(device_id, raw_json): + """ + Tries to create recording with given parameters. Raises error on failure + + :param device_id: Id of device + :type device_id: int + :param raw_json: Raw json received + :type raw_json: json + :raises: ValueError if parsing fails or device does not exist + """ + def parse_raw_json_recording(device_id, json_msg) -> Recording: + try: + return Recording(device_id=device_id, + record_type=json_msg["record_type"], + record_value=json_msg["record_value"], + recorded_at=json_msg["recorded_at"], + raw_json=json_msg) + except KeyError: + error_type, error_instance, traceback = sys.exc_info() + raise ValueError("JSON parsing failed! Key error: " + + str(error_instance)) + + if not Device.exists(id=device_id): + raise ValueError("Device does not exist!") + + recording = parse_raw_json_recording(device_id, raw_json) + with app.app_context(): + recording.save() diff --git a/app/mqtt/__init__.py b/app/mqtt/__init__.py new file mode 100644 index 0000000..f881c9b --- /dev/null +++ b/app/mqtt/__init__.py @@ -0,0 +1,19 @@ +import atexit +from flask import Blueprint +from .mqtt_client import MqttClient + +mqtt_bp = Blueprint('mqtt', __name__) + + +# Setup +@mqtt_bp.record +def __on_blueprint_setup(setup_state): + MqttClient.setup(setup_state.app) + + +# When app dies, stop mqtt connection +def on_stop(): + MqttClient.tear_down() + + +atexit.register(on_stop) diff --git a/app/devices/mqtt_client.py b/app/mqtt/mqtt_client.py similarity index 68% rename from app/devices/mqtt_client.py rename to app/mqtt/mqtt_client.py index 579c9bc..c2dff1d 100644 --- a/app/devices/mqtt_client.py +++ b/app/mqtt/mqtt_client.py @@ -1,8 +1,7 @@ import sys import json from flask_mqtt import Mqtt -from .models import Recording -from app import app +import app.devices as devices class MqttClient: @@ -49,10 +48,9 @@ class MqttClient: print("Payload: " + message.payload.decode()) try: # If type is JSON - recording = MqttClient.parse_json_message( - message.topic, message.payload.decode()) - with app.app_context(): - recording.save() + devices.create_recording( + MqttClient.get_device_id(message.topic), + json.loads(message.payload.decode())) except ValueError: print("ERROR!") error_type, error_instance, traceback = sys.exc_info() @@ -60,21 +58,6 @@ class MqttClient: print("Instance: " + str(error_instance)) return - @staticmethod - def parse_json_message(topic, payload) -> Recording: - try: - json_msg = json.loads(payload) - device_id = MqttClient.get_device_id(topic) - return Recording(device_id=device_id, - record_type=json_msg["record_type"], - record_value=json_msg["record_value"], - recorded_at=json_msg["recorded_at"], - raw_json=json_msg) - except KeyError: - error_type, error_instance, traceback = sys.exc_info() - raise ValueError("JSON parsing failed! Key error: " - + str(error_instance)) - @staticmethod def get_device_id(topic) -> int: device_token, device_id = topic.split("/")