Code Duplication    Length = 243-245 lines in 6 locations

myems-aggregation/meter_billing.py 1 location

@@ 23-267 (lines=245) @@
20
########################################################################################################################
21
22
23
def main(logger):
24
25
    while True:
26
        # the outermost while loop
27
        ################################################################################################################
28
        # Step 1: get all meters
29
        ################################################################################################################
30
        cnx_system_db = None
31
        cursor_system_db = None
32
        try:
33
            cnx_system_db = mysql.connector.connect(**config.myems_system_db)
34
            cursor_system_db = cnx_system_db.cursor()
35
        except Exception as e:
36
            logger.error("Error in step 1.1 of meter_billing " + str(e))
37
            if cursor_system_db:
38
                cursor_system_db.close()
39
            if cnx_system_db:
40
                cnx_system_db.close()
41
            # sleep and continue the outermost while loop
42
            time.sleep(60)
43
            continue
44
45
        print("Connected to MyEMS System Database")
46
47
        meter_list = list()
48
        try:
49
            cursor_system_db.execute(" SELECT id, name, energy_category_id, cost_center_id "
50
                                     " FROM tbl_meters "
51
                                     " ORDER BY id ")
52
            rows_meters = cursor_system_db.fetchall()
53
54
            if rows_meters is None or len(rows_meters) == 0:
55
                print("Step 1.2: There isn't any meters. ")
56
                if cursor_system_db:
57
                    cursor_system_db.close()
58
                if cnx_system_db:
59
                    cnx_system_db.close()
60
                # sleep and continue the outermost while loop
61
                time.sleep(60)
62
                continue
63
64
            for row in rows_meters:
65
                meter_list.append({"id": row[0],
66
                                   "name": row[1],
67
                                   "energy_category_id": row[2],
68
                                   "cost_center_id": row[3]})
69
70
        except Exception as e:
71
            logger.error("Error in step 1.2 of meter_billing " + str(e))
72
            if cursor_system_db:
73
                cursor_system_db.close()
74
            if cnx_system_db:
75
                cnx_system_db.close()
76
            # sleep and continue the outermost while loop
77
            time.sleep(60)
78
            continue
79
80
        print("Step 1.2: Got all meters from MyEMS System Database")
81
82
        cnx_energy_db = None
83
        cursor_energy_db = None
84
        try:
85
            cnx_energy_db = mysql.connector.connect(**config.myems_energy_db)
86
            cursor_energy_db = cnx_energy_db.cursor()
87
        except Exception as e:
88
            logger.error("Error in step 1.3 of meter_billing " + str(e))
89
            if cursor_energy_db:
90
                cursor_energy_db.close()
91
            if cnx_energy_db:
92
                cnx_energy_db.close()
93
94
            if cursor_system_db:
95
                cursor_system_db.close()
96
            if cnx_system_db:
97
                cnx_system_db.close()
98
            # sleep and continue the outermost while loop
99
            time.sleep(60)
100
            continue
101
102
        print("Connected to MyEMS Energy Database")
103
104
        cnx_billing_db = None
105
        cursor_billing_db = None
106
        try:
107
            cnx_billing_db = mysql.connector.connect(**config.myems_billing_db)
108
            cursor_billing_db = cnx_billing_db.cursor()
109
        except Exception as e:
110
            logger.error("Error in step 1.4 of meter_billing " + str(e))
111
            if cursor_billing_db:
112
                cursor_billing_db.close()
113
            if cnx_billing_db:
114
                cnx_billing_db.close()
115
116
            if cursor_energy_db:
117
                cursor_energy_db.close()
118
            if cnx_energy_db:
119
                cnx_energy_db.close()
120
121
            if cursor_system_db:
122
                cursor_system_db.close()
123
            if cnx_system_db:
124
                cnx_system_db.close()
125
            # sleep and continue the outermost while loop
126
            time.sleep(60)
127
            continue
128
129
        print("Connected to MyEMS Billing Database")
130
131
        for meter in meter_list:
132
133
            ############################################################################################################
134
            # Step 2: get the latest start_datetime_utc
135
            ############################################################################################################
136
            print("Step 2: get the latest start_datetime_utc from billing database for " + meter['name'])
137
            try:
138
                cursor_billing_db.execute(" SELECT MAX(start_datetime_utc) "
139
                                          " FROM tbl_meter_hourly "
140
                                          " WHERE meter_id = %s ",
141
                                          (meter['id'], ))
142
                row_datetime = cursor_billing_db.fetchone()
143
                start_datetime_utc = datetime.strptime(config.start_datetime_utc, '%Y-%m-%d %H:%M:%S')
144
                start_datetime_utc = start_datetime_utc.replace(minute=0, second=0, microsecond=0, tzinfo=None)
145
146
                if row_datetime is not None and len(row_datetime) > 0 and isinstance(row_datetime[0], datetime):
147
                    # replace second and microsecond with 0
148
                    # note: do not replace minute in case of calculating in half hourly
149
                    start_datetime_utc = row_datetime[0].replace(second=0, microsecond=0, tzinfo=None)
150
                    # start from the next time slot
151
                    start_datetime_utc += timedelta(minutes=config.minutes_to_count)
152
153
                print("start_datetime_utc: " + start_datetime_utc.isoformat()[0:19])
154
            except Exception as e:
155
                logger.error("Error in step 2 of meter_billing " + str(e))
156
                # break the for meter loop
157
                break
158
159
            ############################################################################################################
160
            # Step 3: get all energy data since the latest start_datetime_utc
161
            ############################################################################################################
162
            print("Step 3: get all energy data since the latest start_datetime_utc")
163
            try:
164
                query = (" SELECT start_datetime_utc, actual_value "
165
                         " FROM tbl_meter_hourly "
166
                         " WHERE meter_id = %s AND start_datetime_utc >= %s "
167
                         " ORDER BY id ")
168
                cursor_energy_db.execute(query, (meter['id'], start_datetime_utc, ))
169
                rows_hourly = cursor_energy_db.fetchall()
170
171
                if rows_hourly is None or len(rows_hourly) == 0:
172
                    print("Step 3: There isn't any energy input data to calculate. ")
173
                    # continue the for meter loop
174
                    continue
175
176
                energy_dict = dict()
177
                end_datetime_utc = start_datetime_utc
178
                for row_hourly in rows_hourly:
179
                    current_datetime_utc = row_hourly[0]
180
                    actual_value = row_hourly[1]
181
                    if energy_dict.get(current_datetime_utc) is None:
182
                        energy_dict[current_datetime_utc] = dict()
183
                    energy_dict[current_datetime_utc][meter['energy_category_id']] = actual_value
184
                    if current_datetime_utc > end_datetime_utc:
185
                        end_datetime_utc = current_datetime_utc
186
            except Exception as e:
187
                logger.error("Error in step 3 of meter_billing " + str(e))
188
                # break the for meter loop
189
                break
190
191
            ############################################################################################################
192
            # Step 4: get tariffs
193
            ############################################################################################################
194
            print("Step 4: get tariffs")
195
            tariff_dict = dict()
196
            tariff_dict[meter['energy_category_id']] = \
197
                tariff.get_energy_category_tariffs(meter['cost_center_id'],
198
                                                   meter['energy_category_id'],
199
                                                   start_datetime_utc,
200
                                                   end_datetime_utc)
201
            ############################################################################################################
202
            # Step 5: calculate billing by multiplying energy with tariff
203
            ############################################################################################################
204
            print("Step 5: calculate billing by multiplying energy with tariff")
205
            aggregated_values = list()
206
207
            if len(energy_dict) > 0:
208
                for current_datetime_utc in energy_dict.keys():
209
                    aggregated_value = dict()
210
                    aggregated_value['start_datetime_utc'] = current_datetime_utc
211
                    aggregated_value['actual_value'] = None
212
                    current_tariff = tariff_dict[meter['energy_category_id']].get(current_datetime_utc)
213
                    current_energy = energy_dict[current_datetime_utc].get(meter['energy_category_id'])
214
                    if current_tariff is not None \
215
                            and isinstance(current_tariff, Decimal) \
216
                            and current_energy is not None \
217
                            and isinstance(current_energy, Decimal):
218
                        aggregated_value['actual_value'] = current_energy * current_tariff
219
                        aggregated_values.append(aggregated_value)
220
221
            ############################################################################################################
222
            # Step 6: save billing data to billing database
223
            ############################################################################################################
224
            print("Step 6: save billing data to billing database")
225
226
            while len(aggregated_values) > 0:
227
                insert_100 = aggregated_values[:100]
228
                aggregated_values = aggregated_values[100:]
229
                try:
230
                    add_values = (" INSERT INTO tbl_meter_hourly "
231
                                  "             (meter_id, "
232
                                  "              start_datetime_utc, "
233
                                  "              actual_value) "
234
                                  " VALUES  ")
235
236
                    for aggregated_value in insert_100:
237
                        if aggregated_value['actual_value'] is not None and \
238
                                isinstance(aggregated_value['actual_value'], Decimal):
239
                            add_values += " (" + str(meter['id']) + ","
240
                            add_values += "'" + aggregated_value['start_datetime_utc'].isoformat()[0:19] + "',"
241
                            add_values += str(aggregated_value['actual_value']) + "), "
242
                    # trim ", " at the end of string and then execute
243
                    cursor_billing_db.execute(add_values[:-2])
244
                    cnx_billing_db.commit()
245
                except Exception as e:
246
                    logger.error("Error in step 6 of meter_billing " + str(e))
247
                    # break the for meter loop
248
                    break
249
250
        # end of for meter loop
251
        if cursor_system_db:
252
            cursor_system_db.close()
253
        if cnx_system_db:
254
            cnx_system_db.close()
255
256
        if cursor_energy_db:
257
            cursor_energy_db.close()
258
        if cnx_energy_db:
259
            cnx_energy_db.close()
260
261
        if cursor_billing_db:
262
            cursor_billing_db.close()
263
        if cnx_billing_db:
264
            cnx_billing_db.close()
265
        print("go to sleep 300 seconds...")
266
        time.sleep(300)
267
        print("wake from sleep, and continue to work...")
268
    # end of the outermost while loop
269

myems-aggregation/virtual_meter_billing.py 1 location

@@ 23-266 (lines=244) @@
20
########################################################################################################################
21
22
23
def main(logger):
24
25
    while True:
26
        # the outermost while loop
27
        ################################################################################################################
28
        # Step 1: get all virtual meters
29
        ################################################################################################################
30
        cnx_system_db = None
31
        cursor_system_db = None
32
        try:
33
            cnx_system_db = mysql.connector.connect(**config.myems_system_db)
34
            cursor_system_db = cnx_system_db.cursor()
35
        except Exception as e:
36
            logger.error("Error in step 1.1 of meter_billing " + str(e))
37
            if cursor_system_db:
38
                cursor_system_db.close()
39
            if cnx_system_db:
40
                cnx_system_db.close()
41
            # sleep and continue the outermost while loop
42
            time.sleep(60)
43
            continue
44
45
        print("Connected to MyEMS System Database")
46
47
        virtual_meter_list = list()
48
        try:
49
            cursor_system_db.execute(" SELECT id, name, energy_category_id, cost_center_id "
50
                                     " FROM tbl_virtual_meters "
51
                                     " ORDER BY id ")
52
            rows_virtual_meters = cursor_system_db.fetchall()
53
54
            if rows_virtual_meters is None or len(rows_virtual_meters) == 0:
55
                print("Step 1.2: There isn't any virtual meters ")
56
                if cursor_system_db:
57
                    cursor_system_db.close()
58
                if cnx_system_db:
59
                    cnx_system_db.close()
60
                # sleep and continue the outermost while loop
61
                time.sleep(60)
62
                continue
63
64
            for row in rows_virtual_meters:
65
                virtual_meter_list.append({"id": row[0],
66
                                           "name": row[1],
67
                                           "energy_category_id": row[2],
68
                                           "cost_center_id": row[3]})
69
70
        except Exception as e:
71
            logger.error("Error in step 1.2 of virtual_meter_billing " + str(e))
72
            if cursor_system_db:
73
                cursor_system_db.close()
74
            if cnx_system_db:
75
                cnx_system_db.close()
76
            # sleep and continue the outermost while loop
77
            time.sleep(60)
78
            continue
79
80
        print("Step 1.2: Got all virtual meters from MyEMS System Database")
81
82
        cnx_energy_db = None
83
        cursor_energy_db = None
84
        try:
85
            cnx_energy_db = mysql.connector.connect(**config.myems_energy_db)
86
            cursor_energy_db = cnx_energy_db.cursor()
87
        except Exception as e:
88
            logger.error("Error in step 1.3 of virtual_meter_billing " + str(e))
89
            if cursor_energy_db:
90
                cursor_energy_db.close()
91
            if cnx_energy_db:
92
                cnx_energy_db.close()
93
94
            if cursor_system_db:
95
                cursor_system_db.close()
96
            if cnx_system_db:
97
                cnx_system_db.close()
98
            # sleep and continue the outermost while loop
99
            time.sleep(60)
100
            continue
101
102
        print("Connected to MyEMS Energy Database")
103
104
        cnx_billing_db = None
105
        cursor_billing_db = None
106
        try:
107
            cnx_billing_db = mysql.connector.connect(**config.myems_billing_db)
108
            cursor_billing_db = cnx_billing_db.cursor()
109
        except Exception as e:
110
            logger.error("Error in step 1.4 of virtual_meter_billing " + str(e))
111
            if cursor_billing_db:
112
                cursor_billing_db.close()
113
            if cnx_billing_db:
114
                cnx_billing_db.close()
115
116
            if cursor_energy_db:
117
                cursor_energy_db.close()
118
            if cnx_energy_db:
119
                cnx_energy_db.close()
120
121
            if cursor_system_db:
122
                cursor_system_db.close()
123
            if cnx_system_db:
124
                cnx_system_db.close()
125
            # sleep and continue the outermost while loop
126
            time.sleep(60)
127
            continue
128
129
        print("Connected to MyEMS Billing Database")
130
131
        for virtual_meter in virtual_meter_list:
132
133
            ############################################################################################################
134
            # Step 2: get the latest start_datetime_utc
135
            ############################################################################################################
136
            print("Step 2: get the latest start_datetime_utc from billing database for " + virtual_meter['name'])
137
            try:
138
                cursor_billing_db.execute(" SELECT MAX(start_datetime_utc) "
139
                                          " FROM tbl_virtual_meter_hourly "
140
                                          " WHERE virtual_meter_id = %s ",
141
                                          (virtual_meter['id'], ))
142
                row_datetime = cursor_billing_db.fetchone()
143
                start_datetime_utc = datetime.strptime(config.start_datetime_utc, '%Y-%m-%d %H:%M:%S')
144
                start_datetime_utc = start_datetime_utc.replace(minute=0, second=0, microsecond=0, tzinfo=None)
145
146
                if row_datetime is not None and len(row_datetime) > 0 and isinstance(row_datetime[0], datetime):
147
                    # replace second and microsecond with 0
148
                    # note: do not replace minute in case of calculating in half hourly
149
                    start_datetime_utc = row_datetime[0].replace(second=0, microsecond=0, tzinfo=None)
150
                    # start from the next time slot
151
                    start_datetime_utc += timedelta(minutes=config.minutes_to_count)
152
153
                print("start_datetime_utc: " + start_datetime_utc.isoformat()[0:19])
154
            except Exception as e:
155
                logger.error("Error in step 2 of virtual_meter_billing " + str(e))
156
                # break the for virtual_meter loop
157
                break
158
159
            ############################################################################################################
160
            # Step 3: get all energy data since the latest start_datetime_utc
161
            ############################################################################################################
162
            print("Step 3: get all energy data since the latest start_datetime_utc")
163
            try:
164
                query = (" SELECT start_datetime_utc, actual_value "
165
                         " FROM tbl_virtual_meter_hourly "
166
                         " WHERE virtual_meter_id = %s AND start_datetime_utc >= %s "
167
                         " ORDER BY id ")
168
                cursor_energy_db.execute(query, (virtual_meter['id'], start_datetime_utc, ))
169
                rows_hourly = cursor_energy_db.fetchall()
170
171
                if rows_hourly is None or len(rows_hourly) == 0:
172
                    print("Step 3: There isn't any energy input data to calculate. ")
173
                    # continue the for virtual_meter loop
174
                    continue
175
176
                energy_dict = dict()
177
                end_datetime_utc = start_datetime_utc
178
                for row_hourly in rows_hourly:
179
                    current_datetime_utc = row_hourly[0]
180
                    actual_value = row_hourly[1]
181
                    if energy_dict.get(current_datetime_utc) is None:
182
                        energy_dict[current_datetime_utc] = dict()
183
                    energy_dict[current_datetime_utc][virtual_meter['energy_category_id']] = actual_value
184
                    if current_datetime_utc > end_datetime_utc:
185
                        end_datetime_utc = current_datetime_utc
186
            except Exception as e:
187
                logger.error("Error in step 3 of virtual_meter_billing " + str(e))
188
                # break the for virtual_meter loop
189
                break
190
191
            ############################################################################################################
192
            # Step 4: get tariffs
193
            ############################################################################################################
194
            print("Step 4: get tariffs")
195
            tariff_dict = dict()
196
            tariff_dict[virtual_meter['energy_category_id']] = \
197
                tariff.get_energy_category_tariffs(virtual_meter['cost_center_id'],
198
                                                   virtual_meter['energy_category_id'],
199
                                                   start_datetime_utc,
200
                                                   end_datetime_utc)
201
            ############################################################################################################
202
            # Step 5: calculate billing by multiplying energy with tariff
203
            ############################################################################################################
204
            print("Step 5: calculate billing by multiplying energy with tariff")
205
            aggregated_values = list()
206
207
            if len(energy_dict) > 0:
208
                for current_datetime_utc in energy_dict.keys():
209
                    aggregated_value = dict()
210
                    aggregated_value['start_datetime_utc'] = current_datetime_utc
211
                    aggregated_value['actual_value'] = None
212
                    current_tariff = tariff_dict[virtual_meter['energy_category_id']].get(current_datetime_utc)
213
                    current_energy = energy_dict[current_datetime_utc].get(virtual_meter['energy_category_id'])
214
                    if current_tariff is not None \
215
                            and isinstance(current_tariff, Decimal) \
216
                            and current_energy is not None \
217
                            and isinstance(current_energy, Decimal):
218
                        aggregated_value['actual_value'] = current_energy * current_tariff
219
                        aggregated_values.append(aggregated_value)
220
221
            ############################################################################################################
222
            # Step 6: save billing data to billing database
223
            ############################################################################################################
224
            print("Step 6: save billing data to billing database")
225
226
            while len(aggregated_values) > 0:
227
                insert_100 = aggregated_values[:100]
228
                aggregated_values = aggregated_values[100:]
229
                try:
230
                    add_values = (" INSERT INTO tbl_virtual_meter_hourly "
231
                                  "             (virtual_meter_id, "
232
                                  "              start_datetime_utc, "
233
                                  "              actual_value) "
234
                                  " VALUES  ")
235
236
                    for aggregated_value in insert_100:
237
                        if aggregated_value['actual_value'] is not None and \
238
                                isinstance(aggregated_value['actual_value'], Decimal):
239
                            add_values += " (" + str(virtual_meter['id']) + ","
240
                            add_values += "'" + aggregated_value['start_datetime_utc'].isoformat()[0:19] + "',"
241
                            add_values += str(aggregated_value['actual_value']) + "), "
242
                    # trim ", " at the end of string and then execute
243
                    cursor_billing_db.execute(add_values[:-2])
244
                    cnx_billing_db.commit()
245
                except Exception as e:
246
                    logger.error("Error in step 6 of virtual_meter_billing " + str(e))
247
                    break
248
249
        # end of for virtual_meter loop
250
        if cursor_system_db:
251
            cursor_system_db.close()
252
        if cnx_system_db:
253
            cnx_system_db.close()
254
255
        if cursor_energy_db:
256
            cursor_energy_db.close()
257
        if cnx_energy_db:
258
            cnx_energy_db.close()
259
260
        if cursor_billing_db:
261
            cursor_billing_db.close()
262
        if cnx_billing_db:
263
            cnx_billing_db.close()
264
        print("go to sleep 300 seconds...")
265
        time.sleep(300)
266
        print("wake from sleep, and continue to work...")
267
    # end of the outermost while loop
268

myems-aggregation/offline_meter_carbon.py 1 location

@@ 23-265 (lines=243) @@
20
########################################################################################################################
21
22
23
def main(logger):
24
25
    while True:
26
        # the outermost while loop
27
        ################################################################################################################
28
        # Step 1: get all offline meters
29
        ################################################################################################################
30
        cnx_system_db = None
31
        cursor_system_db = None
32
        try:
33
            cnx_system_db = mysql.connector.connect(**config.myems_system_db)
34
            cursor_system_db = cnx_system_db.cursor()
35
        except Exception as e:
36
            logger.error("Error in step 1.1 of offline_meter_carbon " + str(e))
37
            if cursor_system_db:
38
                cursor_system_db.close()
39
            if cnx_system_db:
40
                cnx_system_db.close()
41
            # sleep and continue the outermost while loop
42
            time.sleep(60)
43
            continue
44
45
        print("Connected to MyEMS System Database")
46
47
        offline_meter_list = list()
48
        try:
49
            cursor_system_db.execute(" SELECT id, name, energy_category_id, cost_center_id "
50
                                     " FROM tbl_offline_meters "
51
                                     " ORDER BY id ")
52
            rows_offline_meters = cursor_system_db.fetchall()
53
54
            if rows_offline_meters is None or len(rows_offline_meters) == 0:
55
                print("Step 1.2: There isn't any offline meters. ")
56
                if cursor_system_db:
57
                    cursor_system_db.close()
58
                if cnx_system_db:
59
                    cnx_system_db.close()
60
                # sleep and continue the outermost while loop
61
                time.sleep(60)
62
                continue
63
64
            for row in rows_offline_meters:
65
                offline_meter_list.append({"id": row[0],
66
                                           "name": row[1],
67
                                           "energy_category_id": row[2],
68
                                           "cost_center_id": row[3]})
69
70
        except Exception as e:
71
            logger.error("Error in step 1.2 of offline_meter_carbon " + str(e))
72
            if cursor_system_db:
73
                cursor_system_db.close()
74
            if cnx_system_db:
75
                cnx_system_db.close()
76
            # sleep and continue the outermost while loop
77
            time.sleep(60)
78
            continue
79
80
        print("Step 1.2: Got all offline meters from MyEMS System Database")
81
82
        cnx_energy_db = None
83
        cursor_energy_db = None
84
        try:
85
            cnx_energy_db = mysql.connector.connect(**config.myems_energy_db)
86
            cursor_energy_db = cnx_energy_db.cursor()
87
        except Exception as e:
88
            logger.error("Error in step 1.3 of offline_meter_carbon " + str(e))
89
            if cursor_energy_db:
90
                cursor_energy_db.close()
91
            if cnx_energy_db:
92
                cnx_energy_db.close()
93
94
            if cursor_system_db:
95
                cursor_system_db.close()
96
            if cnx_system_db:
97
                cnx_system_db.close()
98
            # sleep and continue the outermost while loop
99
            time.sleep(60)
100
            continue
101
102
        print("Connected to MyEMS Energy Database")
103
104
        cnx_carbon_db = None
105
        cursor_carbon_db = None
106
        try:
107
            cnx_carbon_db = mysql.connector.connect(**config.myems_carbon_db)
108
            cursor_carbon_db = cnx_carbon_db.cursor()
109
        except Exception as e:
110
            logger.error("Error in step 1.4 of offline_meter_carbon " + str(e))
111
            if cursor_carbon_db:
112
                cursor_carbon_db.close()
113
            if cnx_carbon_db:
114
                cnx_carbon_db.close()
115
116
            if cursor_energy_db:
117
                cursor_energy_db.close()
118
            if cnx_energy_db:
119
                cnx_energy_db.close()
120
121
            if cursor_system_db:
122
                cursor_system_db.close()
123
            if cnx_system_db:
124
                cnx_system_db.close()
125
            # sleep and continue the outermost while loop
126
            time.sleep(60)
127
            continue
128
129
        print("Connected to MyEMS Carbon Database")
130
131
        for offline_meter in offline_meter_list:
132
133
            ############################################################################################################
134
            # Step 2: get the latest start_datetime_utc
135
            ############################################################################################################
136
            print("Step 2: get the latest start_datetime_utc from carbon database for " + offline_meter['name'])
137
            try:
138
                cursor_carbon_db.execute(" SELECT MAX(start_datetime_utc) "
139
                                         " FROM tbl_offline_meter_hourly "
140
                                         " WHERE offline_meter_id = %s ",
141
                                         (offline_meter['id'], ))
142
                row_datetime = cursor_carbon_db.fetchone()
143
                start_datetime_utc = datetime.strptime(config.start_datetime_utc, '%Y-%m-%d %H:%M:%S')
144
                start_datetime_utc = start_datetime_utc.replace(minute=0, second=0, microsecond=0, tzinfo=None)
145
146
                if row_datetime is not None and len(row_datetime) > 0 and isinstance(row_datetime[0], datetime):
147
                    # replace second and microsecond with 0
148
                    # note: do not replace minute in case of calculating in half hourly
149
                    start_datetime_utc = row_datetime[0].replace(second=0, microsecond=0, tzinfo=None)
150
                    # start from the next time slot
151
                    start_datetime_utc += timedelta(minutes=config.minutes_to_count)
152
153
                print("start_datetime_utc: " + start_datetime_utc.isoformat()[0:19])
154
            except Exception as e:
155
                logger.error("Error in step 2 of offline_meter_carbon " + str(e))
156
                # break the for offline meter loop
157
                break
158
159
            ############################################################################################################
160
            # Step 3: get all energy data since the latest start_datetime_utc
161
            ############################################################################################################
162
            print("Step 3: get all energy data since the latest start_datetime_utc")
163
            try:
164
                query = (" SELECT start_datetime_utc, actual_value "
165
                         " FROM tbl_offline_meter_hourly "
166
                         " WHERE offline_meter_id = %s AND start_datetime_utc >= %s "
167
                         " ORDER BY id ")
168
                cursor_energy_db.execute(query, (offline_meter['id'], start_datetime_utc, ))
169
                rows_hourly = cursor_energy_db.fetchall()
170
171
                if rows_hourly is None or len(rows_hourly) == 0:
172
                    print("Step 3: There isn't any energy input data to calculate. ")
173
                    # continue the for offline meter loop
174
                    continue
175
176
                energy_dict = dict()
177
                end_datetime_utc = start_datetime_utc
178
                for row_hourly in rows_hourly:
179
                    current_datetime_utc = row_hourly[0]
180
                    actual_value = row_hourly[1]
181
                    if energy_dict.get(current_datetime_utc) is None:
182
                        energy_dict[current_datetime_utc] = dict()
183
                    energy_dict[current_datetime_utc][offline_meter['energy_category_id']] = actual_value
184
                    if current_datetime_utc > end_datetime_utc:
185
                        end_datetime_utc = current_datetime_utc
186
            except Exception as e:
187
                logger.error("Error in step 3 of offline_meter_carbon " + str(e))
188
                # break the for offline meter loop
189
                break
190
191
            ############################################################################################################
192
            # Step 4: get carbon dioxide emission factor
193
            ############################################################################################################
194
            print("Step 4: get carbon dioxide emission factor")
195
            factor_dict = dict()
196
            factor_dict[offline_meter['energy_category_id']] = \
197
                carbon_dioxide_emmision_factor.get_energy_category_factor(
198
                    offline_meter['energy_category_id'],
199
                    start_datetime_utc,
200
                    end_datetime_utc)
201
            ############################################################################################################
202
            # Step 5: calculate carbon dioxide emission by multiplying energy with factor
203
            ############################################################################################################
204
            print("Step 5: calculate carbon dioxide emission by multiplying energy with factor")
205
            aggregated_values = list()
206
            if len(energy_dict) > 0:
207
                for current_datetime_utc in energy_dict.keys():
208
                    aggregated_value = dict()
209
                    aggregated_value['start_datetime_utc'] = current_datetime_utc
210
                    aggregated_value['actual_value'] = None
211
                    current_factor = factor_dict[offline_meter['energy_category_id']]
212
                    current_energy = energy_dict[current_datetime_utc].get(offline_meter['energy_category_id'])
213
                    if current_factor is not None \
214
                            and isinstance(current_factor, Decimal) \
215
                            and current_energy is not None \
216
                            and isinstance(current_energy, Decimal):
217
                        aggregated_value['actual_value'] = current_energy * current_factor
218
                        aggregated_values.append(aggregated_value)
219
220
            ############################################################################################################
221
            # Step 6: save carbon dioxide emission data to database
222
            ############################################################################################################
223
            print("Step 6: save carbon dioxide emission data to database")
224
225
            while len(aggregated_values) > 0:
226
                insert_100 = aggregated_values[:100]
227
                aggregated_values = aggregated_values[100:]
228
                try:
229
                    add_values = (" INSERT INTO tbl_offline_meter_hourly "
230
                                  "             (offline_meter_id, "
231
                                  "              start_datetime_utc, "
232
                                  "              actual_value) "
233
                                  " VALUES  ")
234
235
                    for aggregated_value in insert_100:
236
                        if aggregated_value['actual_value'] is not None and \
237
                                isinstance(aggregated_value['actual_value'], Decimal):
238
                            add_values += " (" + str(offline_meter['id']) + ","
239
                            add_values += "'" + aggregated_value['start_datetime_utc'].isoformat()[0:19] + "',"
240
                            add_values += str(aggregated_value['actual_value']) + "), "
241
                    # trim ", " at the end of string and then execute
242
                    cursor_carbon_db.execute(add_values[:-2])
243
                    cnx_carbon_db.commit()
244
                except Exception as e:
245
                    logger.error("Error in step 6 of offline_meter_carbon " + str(e))
246
                    break
247
248
        # end of for offline meter loop
249
        if cursor_system_db:
250
            cursor_system_db.close()
251
        if cnx_system_db:
252
            cnx_system_db.close()
253
254
        if cursor_energy_db:
255
            cursor_energy_db.close()
256
        if cnx_energy_db:
257
            cnx_energy_db.close()
258
259
        if cursor_carbon_db:
260
            cursor_carbon_db.close()
261
        if cnx_carbon_db:
262
            cnx_carbon_db.close()
263
        print("go to sleep 300 seconds...")
264
        time.sleep(300)
265
        print("wake from sleep, and continue to work...")
266
    # end of the outermost while loop
267

myems-aggregation/offline_meter_billing.py 1 location

@@ 23-265 (lines=243) @@
20
########################################################################################################################
21
22
23
def main(logger):
24
25
    while True:
26
        # the outermost while loop
27
        ################################################################################################################
28
        # Step 1: get all offline meters
29
        ################################################################################################################
30
        cnx_system_db = None
31
        cursor_system_db = None
32
        try:
33
            cnx_system_db = mysql.connector.connect(**config.myems_system_db)
34
            cursor_system_db = cnx_system_db.cursor()
35
        except Exception as e:
36
            logger.error("Error in step 1.1 of offline_meter_billing " + str(e))
37
            if cursor_system_db:
38
                cursor_system_db.close()
39
            if cnx_system_db:
40
                cnx_system_db.close()
41
            # sleep and continue the outermost while loop
42
            time.sleep(60)
43
            continue
44
45
        print("Connected to MyEMS System Database")
46
47
        offline_meter_list = list()
48
        try:
49
            cursor_system_db.execute(" SELECT id, name, energy_category_id, cost_center_id "
50
                                     " FROM tbl_offline_meters "
51
                                     " ORDER BY id ")
52
            rows_offline_meters = cursor_system_db.fetchall()
53
54
            if rows_offline_meters is None or len(rows_offline_meters) == 0:
55
                print("Step 1.2: There isn't any offline meters. ")
56
                if cursor_system_db:
57
                    cursor_system_db.close()
58
                if cnx_system_db:
59
                    cnx_system_db.close()
60
                # sleep and continue the outermost while loop
61
                time.sleep(60)
62
                continue
63
64
            for row in rows_offline_meters:
65
                offline_meter_list.append({"id": row[0],
66
                                           "name": row[1],
67
                                           "energy_category_id": row[2],
68
                                           "cost_center_id": row[3]})
69
70
        except Exception as e:
71
            logger.error("Error in step 1.2 of offline_meter_billing " + str(e))
72
            if cursor_system_db:
73
                cursor_system_db.close()
74
            if cnx_system_db:
75
                cnx_system_db.close()
76
            # sleep and continue the outermost while loop
77
            time.sleep(60)
78
            continue
79
80
        print("Step 1.2: Got all offline_meters from MyEMS System Database")
81
82
        cnx_energy_db = None
83
        cursor_energy_db = None
84
        try:
85
            cnx_energy_db = mysql.connector.connect(**config.myems_energy_db)
86
            cursor_energy_db = cnx_energy_db.cursor()
87
        except Exception as e:
88
            logger.error("Error in step 1.3 of offline_meter_billing " + str(e))
89
            if cursor_energy_db:
90
                cursor_energy_db.close()
91
            if cnx_energy_db:
92
                cnx_energy_db.close()
93
94
            if cursor_system_db:
95
                cursor_system_db.close()
96
            if cnx_system_db:
97
                cnx_system_db.close()
98
            # sleep and continue the outermost while loop
99
            time.sleep(60)
100
            continue
101
102
        print("Connected to MyEMS Energy Database")
103
104
        cnx_billing_db = None
105
        cursor_billing_db = None
106
        try:
107
            cnx_billing_db = mysql.connector.connect(**config.myems_billing_db)
108
            cursor_billing_db = cnx_billing_db.cursor()
109
        except Exception as e:
110
            logger.error("Error in step 1.4 of offline_meter_billing " + str(e))
111
            if cursor_billing_db:
112
                cursor_billing_db.close()
113
            if cnx_billing_db:
114
                cnx_billing_db.close()
115
116
            if cursor_energy_db:
117
                cursor_energy_db.close()
118
            if cnx_energy_db:
119
                cnx_energy_db.close()
120
121
            if cursor_system_db:
122
                cursor_system_db.close()
123
            if cnx_system_db:
124
                cnx_system_db.close()
125
            # sleep and continue the outermost while loop
126
            time.sleep(60)
127
            continue
128
129
        print("Connected to MyEMS Billing Database")
130
131
        for offline_meter in offline_meter_list:
132
133
            ############################################################################################################
134
            # Step 2: get the latest start_datetime_utc
135
            ############################################################################################################
136
            print("Step 2: get the latest start_datetime_utc from billing database for " + offline_meter['name'])
137
            try:
138
                cursor_billing_db.execute(" SELECT MAX(start_datetime_utc) "
139
                                          " FROM tbl_offline_meter_hourly "
140
                                          " WHERE offline_meter_id = %s ",
141
                                          (offline_meter['id'], ))
142
                row_datetime = cursor_billing_db.fetchone()
143
                start_datetime_utc = datetime.strptime(config.start_datetime_utc, '%Y-%m-%d %H:%M:%S')
144
                start_datetime_utc = start_datetime_utc.replace(minute=0, second=0, microsecond=0, tzinfo=None)
145
146
                if row_datetime is not None and len(row_datetime) > 0 and isinstance(row_datetime[0], datetime):
147
                    # replace second and microsecond with 0
148
                    # note: do not replace minute in case of calculating in half hourly
149
                    start_datetime_utc = row_datetime[0].replace(second=0, microsecond=0, tzinfo=None)
150
                    # start from the next time slot
151
                    start_datetime_utc += timedelta(minutes=config.minutes_to_count)
152
153
                print("start_datetime_utc: " + start_datetime_utc.isoformat()[0:19])
154
            except Exception as e:
155
                logger.error("Error in step 2 of offline_meter_billing " + str(e))
156
                # break the for offline_meter loop
157
                break
158
159
            ############################################################################################################
160
            # Step 3: get all energy data since the latest start_datetime_utc
161
            ############################################################################################################
162
            print("Step 3: get all energy data since the latest start_datetime_utc")
163
            try:
164
                query = (" SELECT start_datetime_utc, actual_value "
165
                         " FROM tbl_offline_meter_hourly "
166
                         " WHERE offline_meter_id = %s AND start_datetime_utc >= %s "
167
                         " ORDER BY id ")
168
                cursor_energy_db.execute(query, (offline_meter['id'], start_datetime_utc, ))
169
                rows_hourly = cursor_energy_db.fetchall()
170
171
                if rows_hourly is None or len(rows_hourly) == 0:
172
                    print("Step 3: There isn't any energy input data to calculate. ")
173
                    # continue the for offline_meter loop
174
                    continue
175
176
                energy_dict = dict()
177
                end_datetime_utc = start_datetime_utc
178
                for row_hourly in rows_hourly:
179
                    current_datetime_utc = row_hourly[0]
180
                    actual_value = row_hourly[1]
181
                    if energy_dict.get(current_datetime_utc) is None:
182
                        energy_dict[current_datetime_utc] = dict()
183
                    energy_dict[current_datetime_utc][offline_meter['energy_category_id']] = actual_value
184
                    if current_datetime_utc > end_datetime_utc:
185
                        end_datetime_utc = current_datetime_utc
186
            except Exception as e:
187
                logger.error("Error in step 3 of offline_meter_billing " + str(e))
188
                # break the for offline_meter loop
189
                break
190
            ############################################################################################################
191
            # Step 4: get tariffs
192
            ############################################################################################################
193
            print("Step 4: get tariffs")
194
            tariff_dict = dict()
195
            tariff_dict[offline_meter['energy_category_id']] = \
196
                tariff.get_energy_category_tariffs(offline_meter['cost_center_id'],
197
                                                   offline_meter['energy_category_id'],
198
                                                   start_datetime_utc,
199
                                                   end_datetime_utc)
200
            ############################################################################################################
201
            # Step 5: calculate billing by multiplying energy with tariff
202
            ############################################################################################################
203
            print("Step 5: calculate billing by multiplying energy with tariff")
204
            aggregated_values = list()
205
206
            if len(energy_dict) > 0:
207
                for current_datetime_utc in energy_dict.keys():
208
                    aggregated_value = dict()
209
                    aggregated_value['start_datetime_utc'] = current_datetime_utc
210
                    aggregated_value['actual_value'] = None
211
                    current_tariff = tariff_dict[offline_meter['energy_category_id']].get(current_datetime_utc)
212
                    current_energy = energy_dict[current_datetime_utc].get(offline_meter['energy_category_id'])
213
                    if current_tariff is not None \
214
                            and isinstance(current_tariff, Decimal) \
215
                            and current_energy is not None \
216
                            and isinstance(current_energy, Decimal):
217
                        aggregated_value['actual_value'] = current_energy * current_tariff
218
                        aggregated_values.append(aggregated_value)
219
220
            ############################################################################################################
221
            # Step 6: save billing data to billing database
222
            ############################################################################################################
223
            print("Step 6: save billing data to billing database")
224
225
            while len(aggregated_values) > 0:
226
                insert_100 = aggregated_values[:100]
227
                aggregated_values = aggregated_values[100:]
228
                try:
229
                    add_values = (" INSERT INTO tbl_offline_meter_hourly "
230
                                  "             (offline_meter_id, "
231
                                  "              start_datetime_utc, "
232
                                  "              actual_value) "
233
                                  " VALUES  ")
234
235
                    for aggregated_value in insert_100:
236
                        if aggregated_value['actual_value'] is not None and \
237
                                isinstance(aggregated_value['actual_value'], Decimal):
238
                            add_values += " (" + str(offline_meter['id']) + ","
239
                            add_values += "'" + aggregated_value['start_datetime_utc'].isoformat()[0:19] + "',"
240
                            add_values += str(aggregated_value['actual_value']) + "), "
241
                    # trim ", " at the end of string and then execute
242
                    cursor_billing_db.execute(add_values[:-2])
243
                    cnx_billing_db.commit()
244
                except Exception as e:
245
                    logger.error("Error in step 6 of offline_meter_billing " + str(e))
246
                    break
247
248
        # end of for offline_meter loop
249
        if cursor_system_db:
250
            cursor_system_db.close()
251
        if cnx_system_db:
252
            cnx_system_db.close()
253
254
        if cursor_energy_db:
255
            cursor_energy_db.close()
256
        if cnx_energy_db:
257
            cnx_energy_db.close()
258
259
        if cursor_billing_db:
260
            cursor_billing_db.close()
261
        if cnx_billing_db:
262
            cnx_billing_db.close()
263
        print("go to sleep 300 seconds...")
264
        time.sleep(300)
265
        print("wake from sleep, and continue to work...")
266
    # end of the outermost while loop
267

myems-aggregation/virtual_meter_carbon.py 1 location

@@ 23-265 (lines=243) @@
20
########################################################################################################################
21
22
23
def main(logger):
24
25
    while True:
26
        # the outermost while loop
27
        ################################################################################################################
28
        # Step 1: get all virtual meters
29
        ################################################################################################################
30
        cnx_system_db = None
31
        cursor_system_db = None
32
        try:
33
            cnx_system_db = mysql.connector.connect(**config.myems_system_db)
34
            cursor_system_db = cnx_system_db.cursor()
35
        except Exception as e:
36
            logger.error("Error in step 1.1 of virtual_meter_carbon " + str(e))
37
            if cursor_system_db:
38
                cursor_system_db.close()
39
            if cnx_system_db:
40
                cnx_system_db.close()
41
            # sleep and continue the outermost while loop
42
            time.sleep(60)
43
            continue
44
45
        print("Connected to MyEMS System Database")
46
47
        virtual_meter_list = list()
48
        try:
49
            cursor_system_db.execute(" SELECT id, name, energy_category_id, cost_center_id "
50
                                     " FROM tbl_virtual_meters "
51
                                     " ORDER BY id ")
52
            rows_virtual_meters = cursor_system_db.fetchall()
53
54
            if rows_virtual_meters is None or len(rows_virtual_meters) == 0:
55
                print("Step 1.2: There isn't any virtual meters. ")
56
                if cursor_system_db:
57
                    cursor_system_db.close()
58
                if cnx_system_db:
59
                    cnx_system_db.close()
60
                # sleep and continue the outermost while loop
61
                time.sleep(60)
62
                continue
63
64
            for row in rows_virtual_meters:
65
                virtual_meter_list.append({"id": row[0],
66
                                           "name": row[1],
67
                                           "energy_category_id": row[2],
68
                                           "cost_center_id": row[3]})
69
70
        except Exception as e:
71
            logger.error("Error in step 1.2 of virtual_meter_carbon " + str(e))
72
            if cursor_system_db:
73
                cursor_system_db.close()
74
            if cnx_system_db:
75
                cnx_system_db.close()
76
            # sleep and continue the outermost while loop
77
            time.sleep(60)
78
            continue
79
80
        print("Step 1.2: Got all virtual meters from MyEMS System Database")
81
82
        cnx_energy_db = None
83
        cursor_energy_db = None
84
        try:
85
            cnx_energy_db = mysql.connector.connect(**config.myems_energy_db)
86
            cursor_energy_db = cnx_energy_db.cursor()
87
        except Exception as e:
88
            logger.error("Error in step 1.3 of virtual_meter_carbon " + str(e))
89
            if cursor_energy_db:
90
                cursor_energy_db.close()
91
            if cnx_energy_db:
92
                cnx_energy_db.close()
93
94
            if cursor_system_db:
95
                cursor_system_db.close()
96
            if cnx_system_db:
97
                cnx_system_db.close()
98
            # sleep and continue the outermost while loop
99
            time.sleep(60)
100
            continue
101
102
        print("Connected to MyEMS Energy Database")
103
104
        cnx_carbon_db = None
105
        cursor_carbon_db = None
106
        try:
107
            cnx_carbon_db = mysql.connector.connect(**config.myems_carbon_db)
108
            cursor_carbon_db = cnx_carbon_db.cursor()
109
        except Exception as e:
110
            logger.error("Error in step 1.4 of virtual_meter_carbon " + str(e))
111
            if cursor_carbon_db:
112
                cursor_carbon_db.close()
113
            if cnx_carbon_db:
114
                cnx_carbon_db.close()
115
116
            if cursor_energy_db:
117
                cursor_energy_db.close()
118
            if cnx_energy_db:
119
                cnx_energy_db.close()
120
121
            if cursor_system_db:
122
                cursor_system_db.close()
123
            if cnx_system_db:
124
                cnx_system_db.close()
125
            # sleep and continue the outermost while loop
126
            time.sleep(60)
127
            continue
128
129
        print("Connected to MyEMS Carbon Database")
130
131
        for virtual_meter in virtual_meter_list:
132
133
            ############################################################################################################
134
            # Step 2: get the latest start_datetime_utc
135
            ############################################################################################################
136
            print("Step 2: get the latest start_datetime_utc from carbon database for " + virtual_meter['name'])
137
            try:
138
                cursor_carbon_db.execute(" SELECT MAX(start_datetime_utc) "
139
                                         " FROM tbl_virtual_meter_hourly "
140
                                         " WHERE virtual_meter_id = %s ",
141
                                         (virtual_meter['id'], ))
142
                row_datetime = cursor_carbon_db.fetchone()
143
                start_datetime_utc = datetime.strptime(config.start_datetime_utc, '%Y-%m-%d %H:%M:%S')
144
                start_datetime_utc = start_datetime_utc.replace(minute=0, second=0, microsecond=0, tzinfo=None)
145
146
                if row_datetime is not None and len(row_datetime) > 0 and isinstance(row_datetime[0], datetime):
147
                    # replace second and microsecond with 0
148
                    # note: do not replace minute in case of calculating in half hourly
149
                    start_datetime_utc = row_datetime[0].replace(second=0, microsecond=0, tzinfo=None)
150
                    # start from the next time slot
151
                    start_datetime_utc += timedelta(minutes=config.minutes_to_count)
152
153
                print("start_datetime_utc: " + start_datetime_utc.isoformat()[0:19])
154
            except Exception as e:
155
                logger.error("Error in step 2 of virtual_meter_carbon " + str(e))
156
                # break the for virtual_meter loop
157
                break
158
159
            ############################################################################################################
160
            # Step 3: get all energy data since the latest start_datetime_utc
161
            ############################################################################################################
162
            print("Step 3: get all energy data since the latest start_datetime_utc")
163
            try:
164
                query = (" SELECT start_datetime_utc, actual_value "
165
                         " FROM tbl_virtual_meter_hourly "
166
                         " WHERE virtual_meter_id = %s AND start_datetime_utc >= %s "
167
                         " ORDER BY id ")
168
                cursor_energy_db.execute(query, (virtual_meter['id'], start_datetime_utc, ))
169
                rows_hourly = cursor_energy_db.fetchall()
170
171
                if rows_hourly is None or len(rows_hourly) == 0:
172
                    print("Step 3: There isn't any energy input data to calculate. ")
173
                    # continue the for virtual meter loop
174
                    continue
175
176
                energy_dict = dict()
177
                end_datetime_utc = start_datetime_utc
178
                for row_hourly in rows_hourly:
179
                    current_datetime_utc = row_hourly[0]
180
                    actual_value = row_hourly[1]
181
                    if energy_dict.get(current_datetime_utc) is None:
182
                        energy_dict[current_datetime_utc] = dict()
183
                    energy_dict[current_datetime_utc][virtual_meter['energy_category_id']] = actual_value
184
                    if current_datetime_utc > end_datetime_utc:
185
                        end_datetime_utc = current_datetime_utc
186
            except Exception as e:
187
                logger.error("Error in step 3 of virtual_meter_carbon " + str(e))
188
                # break the for virtual_meter loop
189
                break
190
191
            ############################################################################################################
192
            # Step 4: get carbon dioxide emission factor
193
            ############################################################################################################
194
            print("Step 4: get carbon dioxide emission factor")
195
            factor_dict = dict()
196
            factor_dict[virtual_meter['energy_category_id']] = \
197
                carbon_dioxide_emmision_factor.get_energy_category_factor(
198
                    virtual_meter['energy_category_id'],
199
                    start_datetime_utc,
200
                    end_datetime_utc)
201
            ############################################################################################################
202
            # Step 5: calculate carbon dioxide emission by multiplying energy with factor
203
            ############################################################################################################
204
            print("Step 5: calculate carbon dioxide emission by multiplying energy with factor")
205
            aggregated_values = list()
206
            if len(energy_dict) > 0:
207
                for current_datetime_utc in energy_dict.keys():
208
                    aggregated_value = dict()
209
                    aggregated_value['start_datetime_utc'] = current_datetime_utc
210
                    aggregated_value['actual_value'] = None
211
                    current_factor = factor_dict[virtual_meter['energy_category_id']]
212
                    current_energy = energy_dict[current_datetime_utc].get(virtual_meter['energy_category_id'])
213
                    if current_factor is not None \
214
                            and isinstance(current_factor, Decimal) \
215
                            and current_energy is not None \
216
                            and isinstance(current_energy, Decimal):
217
                        aggregated_value['actual_value'] = current_energy * current_factor
218
                        aggregated_values.append(aggregated_value)
219
220
            ############################################################################################################
221
            # Step 6: save carbon dioxide emission data to database
222
            ############################################################################################################
223
            print("Step 6: save carbon dioxide emission data to database")
224
225
            while len(aggregated_values) > 0:
226
                insert_100 = aggregated_values[:100]
227
                aggregated_values = aggregated_values[100:]
228
                try:
229
                    add_values = (" INSERT INTO tbl_virtual_meter_hourly "
230
                                  "             (virtual_meter_id, "
231
                                  "              start_datetime_utc, "
232
                                  "              actual_value) "
233
                                  " VALUES  ")
234
                    for aggregated_value in insert_100:
235
                        if aggregated_value['actual_value'] is not None and \
236
                                isinstance(aggregated_value['actual_value'], Decimal):
237
                            add_values += " (" + str(virtual_meter['id']) + ","
238
                            add_values += "'" + aggregated_value['start_datetime_utc'].isoformat()[0:19] + "',"
239
                            add_values += str(aggregated_value['actual_value']) + "), "
240
                    # print("add_values:" + add_values)
241
                    # trim ", " at the end of string and then execute
242
                    cursor_carbon_db.execute(add_values[:-2])
243
                    cnx_carbon_db.commit()
244
                except Exception as e:
245
                    logger.error("Error in step 6 of virtual_meter_carbon " + str(e))
246
                    break
247
248
        # end of for virtual_meter loop
249
        if cursor_system_db:
250
            cursor_system_db.close()
251
        if cnx_system_db:
252
            cnx_system_db.close()
253
254
        if cursor_energy_db:
255
            cursor_energy_db.close()
256
        if cnx_energy_db:
257
            cnx_energy_db.close()
258
259
        if cursor_carbon_db:
260
            cursor_carbon_db.close()
261
        if cnx_carbon_db:
262
            cnx_carbon_db.close()
263
        print("go to sleep 300 seconds...")
264
        time.sleep(300)
265
        print("wake from sleep, and continue to work...")
266
    # end of the outermost while loop
267

myems-aggregation/meter_carbon.py 1 location

@@ 23-265 (lines=243) @@
20
########################################################################################################################
21
22
23
def main(logger):
24
25
    while True:
26
        # the outermost while loop
27
        ################################################################################################################
28
        # Step 1: get all meters
29
        ################################################################################################################
30
        cnx_system_db = None
31
        cursor_system_db = None
32
        try:
33
            cnx_system_db = mysql.connector.connect(**config.myems_system_db)
34
            cursor_system_db = cnx_system_db.cursor()
35
        except Exception as e:
36
            logger.error("Error in step 1.1 of meter_carbon " + str(e))
37
            if cursor_system_db:
38
                cursor_system_db.close()
39
            if cnx_system_db:
40
                cnx_system_db.close()
41
            # sleep and continue the outermost while loop
42
            time.sleep(60)
43
            continue
44
45
        print("Connected to MyEMS System Database")
46
47
        meter_list = list()
48
        try:
49
            cursor_system_db.execute(" SELECT id, name, energy_category_id, cost_center_id "
50
                                     " FROM tbl_meters "
51
                                     " ORDER BY id ")
52
            rows_meters = cursor_system_db.fetchall()
53
54
            if rows_meters is None or len(rows_meters) == 0:
55
                print("Step 1.2: There isn't any meters. ")
56
                if cursor_system_db:
57
                    cursor_system_db.close()
58
                if cnx_system_db:
59
                    cnx_system_db.close()
60
                # sleep and continue the outermost while loop
61
                time.sleep(60)
62
                continue
63
64
            for row in rows_meters:
65
                meter_list.append({"id": row[0],
66
                                   "name": row[1],
67
                                   "energy_category_id": row[2],
68
                                   "cost_center_id": row[3]})
69
70
        except Exception as e:
71
            logger.error("Error in step 1.2 of meter_carbon " + str(e))
72
            if cursor_system_db:
73
                cursor_system_db.close()
74
            if cnx_system_db:
75
                cnx_system_db.close()
76
            # sleep and continue the outermost while loop
77
            time.sleep(60)
78
            continue
79
80
        print("Step 1.2: Got all meters from MyEMS System Database")
81
82
        cnx_energy_db = None
83
        cursor_energy_db = None
84
        try:
85
            cnx_energy_db = mysql.connector.connect(**config.myems_energy_db)
86
            cursor_energy_db = cnx_energy_db.cursor()
87
        except Exception as e:
88
            logger.error("Error in step 1.3 of meter_carbon " + str(e))
89
            if cursor_energy_db:
90
                cursor_energy_db.close()
91
            if cnx_energy_db:
92
                cnx_energy_db.close()
93
94
            if cursor_system_db:
95
                cursor_system_db.close()
96
            if cnx_system_db:
97
                cnx_system_db.close()
98
            # sleep and continue the outermost while loop
99
            time.sleep(60)
100
            continue
101
102
        print("Connected to MyEMS Energy Database")
103
104
        cnx_carbon_db = None
105
        cursor_carbon_db = None
106
        try:
107
            cnx_carbon_db = mysql.connector.connect(**config.myems_carbon_db)
108
            cursor_carbon_db = cnx_carbon_db.cursor()
109
        except Exception as e:
110
            logger.error("Error in step 1.4 of meter_carbon " + str(e))
111
            if cursor_carbon_db:
112
                cursor_carbon_db.close()
113
            if cnx_carbon_db:
114
                cnx_carbon_db.close()
115
116
            if cursor_energy_db:
117
                cursor_energy_db.close()
118
            if cnx_energy_db:
119
                cnx_energy_db.close()
120
121
            if cursor_system_db:
122
                cursor_system_db.close()
123
            if cnx_system_db:
124
                cnx_system_db.close()
125
            # sleep and continue the outermost while loop
126
            time.sleep(60)
127
            continue
128
129
        print("Connected to MyEMS Carbon Database")
130
131
        for meter in meter_list:
132
133
            ############################################################################################################
134
            # Step 2: get the latest start_datetime_utc
135
            ############################################################################################################
136
            print("Step 2: get the latest start_datetime_utc from carbon database for " + meter['name'])
137
            try:
138
                cursor_carbon_db.execute(" SELECT MAX(start_datetime_utc) "
139
                                         " FROM tbl_meter_hourly "
140
                                         " WHERE meter_id = %s ",
141
                                         (meter['id'], ))
142
                row_datetime = cursor_carbon_db.fetchone()
143
                start_datetime_utc = datetime.strptime(config.start_datetime_utc, '%Y-%m-%d %H:%M:%S')
144
                start_datetime_utc = start_datetime_utc.replace(minute=0, second=0, microsecond=0, tzinfo=None)
145
146
                if row_datetime is not None and len(row_datetime) > 0 and isinstance(row_datetime[0], datetime):
147
                    # replace second and microsecond with 0
148
                    # note: do not replace minute in case of calculating in half hourly
149
                    start_datetime_utc = row_datetime[0].replace(second=0, microsecond=0, tzinfo=None)
150
                    # start from the next time slot
151
                    start_datetime_utc += timedelta(minutes=config.minutes_to_count)
152
153
                print("start_datetime_utc: " + start_datetime_utc.isoformat()[0:19])
154
            except Exception as e:
155
                logger.error("Error in step 2 of meter_carbon " + str(e))
156
                # break the for meter loop
157
                break
158
159
            ############################################################################################################
160
            # Step 3: get all energy data since the latest start_datetime_utc
161
            ############################################################################################################
162
            print("Step 3: get all energy data since the latest start_datetime_utc")
163
            try:
164
                query = (" SELECT start_datetime_utc, actual_value "
165
                         " FROM tbl_meter_hourly "
166
                         " WHERE meter_id = %s AND start_datetime_utc >= %s "
167
                         " ORDER BY id ")
168
                cursor_energy_db.execute(query, (meter['id'], start_datetime_utc, ))
169
                rows_hourly = cursor_energy_db.fetchall()
170
171
                if rows_hourly is None or len(rows_hourly) == 0:
172
                    print("Step 3: There isn't any energy input data to calculate. ")
173
                    # continue the for meter loop
174
                    continue
175
176
                energy_dict = dict()
177
                end_datetime_utc = start_datetime_utc
178
                for row_hourly in rows_hourly:
179
                    current_datetime_utc = row_hourly[0]
180
                    actual_value = row_hourly[1]
181
                    if energy_dict.get(current_datetime_utc) is None:
182
                        energy_dict[current_datetime_utc] = dict()
183
                    energy_dict[current_datetime_utc][meter['energy_category_id']] = actual_value
184
                    if current_datetime_utc > end_datetime_utc:
185
                        end_datetime_utc = current_datetime_utc
186
            except Exception as e:
187
                logger.error("Error in step 3 of meter_carbon " + str(e))
188
                # break the for meter loop
189
                break
190
191
            ############################################################################################################
192
            # Step 4: get carbon dioxide emission factor
193
            ############################################################################################################
194
            print("Step 4: get carbon dioxide emission factor")
195
            factor_dict = dict()
196
            factor_dict[meter['energy_category_id']] = \
197
                carbon_dioxide_emmision_factor.get_energy_category_factor(
198
                    meter['energy_category_id'],
199
                    start_datetime_utc,
200
                    end_datetime_utc)
201
            ############################################################################################################
202
            # Step 5: calculate carbon dioxide emission by multiplying energy with factor
203
            ############################################################################################################
204
            print("Step 5: calculate carbon dioxide emission by multiplying energy with factor")
205
            aggregated_values = list()
206
            if len(energy_dict) > 0:
207
                for current_datetime_utc in energy_dict.keys():
208
                    aggregated_value = dict()
209
                    aggregated_value['start_datetime_utc'] = current_datetime_utc
210
                    aggregated_value['actual_value'] = None
211
                    current_factor = factor_dict[meter['energy_category_id']]
212
                    current_energy = energy_dict[current_datetime_utc].get(meter['energy_category_id'])
213
                    if current_factor is not None \
214
                            and isinstance(current_factor, Decimal) \
215
                            and current_energy is not None \
216
                            and isinstance(current_energy, Decimal):
217
                        aggregated_value['actual_value'] = current_energy * current_factor
218
                        aggregated_values.append(aggregated_value)
219
220
            ############################################################################################################
221
            # Step 6: save carbon dioxide emission data to database
222
            ############################################################################################################
223
            print("Step 6: save carbon dioxide emission data to database")
224
225
            while len(aggregated_values) > 0:
226
                insert_100 = aggregated_values[:100]
227
                aggregated_values = aggregated_values[100:]
228
                try:
229
                    add_values = (" INSERT INTO tbl_meter_hourly "
230
                                  "             (meter_id, "
231
                                  "              start_datetime_utc, "
232
                                  "              actual_value) "
233
                                  " VALUES  ")
234
                    for aggregated_value in insert_100:
235
                        if aggregated_value['actual_value'] is not None and \
236
                                isinstance(aggregated_value['actual_value'], Decimal):
237
                            add_values += " (" + str(meter['id']) + ","
238
                            add_values += "'" + aggregated_value['start_datetime_utc'].isoformat()[0:19] + "',"
239
                            add_values += str(aggregated_value['actual_value']) + "), "
240
                    # print("add_values:" + add_values)
241
                    # trim ", " at the end of string and then execute
242
                    cursor_carbon_db.execute(add_values[:-2])
243
                    cnx_carbon_db.commit()
244
                except Exception as e:
245
                    logger.error("Error in step 6 of meter_carbon " + str(e))
246
                    break
247
248
        # end of for meter loop
249
        if cursor_system_db:
250
            cursor_system_db.close()
251
        if cnx_system_db:
252
            cnx_system_db.close()
253
254
        if cursor_energy_db:
255
            cursor_energy_db.close()
256
        if cnx_energy_db:
257
            cnx_energy_db.close()
258
259
        if cursor_carbon_db:
260
            cursor_carbon_db.close()
261
        if cnx_carbon_db:
262
            cnx_carbon_db.close()
263
        print("go to sleep 300 seconds...")
264
        time.sleep(300)
265
        print("wake from sleep, and continue to work...")
266
    # end of the outermost while loop
267