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