Passed
Push — master ( 72d593...a065be )
by Guangyu
01:55 queued 11s
created

reports.distributionsystem   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 162
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 92
dl 0
loc 162
rs 10
c 0
b 0
f 0
wmc 28

3 Methods

Rating   Name   Duplication   Size   Complexity  
A Reporting.__init__() 0 3 1
F Reporting.on_get() 0 136 26
A Reporting.on_options() 0 3 1
1
import falcon
2
import simplejson as json
3
import mysql.connector
4
import config
5
from datetime import datetime, timedelta, timezone
6
7
8
class Reporting:
9
    @staticmethod
10
    def __init__():
11
        pass
12
13
    @staticmethod
14
    def on_options(req, resp):
15
        resp.status = falcon.HTTP_200
16
17
    ####################################################################################################################
18
    # PROCEDURES
19
    # Step 1: valid parameters
20
    # Step 2: query the distribution system
21
    # Step 3: query associated circuits
22
    # Step 4: query circuits' associated points
23
    # Step 5: query points' latest values
24
    # Step 6: construct the report
25
    ####################################################################################################################
26
    @staticmethod
27
    def on_get(req, resp):
28
        print(req.params)
29
        distribution_system_id = req.params.get('distributionsystemid')
30
31
        ################################################################################################################
32
        # Step 1: valid parameters
33
        ################################################################################################################
34
        if distribution_system_id is None:
35
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
36
                                   description='API.INVALID_DISTRIBUTION_SYSTEM_ID')
37
        else:
38
            distribution_system_id = str.strip(distribution_system_id)
39
            if not distribution_system_id.isdigit() or int(distribution_system_id) <= 0:
40
                raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
41
                                       description='API.INVALID_DISTRIBUTION_SYSTEM_ID')
42
        # set the earliest datetime of valid actual value
43
        # if the utc_date_time is less than reporting_start_datetime_utc, then the value is None because of timeout
44
        reporting_start_datetime_utc = datetime.utcnow() - timedelta(minutes=5)
45
46
        ################################################################################################################
47
        # Step 2: Step 2: query the distribution system
48
        ################################################################################################################
49
        cnx_system = mysql.connector.connect(**config.myems_system_db)
50
        cursor_system = cnx_system.cursor(dictionary=True)
51
52
        cursor_system.execute(" SELECT name "
53
                              " FROM tbl_distribution_systems "
54
                              " WHERE id = %s ", (distribution_system_id,))
55
        if cursor_system.fetchone() is None:
56
            if cursor_system:
57
                cursor_system.close()
58
            if cnx_system:
59
                cnx_system.disconnect()
60
            raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
61
                                   description='API.DISTRIBUTION_SYSTEM_NOT_FOUND')
62
63
        ################################################################################################################
64
        # Step 3: query associated circuits
65
        ################################################################################################################
66
        query = (" SELECT id, name, uuid, "
67
                 "        distribution_room, switchgear, peak_load, peak_current, customers, meters "
68
                 " FROM tbl_distribution_circuits "
69
                 " WHERE distribution_system_id = %s "
70
                 " ORDER BY name ")
71
        cursor_system.execute(query, (distribution_system_id,))
72
        rows = cursor_system.fetchall()
73
74
        circuit_list = list()
75
        if rows is not None and len(rows) > 0:
76
            for row in rows:
77
                circuit_list.append({"id": row['id'], "name": row['name'], "uuid": row['uuid'],
78
                                     "distribution_room": row['distribution_room'], "switchgear": row['switchgear'],
79
                                     "peak_load": row['peak_load'], "peak_current": row['peak_current'],
80
                                     "customers": row['customers'], "meters": row['meters'],
81
                                     "points": list()})
82
83
        ################################################################################################################
84
        # Step 4: query circuits' associated points
85
        ################################################################################################################
86
        for x in range(len(circuit_list)):
87
            query = (" SELECT p.id, p.name, p.object_type "
88
                     " FROM tbl_points p, tbl_distribution_circuits_points dcp, tbl_distribution_circuits dc "
89
                     " WHERE dcp.distribution_circuit_id = %s AND p.id = dcp.point_id "
90
                     "       AND dcp.distribution_circuit_id = dc.id "
91
                     " ORDER BY p.name ")
92
            cursor_system.execute(query, (circuit_list[x]['id'],))
93
            rows = cursor_system.fetchall()
94
95
            if rows is not None and len(rows) > 0:
96
                for row in rows:
97
                    circuit_list[x]['points'].append({"id": row['id'],
98
                                                      "name": row['name'],
99
                                                      "object_type": row['object_type'],
100
                                                      "value": None})
101
        if cursor_system:
102
            cursor_system.close()
103
        if cnx_system:
104
            cnx_system.disconnect()
105
        ################################################################################################################
106
        # Step 5: query points' data
107
        ################################################################################################################
108
        cnx_historical = mysql.connector.connect(**config.myems_historical_db)
109
        cursor_historical = cnx_historical.cursor()
110
111
        for x in range(len(circuit_list)):
112
            for y in range(len(circuit_list[x]['points'])):
113
                if circuit_list[x]['points'][y]['object_type'] == 'ANALOG_VALUE':
114
115
                    query = (" SELECT actual_value "
116
                             " FROM tbl_analog_value_latest "
117
                             " WHERE point_id = %s "
118
                             "       AND utc_date_time > %s ")
119
                    cursor_historical.execute(query, (circuit_list[x]['points'][y]['id'],
120
                                                      reporting_start_datetime_utc))
121
                    row = cursor_historical.fetchone()
122
123
                    if row is not None:
124
                        circuit_list[x]['points'][y]['value'] = row[0]
125
126
                elif circuit_list[x]['points'][y]['object_type'] == 'ENERGY_VALUE':
127
                    query = (" SELECT actual_value "
128
                             " FROM tbl_energy_value_latest "
129
                             " WHERE point_id = %s "
130
                             "       AND utc_date_time > %s ")
131
                    cursor_historical.execute(query, (circuit_list[x]['points'][y]['id'],
132
                                                      reporting_start_datetime_utc))
133
                    row = cursor_historical.fetchone()
134
135
                    if row is not None:
136
                        circuit_list[x]['points'][y]['value'] = row[0]
137
138
                elif circuit_list[x]['points'][y]['object_type'] == 'DIGITAL_VALUE':
139
                    query = (" SELECT actual_value "
140
                             " FROM tbl_digital_value_latest "
141
                             " WHERE point_id = %s "
142
                             "       AND utc_date_time > %s ")
143
                    cursor_historical.execute(query, (circuit_list[x]['points'][y]['id'],
144
                                                      reporting_start_datetime_utc))
145
                    row = cursor_historical.fetchone()
146
147
                    if row is not None:
148
                        circuit_list[x]['points'][y]['value'] = row[0]
149
150
        if cursor_historical:
151
            cursor_historical.close()
152
        if cnx_historical:
153
            cnx_historical.disconnect()
154
155
        ################################################################################################################
156
        # Step 6: construct the report
157
        ################################################################################################################
158
159
        result = circuit_list
160
161
        resp.body = json.dumps(result)
162