From 422a7efa6fc49d870d64c9dde5216a3d141461c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torma=20Krist=C3=B3f?= Date: Mon, 20 Jul 2020 18:19:31 +0200 Subject: [PATCH] flask endpoints done --- src/models.py | 3 +- src/mqtt_methods.py | 7 ++- src/resources.py | 115 +++++++++++++++++++++++++++++++++++++++++++- src/schemas.py | 1 + 4 files changed, 122 insertions(+), 4 deletions(-) diff --git a/src/models.py b/src/models.py index 2e6c08c..4f00692 100644 --- a/src/models.py +++ b/src/models.py @@ -28,7 +28,8 @@ class SensorStatusEnum(StatusEnum): class Device(db.Model): __tablename__ = 'device' - id = db.Column(db.UUID, primary_key=True) + id = db.Column(db.Integer, primary_key=True) + sensorid = db.Column(db.UUID, nullable=False) status = db.Column(db.Enum(DeviceStatusEnum), nullable=False) url = db.Column(db.String, nullable=False) lastupdate = db.Column(db.TIMESTAMP, nullable=False, server_default=func.now(), onupdate=func.current_timestamp()) diff --git a/src/mqtt_methods.py b/src/mqtt_methods.py index 6f537ab..3e152a9 100644 --- a/src/mqtt_methods.py +++ b/src/mqtt_methods.py @@ -16,6 +16,9 @@ __version__text__ = "1" deviceschema = DeviceSchema(many=False) +LOGGER = logging.getLogger(__name__) + + @mqtt.on_message() def handle_status_message(client, userdata, message): data = dict( @@ -24,10 +27,10 @@ def handle_status_message(client, userdata, message): ) try: status_message = deviceschema.load(data['payload'], session=db.session, transient=True).data - logging.info(f"Recieved status message from {data['payload']['id']}, persisting to db.") + LOGGER.info(f"Recieved status message from {data['payload']['id']}, persisting to db.") db.session.merge(status_message) except Exception as e: db.session.rollback() - logging.exception(e) + LOGGER.exception(e) else: db.session.commit() diff --git a/src/resources.py b/src/resources.py index 1bf732a..5386435 100644 --- a/src/resources.py +++ b/src/resources.py @@ -1,6 +1,11 @@ #!/usr/bin/env python3 import logging - +from flask_restful import Resource +from db import db +from mqtt_flask_instance import mqtt +import config +import models +import schemas """ Flask Restful endpoints @@ -10,3 +15,111 @@ __author__ = '@tormakris' __copyright__ = "Copyright 2020, Birbnetes Team" __module_name__ = "resources" __version__text__ = "1" + +LOGGER = logging.getLogger(__name__) + + +class AllDevicesResource(Resource): + """ + Query and control all known devices + """ + alldeviceschema = schemas.DeviceSchema(many=True) + + def get(self): + """ + Get all stored items + :return: + """ + alldevices = models.Device.query.all() + return self.alldeviceschema.dump(list(alldevices)), 200 + + def delete(self): + """ + Shut down every device + :return: + """ + ids = db.session.query(models.Device.id).filter(models.Device.status != models.DeviceStatusEnum.offline) + for d_id in ids: + mqtt.publish(config.MQTT_COMMAND_TOPIC, {"deviceID": d_id, "command": "offline"}) + + def post(self): + """ + Bring every device online + :return: + """ + ids = db.session.query(models.Device.id).filter(models.Device.status != models.DeviceStatusEnum.online) + for d_id in ids: + mqtt.publish(config.MQTT_COMMAND_TOPIC, {"deviceID": d_id, "command": "online"}) + + +class DeviceResource(Resource): + """ + Query and control a particular device + """ + deviceschema = schemas.DeviceSchema(many=False) + + def get(self, deviceid: str): + """ + Query a device + :param deviceid: UUID of device + :return: + """ + device = models.Device.query.filter_by(id=deviceid).first_or_404() + return self.deviceschema.dump(device), 200 + + def delete(self, deviceid: str): + """ + Shut down a device + :param deviceid: UUID of device + :return: + """ + device = db.session.query(models.Device.id).filter(str(models.Device.id) == deviceid).first() + mqtt.publish(config.MQTT_COMMAND_TOPIC, {"deviceID": device, "command": "offline"}) + + def post(self, deviceid: str): + """ + Bring a device online + :param deviceid: UUID of device + :return: + """ + device = db.session.query(models.Device.id).filter(str(models.Device.id) == deviceid).first() + mqtt.publish(config.MQTT_COMMAND_TOPIC, {"deviceID": device, "command": "offline"}) + + +class SensorResource(Resource): + """ + Query and control a particular sensor of a device + """ + sensorschema = schemas.SensorSchema(many=False) + + def get(self, deviceid: str, sensorid: str): + """ + Query a sensor + :param deviceid: UUID of device + :param sensorid: UUID of sensor + :return: + """ + sensor = models.Sensor.query.filter_by(device_id=deviceid, sensorid=sensorid).first_or_404() + return self.sensorschema.dump(sensor) + + def delete(self, deviceid: str, sensorid: str): + """ + Shut down a sensor of a device + :param deviceid: UUID of device + :param sensorid: UUID of sensor + :return: + """ + sensor = db.session.query(models.Sensor.device_id, models.Sensor.id).filter( + str(models.Sensor.device_id) == deviceid & & str(models.Sensor.id) == sensorid) + mqtt.publish(config.MQTT_COMMAND_TOPIC, {"deviceID": sensor, "sensorID": sensor, "command": "offline"}) + + def post(self, deviceid: str, sensorid: str): + """ + Bring a sensor online + :param deviceid: UUID of device + :param sensorid: UUID of sensor + :return: + """ + sensor = db.session.query(models.Sensor.device_id, models.Sensor.id).filter( + str(models.Sensor.device_id) == deviceid & & str(models.Sensor.id) == sensorid) + mqtt.publish(config.MQTT_COMMAND_TOPIC, {"deviceID": sensor, "sensorID": sensor, "command": "online"}) diff --git a/src/schemas.py b/src/schemas.py index 6ea8597..cb87167 100644 --- a/src/schemas.py +++ b/src/schemas.py @@ -21,6 +21,7 @@ class SensorSchema(ma.SQLAlchemyAutoSchema): class Meta: model = models.Sensor include_fk = True + exclude = ('id',) class DeviceSchema(ma.SQLAlchemyAutoSchema):