myems-api/reports/offlinemeterinput.py
import json
import config
import mysql.connector
from datetime import datetime, timedelta
from decimal import Decimal
import falcon
from core.useractivity import access_control, api_key_control
class Reporting:
def __init__(self):
pass
@staticmethod
def on_options(req, resp):
resp.status = falcon.HTTP_200
@staticmethod
def on_post(req, resp):
if 'API-KEY' not in req.headers or \
not isinstance(req.headers['API-KEY'], str) or \
len(str.strip(req.headers['API-KEY'])) == 0:
access_control(req)
else:
api_key_control(req)
cnx_energy = mysql.connector.connect(**config.myems_energy_db)
cursor_energy = cnx_energy.cursor()
timezone_offset = int(config.utc_offset[1:3]) * 60 + int(config.utc_offset[4:6])
if config.utc_offset[0] == '-':
timezone_offset = -timezone_offset
energy_data_list = list()
"""Handles POST requests"""
try:
raw_json = req.stream.read().decode('utf-8')
new_values = json.loads(raw_json)
formdata = new_values['value']
offline_meter_data = dict()
offline_meter_data['offline_meter_id'] = new_values['meter']
offline_meter_data['data'] = dict()
for onepieces in formdata:
start_datetime_local = datetime(year=int(onepieces[0][0:4]),
month=int(onepieces[0][5:7]),
day=int(onepieces[0][8:10]))
start_datetime_utc = start_datetime_local - timedelta(minutes=timezone_offset)
if onepieces[1] is None or \
onepieces[1] == '' or \
float(onepieces[1]) < 0:
raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_OFFLINE_METER_VALUE')
offline_meter_data['data'][start_datetime_utc] = Decimal(onepieces[1])
if len(offline_meter_data['data']) > 0:
energy_data_list.append(offline_meter_data)
except Exception as ex:
raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_OFFLINE_METER_VALUE')
for energy_data_item in energy_data_list:
offline_meter_id = energy_data_item['offline_meter_id']
cnx_system = mysql.connector.connect(**config.myems_system_db)
cursor_system = cnx_system.cursor()
cursor_system.execute(" SELECT hourly_low_limit, hourly_high_limit "
" FROM tbl_offline_meters "
" WHERE id = %s ", (offline_meter_id,))
row_meter = cursor_system.fetchone()
if row_meter is None:
raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
description='API.OFFLINE_METER_NOT_FOUND')
hourly_low_limit = row_meter[0] if row_meter[0] is not None else 0
hourly_high_limit = row_meter[1] if row_meter[1] is not None else 0
if cursor_system:
cursor_system.close()
if cnx_system:
cnx_system.disconnect()
for start_datetime_utc, daily_value in energy_data_item['data'].items():
end_datetime_utc = start_datetime_utc + timedelta(hours=24)
actual_value = \
round(daily_value / (Decimal(24) * Decimal(60) / Decimal(config.minutes_to_count)), 3)
cursor_energy.execute("DELETE FROM tbl_offline_meter_hourly WHERE offline_meter_id = %s "
"AND start_datetime_utc >= %s AND start_datetime_utc < %s ",
(offline_meter_id, start_datetime_utc.isoformat()[0:19],
end_datetime_utc.isoformat()[0:19]))
cnx_energy.commit()
# check with hourly low limit and hourly high limit
if actual_value < hourly_low_limit \
or actual_value > hourly_high_limit:
raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_OFFLINE_METER_VALUE')
add_values = (" INSERT INTO tbl_offline_meter_hourly "
" (offline_meter_id, start_datetime_utc, actual_value) "
" VALUES ")
sum_24hours = actual_value * 24
last_date_utc = end_datetime_utc - timedelta(minutes=config.minutes_to_count)
while start_datetime_utc < end_datetime_utc:
if start_datetime_utc == last_date_utc and sum_24hours != daily_value:
actual_value = daily_value - sum_24hours + actual_value
add_values += " (" + str(offline_meter_id) + ","
add_values += "'" + start_datetime_utc.isoformat()[0:19] + "',"
add_values += str(actual_value) + "), "
start_datetime_utc += timedelta(minutes=config.minutes_to_count)
# trim ", " at the end of string and then execute
cursor_energy.execute(add_values[:-2])
cnx_energy.commit()
if cursor_energy:
cursor_energy.close()
if cnx_energy:
cnx_energy.close()
resp.text = json.dumps({})