diff --git a/database/install/myems_system_db.sql b/database/install/myems_system_db.sql index dc568823b7474f5b9d29b0fd2bbe3098c7020e6a..11b428446226e79dc3ad3dbcb8805ed0dc4bf150 100644 --- a/database/install/myems_system_db.sql +++ b/database/install/myems_system_db.sql @@ -566,7 +566,7 @@ CREATE TABLE IF NOT EXISTS `myems_system_db`.`tbl_microgrids` ( `address` VARCHAR(255) NOT NULL, `latitude` DECIMAL(9, 6) NOT NULL, `longitude` DECIMAL(9, 6) NOT NULL, - `installed_capacity` DECIMAL(18, 3) NOT NULL, + `capacity` DECIMAL(18, 3) NOT NULL, `microgrid_type_id` BIGINT NOT NULL, `microgrid_owner_type_id` BIGINT NOT NULL, `is_input_counted` BOOL NOT NULL, @@ -631,6 +631,47 @@ VALUES (3, 'Industrial', 'e99fceda-1b34-4b6a-8bd2-c8532c835322', 'Industry', 'IND'); +-- --------------------------------------------------------------------------------------------------------------------- +-- Table `myems_system_db`.`tbl_microgrids_batteries` +-- --------------------------------------------------------------------------------------------------------------------- +DROP TABLE IF EXISTS `myems_system_db`.`tbl_microgrids_batteries` ; + +CREATE TABLE IF NOT EXISTS `myems_system_db`.`tbl_microgrids_batteries` ( + `id` BIGINT NOT NULL AUTO_INCREMENT, + `name` VARCHAR(255) NOT NULL, + `uuid` CHAR(36) NOT NULL, + `microgrid_id` BIGINT NOT NULL, + `capacity` DECIMAL(18, 3) NOT NULL, + PRIMARY KEY (`id`)); +CREATE INDEX `tbl_microgrids_batteries_index_1` ON `myems_system_db`.`tbl_microgrids_batteries` (`name`); + +-- --------------------------------------------------------------------------------------------------------------------- +-- Table `myems_system_db`.`tbl_microgrids_photovoltaics` +-- --------------------------------------------------------------------------------------------------------------------- +DROP TABLE IF EXISTS `myems_system_db`.`tbl_microgrids_photovoltaics` ; + +CREATE TABLE IF NOT EXISTS `myems_system_db`.`tbl_microgrids_photovoltaics` ( + `id` BIGINT NOT NULL AUTO_INCREMENT, + `name` VARCHAR(255) NOT NULL, + `uuid` CHAR(36) NOT NULL, + `microgrid_id` BIGINT NOT NULL, + `capacity` DECIMAL(18, 3) NOT NULL, + PRIMARY KEY (`id`)); +CREATE INDEX `tbl_microgrids_photovoltaics_index_1` ON `myems_system_db`.`tbl_microgrids_photovoltaics` (`name`); + + +-- --------------------------------------------------------------------------------------------------------------------- +-- Table `myems_system_db`.`tbl_microgrids_sensors` +-- --------------------------------------------------------------------------------------------------------------------- +DROP TABLE IF EXISTS `myems_system_db`.`tbl_microgrids_sensors` ; + +CREATE TABLE IF NOT EXISTS `myems_system_db`.`tbl_microgrids_sensors` ( + `id` BIGINT NOT NULL AUTO_INCREMENT, + `microgrid_id` BIGINT NOT NULL, + `sensor_id` BIGINT NOT NULL, + PRIMARY KEY (`id`)); +CREATE INDEX `tbl_microgrids_sensors_index_1` ON `myems_system_db`.`tbl_microgrids_sensors` (`microgrid_id`); + -- --------------------------------------------------------------------------------------------------------------------- -- Table `myems_system_db`.`tbl_offline_meters` -- --------------------------------------------------------------------------------------------------------------------- diff --git a/database/upgrade/upgrade3.4.0RC.sql b/database/upgrade/upgrade3.4.0RC.sql index cec999e1fc2f3ab0c2b8ec16fe9fcbf70d20adf7..4842277672e8c47b92396823ff21f9d44d3e82ee 100644 --- a/database/upgrade/upgrade3.4.0RC.sql +++ b/database/upgrade/upgrade3.4.0RC.sql @@ -18,7 +18,7 @@ CREATE TABLE IF NOT EXISTS `myems_system_db`.`tbl_microgrids` ( `address` VARCHAR(255) NOT NULL, `latitude` DECIMAL(9, 6) NOT NULL, `longitude` DECIMAL(9, 6) NOT NULL, - `installed_capacity` DECIMAL(18, 3) NOT NULL, + `capacity` DECIMAL(18, 3) NOT NULL, `microgrid_type_id` BIGINT NOT NULL, `microgrid_owner_type_id` BIGINT NOT NULL, `is_input_counted` BOOL NOT NULL, @@ -81,6 +81,46 @@ VALUES (3, 'Industrial', 'e99fceda-1b34-4b6a-8bd2-c8532c835322', 'Industry', 'IND'); +-- --------------------------------------------------------------------------------------------------------------------- +-- Table `myems_system_db`.`tbl_microgrids_batteries` +-- --------------------------------------------------------------------------------------------------------------------- +DROP TABLE IF EXISTS `myems_system_db`.`tbl_microgrids_batteries` ; + +CREATE TABLE IF NOT EXISTS `myems_system_db`.`tbl_microgrids_batteries` ( + `id` BIGINT NOT NULL AUTO_INCREMENT, + `name` VARCHAR(255) NOT NULL, + `uuid` CHAR(36) NOT NULL, + `microgrid_id` BIGINT NOT NULL, + `capacity` DECIMAL(18, 3) NOT NULL, + PRIMARY KEY (`id`)); +CREATE INDEX `tbl_microgrids_batteries_index_1` ON `myems_system_db`.`tbl_microgrids_batteries` (`name`); + +-- --------------------------------------------------------------------------------------------------------------------- +-- Table `myems_system_db`.`tbl_microgrids_photovoltaics` +-- --------------------------------------------------------------------------------------------------------------------- +DROP TABLE IF EXISTS `myems_system_db`.`tbl_microgrids_photovoltaics` ; + +CREATE TABLE IF NOT EXISTS `myems_system_db`.`tbl_microgrids_photovoltaics` ( + `id` BIGINT NOT NULL AUTO_INCREMENT, + `name` VARCHAR(255) NOT NULL, + `uuid` CHAR(36) NOT NULL, + `microgrid_id` BIGINT NOT NULL, + `capacity` DECIMAL(18, 3) NOT NULL, + PRIMARY KEY (`id`)); +CREATE INDEX `tbl_microgrids_photovoltaics_index_1` ON `myems_system_db`.`tbl_microgrids_photovoltaics` (`name`); + +-- --------------------------------------------------------------------------------------------------------------------- +-- Table `myems_system_db`.`tbl_microgrids_sensors` +-- --------------------------------------------------------------------------------------------------------------------- +DROP TABLE IF EXISTS `myems_system_db`.`tbl_microgrids_sensors` ; + +CREATE TABLE IF NOT EXISTS `myems_system_db`.`tbl_microgrids_sensors` ( + `id` BIGINT NOT NULL AUTO_INCREMENT, + `microgrid_id` BIGINT NOT NULL, + `sensor_id` BIGINT NOT NULL, + PRIMARY KEY (`id`)); +CREATE INDEX `tbl_microgrids_sensors_index_1` ON `myems_system_db`.`tbl_microgrids_sensors` (`microgrid_id`); + -- UPDATE VERSION NUMBER UPDATE `myems_system_db`.`tbl_versions` SET version='3.4.0RC', release_date='2023-06-16' WHERE id=1; diff --git a/myems-api/MyEMS.postman_collection.json b/myems-api/MyEMS.postman_collection.json index 3790fb79cbac0ffb1265d4aa3703804558b09c92..cf6c07f6fc1544f32d99e018c342bea1767ab7bc 100644 --- a/myems-api/MyEMS.postman_collection.json +++ b/myems-api/MyEMS.postman_collection.json @@ -1,9 +1,8 @@ { "info": { - "_postman_id": "bd0a9e37-486d-4575-b91a-bdbdcddae6b3", + "_postman_id": "cf01b0e4-707f-4eab-9532-96586e805515", "name": "MyEMS", - "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", - "_exporter_id": "9079920" + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" }, "item": [ { @@ -4587,6 +4586,224 @@ } ] }, + { + "name": "Microgrid", + "item": [ + { + "name": "GET All Microgrids", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{base_url}}/microgrids", + "host": [ + "{{base_url}}" + ], + "path": [ + "microgrids" + ] + } + }, + "response": [] + }, + { + "name": "GET a Microgrid by ID", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{base_url}}/microgrids/1", + "host": [ + "{{base_url}}" + ], + "path": [ + "microgrids", + "1" + ] + } + }, + "response": [] + }, + { + "name": "POST Create New Microgrids", + "request": { + "method": "POST", + "header": [ + { + "key": "User-UUID", + "value": "dcdb67d1-6116-4987-916f-6fc6cf2bc0e4", + "type": "text" + }, + { + "key": "Token", + "value": "9a3748fadf64270dd4617594939169d0008a1b713e3a5861af384c68de73442b56b56771ce2be1e51ecd7443ec0fc1fbd6dcc3335a2c7518ca12b7a479ccb2e0", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\"data\":{\"name\":\"Beijing Office\", \"address\":\"Wangfujing Street, Dongcheng District, Beijing\", \"latitude\":39.909429, \"longitude\":116.416993, \"capacity\":600.000, \"microgrid_type_id\":1, \"microgrid_owner_type_id\":1, \"is_input_counted\":true, \"is_output_counted\":true, \"contact_id\":1, \"cost_center_id\":1, \"description\":\"Classic\"}}" + }, + "url": { + "raw": "{{base_url}}/microgrids", + "host": [ + "{{base_url}}" + ], + "path": [ + "microgrids" + ] + } + }, + "response": [] + }, + { + "name": "PUT Update a Microgrid", + "request": { + "method": "PUT", + "header": [ + { + "key": "User-UUID", + "value": "dcdb67d1-6116-4987-916f-6fc6cf2bc0e4", + "type": "text" + }, + { + "key": "Token", + "value": "9a3748fadf64270dd4617594939169d0008a1b713e3a5861af384c68de73442b56b56771ce2be1e51ecd7443ec0fc1fbd6dcc3335a2c7518ca12b7a479ccb2e0", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\"data\":{\"name\":\"Beijing Office\", \"address\":\"Wangfujing Street, Dongcheng District, Beijing\", \"latitude\":39.909429, \"longitude\":116.416993, \"capacity\":600.000, \"microgrid_type_id\":1, \"microgrid_owner_type_id\":1, \"is_input_counted\":true, \"is_output_counted\":true, \"contact_id\":1, \"cost_center_id\":1, \"description\":\"New\"}}" + }, + "url": { + "raw": "{{base_url}}/microgrids/1", + "host": [ + "{{base_url}}" + ], + "path": [ + "microgrids", + "1" + ] + } + }, + "response": [] + }, + { + "name": "DELETE a Microgrid by ID", + "request": { + "method": "DELETE", + "header": [ + { + "key": "User-UUID", + "value": "dcdb67d1-6116-4987-916f-6fc6cf2bc0e4", + "type": "text" + }, + { + "key": "Token", + "value": "9a3748fadf64270dd4617594939169d0008a1b713e3a5861af384c68de73442b56b56771ce2be1e51ecd7443ec0fc1fbd6dcc3335a2c7518ca12b7a479ccb2e0", + "type": "text" + } + ], + "url": { + "raw": "{{base_url}}/microgrids/2", + "host": [ + "{{base_url}}" + ], + "path": [ + "microgrids", + "2" + ] + } + }, + "response": [] + }, + { + "name": "GET All Sensors of Microgrid by ID", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{base_url}}/microgrids/1/sensors", + "host": [ + "{{base_url}}" + ], + "path": [ + "microgrids", + "1", + "sensors" + ] + } + }, + "response": [] + }, + { + "name": "POST Bind a Sensor to a Microgrid", + "request": { + "method": "POST", + "header": [ + { + "key": "User-UUID", + "value": "dcdb67d1-6116-4987-916f-6fc6cf2bc0e4", + "type": "text" + }, + { + "key": "Token", + "value": "9a3748fadf64270dd4617594939169d0008a1b713e3a5861af384c68de73442b56b56771ce2be1e51ecd7443ec0fc1fbd6dcc3335a2c7518ca12b7a479ccb2e0", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\"data\":{\"sensor_id\":1}}" + }, + "url": { + "raw": "{{base_url}}/microgrids/1/sensors", + "host": [ + "{{base_url}}" + ], + "path": [ + "microgrids", + "1", + "sensors" + ] + } + }, + "response": [] + }, + { + "name": "DELETE a Sensor from Stores", + "request": { + "method": "DELETE", + "header": [ + { + "key": "User-UUID", + "value": "dcdb67d1-6116-4987-916f-6fc6cf2bc0e4", + "type": "text" + }, + { + "key": "Token", + "value": "9a3748fadf64270dd4617594939169d0008a1b713e3a5861af384c68de73442b56b56771ce2be1e51ecd7443ec0fc1fbd6dcc3335a2c7518ca12b7a479ccb2e0", + "type": "text" + } + ], + "url": { + "raw": "{{base_url}}/microgrids/1/sensors/1", + "host": [ + "{{base_url}}" + ], + "path": [ + "microgrids", + "1", + "sensors", + "1" + ] + } + }, + "response": [] + } + ] + }, { "name": "Notification", "item": [ diff --git a/myems-api/README.md b/myems-api/README.md index 3410eedf72fa7b48b5391f0a546e28208279592c..f91311159494c59eac2aa11eb3a7b8dc992dec3d 100644 --- a/myems-api/README.md +++ b/myems-api/README.md @@ -35,7 +35,7 @@ python-decouple Quick run on Linux (NOT for production use): ```bash cd myems/myems-api -sudo pip install -r requirements.txt -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com +sudo pip install -r requirements.txt cp example.env .env sudo chmod +x run.sh ./run.sh diff --git a/myems-api/app.py b/myems-api/app.py index 059e860775b0383a3d7b29b0a3ff5a1693aaea6b..3d42ff21925292fa1b87d0f4719525fea7bdb87e 100644 --- a/myems-api/app.py +++ b/myems-api/app.py @@ -6,7 +6,9 @@ from core import energyflowdiagram, privilege, textmessage, distributioncircuit, costcenter, point, knowledgefile, meter, tariff, user, storetype, timezone, \ costfile, offlinemeterfile, version, contact, emailserver, combinedequipment, datasource, equipment, tenant, \ shopfloor, webmessage, distributionsystem, store, emailmessage, tenanttype, wechatmessage, space, gateway, \ - offlinemeter, rule, energycategory, sensor, energyitem, notification, menu, datarepairfile, workingcalendar + offlinemeter, rule, energycategory, sensor, energyitem, notification, menu, datarepairfile, workingcalendar, \ + microgrid + from reports import advancedreport from reports import combinedequipmentbatch from reports import combinedequipmentcarbon @@ -277,6 +279,15 @@ api.add_route('/meters/{id_}/points', api.add_route('/meters/{id_}/points/{pid}', meter.MeterPointItem()) +api.add_route('/microgrids', + microgrid.MicrogridCollection()) +api.add_route('/microgrids/{id_}', + microgrid.MicrogridItem()) +api.add_route('/microgrids/{id_}/sensors', + microgrid.MicrogridSensorCollection()) +api.add_route('/microgrids/{id_}/sensors/{sid}', + microgrid.MicrogridSensorItem()) + api.add_route('/notifications', notification.NotificationCollection()) api.add_route('/notifications/{id_}', diff --git a/myems-api/core/microgrid.py b/myems-api/core/microgrid.py new file mode 100644 index 0000000000000000000000000000000000000000..54b35892fdbf8deac41d3bdbac76ad32469c5f67 --- /dev/null +++ b/myems-api/core/microgrid.py @@ -0,0 +1,819 @@ +import uuid + +import falcon +import mysql.connector +import simplejson as json + +import config +from core.useractivity import user_logger, access_control + + +class MicrogridCollection: + @staticmethod + def __init__(): + """"Initializes MicrogridCollection""" + pass + + @staticmethod + def on_options(req, resp): + resp.status = falcon.HTTP_200 + + @staticmethod + def on_get(req, resp): + cnx = mysql.connector.connect(**config.myems_system_db) + cursor = cnx.cursor() + + query = (" SELECT id, name, uuid " + " FROM tbl_microgrid_types ") + cursor.execute(query) + rows_microgrid_types = cursor.fetchall() + + microgrid_type_dict = dict() + if rows_microgrid_types is not None and len(rows_microgrid_types) > 0: + for row in rows_microgrid_types: + microgrid_type_dict[row[0]] = {"id": row[0], + "name": row[1], + "uuid": row[2]} + query = (" SELECT id, name, uuid " + " FROM tbl_microgrid_owner_types ") + cursor.execute(query) + rows_microgrid_owner_types = cursor.fetchall() + + microgrid_owner_type_dict = dict() + if rows_microgrid_owner_types is not None and len(rows_microgrid_owner_types) > 0: + for row in rows_microgrid_owner_types: + microgrid_owner_type_dict[row[0]] = {"id": row[0], + "name": row[1], + "uuid": row[2]} + + query = (" SELECT id, name, uuid " + " FROM tbl_contacts ") + cursor.execute(query) + rows_contacts = cursor.fetchall() + + contact_dict = dict() + if rows_contacts is not None and len(rows_contacts) > 0: + for row in rows_contacts: + contact_dict[row[0]] = {"id": row[0], + "name": row[1], + "uuid": row[2]} + + query = (" SELECT id, name, uuid " + " FROM tbl_cost_centers ") + cursor.execute(query) + rows_cost_centers = cursor.fetchall() + + cost_center_dict = dict() + if rows_cost_centers is not None and len(rows_cost_centers) > 0: + for row in rows_cost_centers: + cost_center_dict[row[0]] = {"id": row[0], + "name": row[1], + "uuid": row[2]} + + query = (" SELECT id, name, uuid, " + " address, latitude, longitude, capacity, " + " microgrid_type_id, microgrid_owner_type_id, " + " is_input_counted, is_output_counted, contact_id, cost_center_id, description " + " FROM tbl_microgrids " + " ORDER BY id ") + cursor.execute(query) + rows_spaces = cursor.fetchall() + + result = list() + if rows_spaces is not None and len(rows_spaces) > 0: + for row in rows_spaces: + microgrid_type = microgrid_type_dict.get(row[7], None) + microgrid_owner_type = microgrid_owner_type_dict.get(row[8], None) + contact = contact_dict.get(row[11], None) + cost_center = cost_center_dict.get(row[12], None) + + meta_result = {"id": row[0], + "name": row[1], + "uuid": row[2], + "address": row[3], + "latitude": row[4], + "longitude": row[5], + "installed_capacity": row[6], + "microgrid_type": microgrid_type, + "microgrid_owner_type": microgrid_owner_type, + "is_input_counted": bool(row[9]), + "is_output_counted": bool(row[10]), + "contact": contact, + "cost_center": cost_center, + "description": row[13], + "qrcode": 'microgrid:' + row[2]} + result.append(meta_result) + + cursor.close() + cnx.close() + resp.text = json.dumps(result) + + @staticmethod + @user_logger + def on_post(req, resp): + """Handles POST requests""" + access_control(req) + try: + raw_json = req.stream.read().decode('utf-8') + except Exception as ex: + raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR', description=str(ex)) + + new_values = json.loads(raw_json) + + if 'name' not in new_values['data'].keys() or \ + not isinstance(new_values['data']['name'], str) or \ + len(str.strip(new_values['data']['name'])) == 0: + raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST', + description='API.INVALID_MICROGRID_NAME') + name = str.strip(new_values['data']['name']) + + if 'address' not in new_values['data'].keys() or \ + not isinstance(new_values['data']['address'], str) or \ + len(str.strip(new_values['data']['address'])) == 0: + raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST', + description='API.INVALID_ADDRESS_VALUE') + address = str.strip(new_values['data']['address']) + + if 'latitude' not in new_values['data'].keys() or \ + not (isinstance(new_values['data']['latitude'], float) or + isinstance(new_values['data']['latitude'], int)) or \ + new_values['data']['latitude'] < -90.0 or \ + new_values['data']['latitude'] > 90.0: + raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST', + description='API.INVALID_LATITUDE_VALUE') + latitude = new_values['data']['latitude'] + + if 'longitude' not in new_values['data'].keys() or \ + not (isinstance(new_values['data']['longitude'], float) or + isinstance(new_values['data']['longitude'], int)) or \ + new_values['data']['longitude'] < -180.0 or \ + new_values['data']['longitude'] > 180.0: + raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST', + description='API.INVALID_LONGITUDE_VALUE') + longitude = new_values['data']['longitude'] + + if 'capacity' not in new_values['data'].keys() or \ + not (isinstance(new_values['data']['capacity'], float) or + isinstance(new_values['data']['capacity'], int)) or \ + new_values['data']['capacity'] <= 0.0: + raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST', + description='API.INVALID_CAPACITY_VALUE') + capacity = new_values['data']['capacity'] + + if 'microgrid_type_id' not in new_values['data'].keys() or \ + not isinstance(new_values['data']['microgrid_type_id'], int) or \ + new_values['data']['microgrid_type_id'] <= 0: + raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST', + description='API.INVALID_MICROGRID_TYPE_ID') + microgrid_type_id = new_values['data']['microgrid_type_id'] + + if 'microgrid_owner_type_id' not in new_values['data'].keys() or \ + not isinstance(new_values['data']['microgrid_owner_type_id'], int) or \ + new_values['data']['microgrid_owner_type_id'] <= 0: + raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST', + description='API.INVALID_MICROGRID_OWNER_TYPE_ID') + microgrid_owner_type_id = new_values['data']['microgrid_owner_type_id'] + + if 'is_input_counted' not in new_values['data'].keys() or \ + not isinstance(new_values['data']['is_input_counted'], bool): + raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST', + description='API.INVALID_IS_INPUT_COUNTED_VALUE') + is_input_counted = new_values['data']['is_input_counted'] + + if 'is_output_counted' not in new_values['data'].keys() or \ + not isinstance(new_values['data']['is_output_counted'], bool): + raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST', + description='API.INVALID_IS_OUTPUT_COUNTED_VALUE') + is_output_counted = new_values['data']['is_output_counted'] + + if 'contact_id' not in new_values['data'].keys() or \ + not isinstance(new_values['data']['contact_id'], int) or \ + new_values['data']['contact_id'] <= 0: + raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST', + description='API.INVALID_CONTACT_ID') + contact_id = new_values['data']['contact_id'] + + if 'cost_center_id' not in new_values['data'].keys() or \ + not isinstance(new_values['data']['cost_center_id'], int) or \ + new_values['data']['cost_center_id'] <= 0: + raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST', + description='API.INVALID_COST_CENTER_ID') + cost_center_id = new_values['data']['cost_center_id'] + + if 'description' in new_values['data'].keys() and \ + new_values['data']['description'] is not None and \ + len(str(new_values['data']['description'])) > 0: + description = str.strip(new_values['data']['description']) + else: + description = None + + cnx = mysql.connector.connect(**config.myems_system_db) + cursor = cnx.cursor() + + cursor.execute(" SELECT name " + " FROM tbl_microgrids " + " WHERE name = %s ", (name,)) + if cursor.fetchone() is not None: + cursor.close() + cnx.close() + raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST', + description='API.MICROGRID_NAME_IS_ALREADY_IN_USE') + + cursor.execute(" SELECT name " + " FROM tbl_microgrid_types " + " WHERE id = %s ", + (microgrid_type_id,)) + if cursor.fetchone() is None: + cursor.close() + cnx.close() + raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND', + description='API.MICROGRID_TYPE_NOT_FOUND') + cursor.execute(" SELECT name " + " FROM tbl_microgrid_owner_types " + " WHERE id = %s ", + (microgrid_type_id,)) + if cursor.fetchone() is None: + cursor.close() + cnx.close() + raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND', + description='API.MICROGRID_OWNER_TYPE_NOT_FOUND') + + cursor.execute(" SELECT name " + " FROM tbl_contacts " + " WHERE id = %s ", + (new_values['data']['contact_id'],)) + row = cursor.fetchone() + if row is None: + cursor.close() + cnx.close() + raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND', + description='API.CONTACT_NOT_FOUND') + + cursor.execute(" SELECT name " + " FROM tbl_cost_centers " + " WHERE id = %s ", + (new_values['data']['cost_center_id'],)) + row = cursor.fetchone() + if row is None: + cursor.close() + cnx.close() + raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND', + description='API.COST_CENTER_NOT_FOUND') + + add_values = (" INSERT INTO tbl_microgrids " + " (name, uuid, address, latitude, longitude, capacity, " + " microgrid_type_id, microgrid_owner_type_id, " + " is_input_counted, is_output_counted, " + " contact_id, cost_center_id, description) " + " VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) ") + cursor.execute(add_values, (name, + str(uuid.uuid4()), + address, + latitude, + longitude, + capacity, + microgrid_type_id, + microgrid_owner_type_id, + is_input_counted, + is_output_counted, + contact_id, + cost_center_id, + description)) + new_id = cursor.lastrowid + cnx.commit() + cursor.close() + cnx.close() + + resp.status = falcon.HTTP_201 + resp.location = '/microgrids/' + str(new_id) + + +class MicrogridItem: + @staticmethod + def __init__(): + """"Initializes MicrogridItem""" + pass + + @staticmethod + def on_options(req, resp, id_): + resp.status = falcon.HTTP_200 + + @staticmethod + def on_get(req, resp, id_): + if not id_.isdigit() or int(id_) <= 0: + raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST', + description='API.INVALID_MICROGRID_ID') + + cnx = mysql.connector.connect(**config.myems_system_db) + cursor = cnx.cursor() + + query = (" SELECT id, name, uuid " + " FROM tbl_microgrid_types ") + cursor.execute(query) + rows_microgrid_types = cursor.fetchall() + + microgrid_type_dict = dict() + if rows_microgrid_types is not None and len(rows_microgrid_types) > 0: + for row in rows_microgrid_types: + microgrid_type_dict[row[0]] = {"id": row[0], + "name": row[1], + "uuid": row[2]} + query = (" SELECT id, name, uuid " + " FROM tbl_microgrid_owner_types ") + cursor.execute(query) + rows_microgrid_owner_types = cursor.fetchall() + + microgrid_owner_type_dict = dict() + if rows_microgrid_owner_types is not None and len(rows_microgrid_owner_types) > 0: + for row in rows_microgrid_owner_types: + microgrid_owner_type_dict[row[0]] = {"id": row[0], + "name": row[1], + "uuid": row[2]} + + query = (" SELECT id, name, uuid " + " FROM tbl_contacts ") + cursor.execute(query) + rows_contacts = cursor.fetchall() + + contact_dict = dict() + if rows_contacts is not None and len(rows_contacts) > 0: + for row in rows_contacts: + contact_dict[row[0]] = {"id": row[0], + "name": row[1], + "uuid": row[2]} + + query = (" SELECT id, name, uuid " + " FROM tbl_cost_centers ") + cursor.execute(query) + rows_cost_centers = cursor.fetchall() + + cost_center_dict = dict() + if rows_cost_centers is not None and len(rows_cost_centers) > 0: + for row in rows_cost_centers: + cost_center_dict[row[0]] = {"id": row[0], + "name": row[1], + "uuid": row[2]} + + query = (" SELECT id, name, uuid, " + " address, latitude, longitude, capacity, " + " microgrid_type_id, microgrid_owner_type_id, " + " is_input_counted, is_output_counted, " + " contact_id, cost_center_id, description " + " FROM tbl_microgrids " + " WHERE id = %s ") + cursor.execute(query, (id_,)) + row = cursor.fetchone() + cursor.close() + cnx.close() + + if row is None: + raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND', + description='API.MICROGRID_NOT_FOUND') + else: + microgrid_type = microgrid_type_dict.get(row[7], None) + microgrid_owner_type = microgrid_owner_type_dict.get(row[8], None) + contact = contact_dict.get(row[11], None) + cost_center = cost_center_dict.get(row[12], None) + meta_result = {"id": row[0], + "name": row[1], + "uuid": row[2], + "address": row[3], + "latitude": row[4], + "longitude": row[5], + "capacity": row[6], + "microgrid_type": microgrid_type, + "microgrid_owner_type": microgrid_owner_type, + "is_input_counted": bool(row[9]), + "is_output_counted": bool(row[10]), + "contact": contact, + "cost_center": cost_center, + "description": row[13], + "qrcode": 'microgrid:' + row[2]} + + resp.text = json.dumps(meta_result) + + @staticmethod + @user_logger + def on_delete(req, resp, id_): + access_control(req) + if not id_.isdigit() or int(id_) <= 0: + raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST', + description='API.INVALID_MICROGRID_ID') + + cnx = mysql.connector.connect(**config.myems_system_db) + cursor = cnx.cursor() + + cursor.execute(" SELECT name " + " FROM tbl_microgrids " + " WHERE id = %s ", (id_,)) + if cursor.fetchone() is None: + cursor.close() + cnx.close() + raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND', + description='API.MICROGRID_NOT_FOUND') + + # # check relation with space + # cursor.execute(" SELECT space_id " + # " FROM tbl_spaces_microgrids " + # " WHERE microgrid_id = %s ", + # (id_,)) + # rows_spaces = cursor.fetchall() + # if rows_spaces is not None and len(rows_spaces) > 0: + # cursor.close() + # cnx.close() + # raise falcon.HTTPError(status=falcon.HTTP_400, + # title='API.BAD_REQUEST', + # description='API.THERE_IS_RELATION_WITH_SPACES') + + # # check relation with meter + # cursor.execute(" SELECT meter_id " + # " FROM tbl_microgrids_meters " + # " WHERE microgrid_id = %s ", + # (id_,)) + # rows_meters = cursor.fetchall() + # if rows_meters is not None and len(rows_meters) > 0: + # cursor.close() + # cnx.close() + # raise falcon.HTTPError(status=falcon.HTTP_400, + # title='API.BAD_REQUEST', + # description='API.THERE_IS_RELATION_WITH_METERS') + + # check relation with sensor + cursor.execute(" SELECT sensor_id " + " FROM tbl_microgrids_sensors " + " WHERE microgrid_id = %s ", + (id_,)) + rows_sensors = cursor.fetchall() + if rows_sensors is not None and len(rows_sensors) > 0: + cursor.close() + cnx.close() + raise falcon.HTTPError(status=falcon.HTTP_400, + title='API.BAD_REQUEST', + description='API.THERE_IS_RELATION_WITH_SENSORS') + + cursor.close() + cnx.close() + + resp.status = falcon.HTTP_204 + + @staticmethod + @user_logger + def on_put(req, resp, id_): + """Handles PUT requests""" + access_control(req) + try: + raw_json = req.stream.read().decode('utf-8') + except Exception as ex: + raise falcon.HTTPError(status=falcon.HTTP_400, title='API.EXCEPTION', description=str(ex)) + + if not id_.isdigit() or int(id_) <= 0: + raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST', + description='API.INVALID_MICROGRID_ID') + + new_values = json.loads(raw_json) + + if 'name' not in new_values['data'].keys() or \ + not isinstance(new_values['data']['name'], str) or \ + len(str.strip(new_values['data']['name'])) == 0: + raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST', + description='API.INVALID_MICROGRID_NAME') + name = str.strip(new_values['data']['name']) + + if 'address' not in new_values['data'].keys() or \ + not isinstance(new_values['data']['address'], str) or \ + len(str.strip(new_values['data']['address'])) == 0: + raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST', + description='API.INVALID_ADDRESS_VALUE') + address = str.strip(new_values['data']['address']) + + if 'latitude' not in new_values['data'].keys() or \ + not (isinstance(new_values['data']['latitude'], float) or + isinstance(new_values['data']['latitude'], int)) or \ + new_values['data']['latitude'] < -90.0 or \ + new_values['data']['latitude'] > 90.0: + raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST', + description='API.INVALID_LATITUDE_VALUE') + latitude = new_values['data']['latitude'] + + if 'longitude' not in new_values['data'].keys() or \ + not (isinstance(new_values['data']['longitude'], float) or + isinstance(new_values['data']['longitude'], int)) or \ + new_values['data']['longitude'] < -180.0 or \ + new_values['data']['longitude'] > 180.0: + raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST', + description='API.INVALID_LONGITUDE_VALUE') + longitude = new_values['data']['longitude'] + + if 'capacity' not in new_values['data'].keys() or \ + not (isinstance(new_values['data']['capacity'], float) or + isinstance(new_values['data']['capacity'], int)) or \ + new_values['data']['capacity'] <= 0.0: + raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST', + description='API.INVALID_CAPACITY_VALUE') + capacity = new_values['data']['capacity'] + + if 'microgrid_type_id' not in new_values['data'].keys() or \ + not isinstance(new_values['data']['microgrid_type_id'], int) or \ + new_values['data']['microgrid_type_id'] <= 0: + raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST', + description='API.INVALID_MICROGRID_TYPE_ID') + microgrid_type_id = new_values['data']['microgrid_type_id'] + + if 'microgrid_owner_type_id' not in new_values['data'].keys() or \ + not isinstance(new_values['data']['microgrid_owner_type_id'], int) or \ + new_values['data']['microgrid_owner_type_id'] <= 0: + raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST', + description='API.INVALID_MICROGRID_OWNER_TYPE_ID') + microgrid_owner_type_id = new_values['data']['microgrid_owner_type_id'] + + if 'is_input_counted' not in new_values['data'].keys() or \ + not isinstance(new_values['data']['is_input_counted'], bool): + raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST', + description='API.INVALID_IS_INPUT_COUNTED_VALUE') + is_input_counted = new_values['data']['is_input_counted'] + + if 'is_output_counted' not in new_values['data'].keys() or \ + not isinstance(new_values['data']['is_output_counted'], bool): + raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST', + description='API.INVALID_IS_OUTPUT_COUNTED_VALUE') + is_output_counted = new_values['data']['is_output_counted'] + + if 'contact_id' not in new_values['data'].keys() or \ + not isinstance(new_values['data']['contact_id'], int) or \ + new_values['data']['contact_id'] <= 0: + raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST', + description='API.INVALID_CONTACT_ID') + contact_id = new_values['data']['contact_id'] + + if 'cost_center_id' not in new_values['data'].keys() or \ + not isinstance(new_values['data']['cost_center_id'], int) or \ + new_values['data']['cost_center_id'] <= 0: + raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST', + description='API.INVALID_COST_CENTER_ID') + cost_center_id = new_values['data']['cost_center_id'] + + if 'description' in new_values['data'].keys() and \ + new_values['data']['description'] is not None and \ + len(str(new_values['data']['description'])) > 0: + description = str.strip(new_values['data']['description']) + else: + description = None + + cnx = mysql.connector.connect(**config.myems_system_db) + cursor = cnx.cursor() + + cursor.execute(" SELECT name " + " FROM tbl_microgrids " + " WHERE id = %s ", (id_,)) + if cursor.fetchone() is None: + cursor.close() + cnx.close() + raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND', + description='API.MICROGRID_NOT_FOUND') + + cursor.execute(" SELECT name " + " FROM tbl_microgrids " + " WHERE name = %s AND id != %s ", (name, id_)) + if cursor.fetchone() is not None: + cursor.close() + cnx.close() + raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST', + description='API.MICROGRID_NAME_IS_ALREADY_IN_USE') + + cursor.execute(" SELECT name " + " FROM tbl_microgrid_types " + " WHERE id = %s ", + (microgrid_type_id,)) + if cursor.fetchone() is None: + cursor.close() + cnx.close() + raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND', + description='API.MICROGRID_TYPE_NOT_FOUND') + cursor.execute(" SELECT name " + " FROM tbl_microgrid_owner_types " + " WHERE id = %s ", + (microgrid_type_id,)) + if cursor.fetchone() is None: + cursor.close() + cnx.close() + raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND', + description='API.MICROGRID_OWNER_TYPE_NOT_FOUND') + + cursor.execute(" SELECT name " + " FROM tbl_contacts " + " WHERE id = %s ", + (new_values['data']['contact_id'],)) + row = cursor.fetchone() + if row is None: + cursor.close() + cnx.close() + raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND', + description='API.CONTACT_NOT_FOUND') + + cursor.execute(" SELECT name " + " FROM tbl_cost_centers " + " WHERE id = %s ", + (new_values['data']['cost_center_id'],)) + row = cursor.fetchone() + if row is None: + cursor.close() + cnx.close() + raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND', + description='API.COST_CENTER_NOT_FOUND') + + update_row = (" UPDATE tbl_microgrids " + " SET name = %s, address = %s, latitude = %s, longitude = %s, capacity = %s, " + " microgrid_type_id = %s, microgrid_owner_type_id = %s, " + " is_input_counted = %s, is_output_counted = %s, " + " contact_id = %s, cost_center_id = %s, " + " description = %s " + " WHERE id = %s ") + cursor.execute(update_row, (name, + address, + latitude, + longitude, + capacity, + microgrid_type_id, + microgrid_owner_type_id, + is_input_counted, + is_output_counted, + contact_id, + cost_center_id, + description, + id_)) + cnx.commit() + + cursor.close() + cnx.close() + + resp.status = falcon.HTTP_200 + + +class MicrogridSensorCollection: + @staticmethod + def __init__(): + """Initializes Class""" + pass + + @staticmethod + def on_options(req, resp, id_): + resp.status = falcon.HTTP_200 + + @staticmethod + def on_get(req, resp, id_): + if not id_.isdigit() or int(id_) <= 0: + raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST', + description='API.INVALID_MICROGRID_ID') + + cnx = mysql.connector.connect(**config.myems_system_db) + cursor = cnx.cursor() + + cursor.execute(" SELECT name " + " FROM tbl_microgrids " + " WHERE id = %s ", (id_,)) + if cursor.fetchone() is None: + cursor.close() + cnx.close() + raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND', + description='API.MICROGRID_NOT_FOUND') + + query = (" SELECT s.id, s.name, s.uuid " + " FROM tbl_microgrids m, tbl_microgrids_sensors ms, tbl_sensors s " + " WHERE ms.microgrid_id = m.id AND s.id = ms.sensor_id AND m.id = %s " + " ORDER BY s.id ") + cursor.execute(query, (id_,)) + rows = cursor.fetchall() + + result = list() + if rows is not None and len(rows) > 0: + for row in rows: + meta_result = {"id": row[0], "name": row[1], "uuid": row[2]} + result.append(meta_result) + + resp.text = json.dumps(result) + + @staticmethod + @user_logger + def on_post(req, resp, id_): + """Handles POST requests""" + access_control(req) + try: + raw_json = req.stream.read().decode('utf-8') + except Exception as ex: + raise falcon.HTTPError(status=falcon.HTTP_400, title='API.EXCEPTION', description=str(ex)) + + if not id_.isdigit() or int(id_) <= 0: + raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST', + description='API.INVALID_MICROGRID_ID') + + new_values = json.loads(raw_json) + + if 'sensor_id' not in new_values['data'].keys() or \ + not isinstance(new_values['data']['sensor_id'], int) or \ + new_values['data']['sensor_id'] <= 0: + raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST', + description='API.INVALID_SENSOR_ID') + sensor_id = new_values['data']['sensor_id'] + + cnx = mysql.connector.connect(**config.myems_system_db) + cursor = cnx.cursor() + + cursor.execute(" SELECT name " + " from tbl_microgrids " + " WHERE id = %s ", (id_,)) + if cursor.fetchone() is None: + cursor.close() + cnx.close() + raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND', + description='API.MICROGRID_NOT_FOUND') + + cursor.execute(" SELECT name " + " FROM tbl_sensors " + " WHERE id = %s ", (sensor_id,)) + if cursor.fetchone() is None: + cursor.close() + cnx.close() + raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND', + description='API.SENSOR_NOT_FOUND') + + query = (" SELECT id " + " FROM tbl_microgrids_sensors " + " WHERE microgrid_id = %s AND sensor_id = %s") + cursor.execute(query, (id_, sensor_id,)) + if cursor.fetchone() is not None: + cursor.close() + cnx.close() + raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR', + description='API.MICROGRID_SENSOR_RELATION_EXISTS') + + add_row = (" INSERT INTO tbl_microgrids_sensors (microgrid_id, sensor_id) " + " VALUES (%s, %s) ") + cursor.execute(add_row, (id_, sensor_id,)) + cnx.commit() + cursor.close() + cnx.close() + + resp.status = falcon.HTTP_201 + resp.location = '/microgrids/' + str(id_) + '/sensors/' + str(sensor_id) + + +class MicrogridSensorItem: + @staticmethod + def __init__(): + """Initializes Class""" + pass + + @staticmethod + def on_options(req, resp, id_, sid): + resp.status = falcon.HTTP_200 + + @staticmethod + @user_logger + def on_delete(req, resp, id_, sid): + access_control(req) + if not id_.isdigit() or int(id_) <= 0: + raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST', + description='API.INVALID_MICROGRID_ID') + + if not sid.isdigit() or int(sid) <= 0: + raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST', + description='API.INVALID_SENSOR_ID') + + cnx = mysql.connector.connect(**config.myems_system_db) + cursor = cnx.cursor() + + cursor.execute(" SELECT name " + " FROM tbl_microgrids " + " WHERE id = %s ", (id_,)) + if cursor.fetchone() is None: + cursor.close() + cnx.close() + raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND', + description='API.MICROGRID_NOT_FOUND') + + cursor.execute(" SELECT name " + " FROM tbl_sensors " + " WHERE id = %s ", (sid,)) + if cursor.fetchone() is None: + cursor.close() + cnx.close() + raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND', + description='API.SENSOR_NOT_FOUND') + + cursor.execute(" SELECT id " + " FROM tbl_microgrids_sensors " + " WHERE microgrid_id = %s AND sensor_id = %s ", (id_, sid)) + if cursor.fetchone() is None: + cursor.close() + cnx.close() + raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND', + description='API.MICROGRID_SENSOR_RELATION_NOT_FOUND') + + cursor.execute(" DELETE FROM tbl_microgrids_sensors WHERE microgrid_id = %s AND sensor_id = %s ", (id_, sid)) + cnx.commit() + + cursor.close() + cnx.close() + + resp.status = falcon.HTTP_204 +