@@ 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 |
@@ 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 |
@@ 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 |
@@ 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 |
@@ 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 |
@@ 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 |