reports.distributionsystem.Reporting.on_get()   F
last analyzed

Complexity

Conditions 26

Size

Total Lines 137
Code Lines 80

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 26
eloc 80
nop 2
dl 0
loc 137
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like reports.distributionsystem.Reporting.on_get() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

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, p.units "
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
                                                      "units": row['units'],
101
                                                      "value": None})
102
        if cursor_system:
103
            cursor_system.close()
104
        if cnx_system:
105
            cnx_system.disconnect()
106
        ################################################################################################################
107
        # Step 5: query points' data
108
        ################################################################################################################
109
        cnx_historical = mysql.connector.connect(**config.myems_historical_db)
110
        cursor_historical = cnx_historical.cursor()
111
112
        for x in range(len(circuit_list)):
113
            for y in range(len(circuit_list[x]['points'])):
114
                if circuit_list[x]['points'][y]['object_type'] == 'ANALOG_VALUE':
115
116
                    query = (" SELECT actual_value "
117
                             " FROM tbl_analog_value_latest "
118
                             " WHERE point_id = %s "
119
                             "       AND utc_date_time > %s ")
120
                    cursor_historical.execute(query, (circuit_list[x]['points'][y]['id'],
121
                                                      reporting_start_datetime_utc))
122
                    row = cursor_historical.fetchone()
123
124
                    if row is not None:
125
                        circuit_list[x]['points'][y]['value'] = row[0]
126
127
                elif circuit_list[x]['points'][y]['object_type'] == 'ENERGY_VALUE':
128
                    query = (" SELECT actual_value "
129
                             " FROM tbl_energy_value_latest "
130
                             " WHERE point_id = %s "
131
                             "       AND utc_date_time > %s ")
132
                    cursor_historical.execute(query, (circuit_list[x]['points'][y]['id'],
133
                                                      reporting_start_datetime_utc))
134
                    row = cursor_historical.fetchone()
135
136
                    if row is not None:
137
                        circuit_list[x]['points'][y]['value'] = row[0]
138
139
                elif circuit_list[x]['points'][y]['object_type'] == 'DIGITAL_VALUE':
140
                    query = (" SELECT actual_value "
141
                             " FROM tbl_digital_value_latest "
142
                             " WHERE point_id = %s "
143
                             "       AND utc_date_time > %s ")
144
                    cursor_historical.execute(query, (circuit_list[x]['points'][y]['id'],
145
                                                      reporting_start_datetime_utc))
146
                    row = cursor_historical.fetchone()
147
148
                    if row is not None:
149
                        circuit_list[x]['points'][y]['value'] = row[0]
150
151
        if cursor_historical:
152
            cursor_historical.close()
153
        if cnx_historical:
154
            cnx_historical.disconnect()
155
156
        ################################################################################################################
157
        # Step 6: construct the report
158
        ################################################################################################################
159
160
        result = circuit_list
161
162
        resp.body = json.dumps(result)
163