Skip to content

Commit 5a79b2d

Browse files
committed
hotfixes and ver update
1 parent dff3aec commit 5a79b2d

File tree

4 files changed

+82
-33
lines changed

4 files changed

+82
-33
lines changed

codegreen_core/data/entsoe.py

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ def _refine_data(options, data1):
6767
"""
6868
# calculate the duration of the time series by finding the difference between the
6969
# first and the second index (which is of the type `datatime``) and convert this into minutes
70+
#print(data1)
71+
if len(data1) == 1:
72+
return {"data": None, "refine_logs": ["Only one record cannot be processed"]}
73+
7074
durationMin = (data1.index[1] - data1.index[0]).total_seconds() / 60
7175
# initializing the log list
7276
refine_logs = []
@@ -132,12 +136,19 @@ def _entsoe_get_actual_generation(options={"country": "", "start": "", "end": ""
132136
utc_start = _convert_local_to_utc(options["start"])
133137
utc_end = _convert_local_to_utc(options["end"])
134138
client1 = entsoePandas(api_key=_get_API_token())
135-
data1 = client1.query_generation(
136-
options["country"],
137-
start = utc_start ,
138-
end = utc_end ,
139-
psr_type=None,
140-
)
139+
try :
140+
data1 = client1.query_generation(
141+
options["country"],
142+
start = utc_start ,
143+
end = utc_end ,
144+
psr_type=None,
145+
)
146+
except Exception as e:
147+
print("Error in fetching data from ENTSOE")
148+
return {
149+
"data": None,
150+
"duration": 0,
151+
}
141152
# drop columns with actual consumption values (we want actual aggregated generation values)
142153
columns_to_drop = [col for col in data1.columns if col[1] == "Actual Consumption"]
143154
data1 = data1.drop(columns=columns_to_drop)
@@ -149,9 +160,13 @@ def _entsoe_get_actual_generation(options={"country": "", "start": "", "end": ""
149160
# refine the dataframe. see the refine method
150161
data2 = _refine_data(options, data1)
151162
refined_data = data2["data"]
152-
refined_data = refined_data.reset_index(drop=True)
163+
153164
# finding the duration of the time series data
154-
durationMin = (data1.index[1] - data1.index[0]).total_seconds() / 60
165+
if(refined_data is not None):
166+
refined_data = refined_data.reset_index(drop=True)
167+
durationMin = (data1.index[1] - data1.index[0]).total_seconds() / 60
168+
else:
169+
durationMin = 0
155170
return {
156171
"data": refined_data,
157172
"duration": durationMin,
@@ -274,15 +289,15 @@ def _format_energy_data(df):
274289
# the main methods
275290

276291

277-
def get_actual_production_percentage(country, start, end, interval60=False) -> dict:
292+
def get_actual_production_percentage(country, start, end, interval60=True) -> dict:
278293
"""Returns time series data containing the percentage of energy generated from various sources for the specified country within the selected time period.
279294
It also includes the percentage of energy from renewable and non renewable sources. The data is fetched from the APIs is subsequently refined.
280295
To obtain data in 60-minute intervals (if not already available), set 'interval60' to True
281296
282297
:param str country: The 2 alphabet country code.
283298
:param datetime start: The start date for data retrieval. A Datetime object. Note that this date will be rounded to the nearest hour.
284299
:param datetime end: The end date for data retrieval. A datetime object. This date is also rounded to the nearest hour.
285-
:param boolean interval60: To convert the data into 60 min time interval. False by default
300+
:param boolean interval60: To convert the data into 60 min time interval. True by default
286301
:return: A DataFrame containing the hourly energy production mix and percentage of energy generated from renewable and non renewable sources.
287302
:return: A dictionary containing:
288303
- `error`: A string with an error message, empty if no errors.
@@ -322,6 +337,15 @@ def get_actual_production_percentage(country, start, end, interval60=False) -> d
322337
# get actual generation data per production type and convert it into 60 min interval if required
323338
totalRaw = _entsoe_get_actual_generation(options)
324339
total = totalRaw["data"]
340+
341+
if total is None :
342+
# no data to process further
343+
return {
344+
"data": None,
345+
"data_available": False,
346+
"error": "Data is not available"
347+
}
348+
325349
duration = totalRaw["duration"]
326350
if options["interval60"] == True and totalRaw["duration"] != 60.0:
327351
table = _convert_to_60min_interval(totalRaw)

codegreen_core/data/offline.py

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -105,24 +105,31 @@ def _sync_offline_file(country):
105105
current_time = datetime.now()
106106
# storing data from 5 hours from now.
107107
end_time = _round_to_nearest_hour(current_time) - timedelta(hours=5)
108-
108+
print(country)
109+
print("Checking for file ",json_file_path)
109110
if not (os.path.exists(json_file_path) and os.path.exists(csv_file_path)):
110111
print("Files do not exist. Gathering new data.")
111112
try:
112113
data = _gather_energy_data(country, start_time, end_time)
113-
114-
data.to_csv(csv_file_path, index=False)
115-
metadata = {
116-
"country": country,
117-
"first_start_time": int(data.iloc[0]["startTime"].timestamp()),
118-
"last_start_time": int(data.iloc[-1]["startTime"].timestamp()),
119-
"created_on": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
120-
"updated_on": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
121-
}
122-
with open(json_file_path, "w") as f:
123-
json.dump(metadata, f, indent=4)
124-
log_stuff("Successfully created new offline file for "+country)
125-
return data
114+
if data :
115+
data.to_csv(csv_file_path, index=False)
116+
first_start_time1 = data.iloc[0]["startTime"]
117+
last_start_time1 = data.iloc[-1]["startTime"]
118+
metadata = {
119+
"country": country,
120+
"first_start_time": int(first_start_time1.timestamp()),
121+
"last_start_time": int(last_start_time1.timestamp()),
122+
"created_on": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
123+
"updated_on": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
124+
"message" : f"Data ranges from {first_start_time1.strftime('%Y-%m-%d %H:%M:%S')} to {last_start_time1.strftime('%Y-%m-%d %H:%M:%S')}"
125+
126+
}
127+
with open(json_file_path, "w") as f:
128+
json.dump(metadata, f, indent=4)
129+
log_stuff("Successfully created new offline file for "+country)
130+
return data
131+
else:
132+
print("Data not available")
126133
except Exception as e:
127134
print(e)
128135
else:
@@ -138,23 +145,34 @@ def _sync_offline_file(country):
138145

139146
update_required = False
140147
if start_diff.total_seconds() > 0:
141-
print("Gathering missing data before current start time.")
148+
print("Gathering missing data before current start time in the file.")
142149
new_data = _gather_energy_data(country, start_time, current_start_time )
143150
df = pd.concat([new_data, df], ignore_index=True)
144151
update_required = True
145152
if end_diff.total_seconds() > 0:
146-
print("Gathering missing data after current end time.")
147-
new_data = _gather_energy_data(country, current_end_time, end_time)
148-
#print(new_data)
149-
df = pd.concat([df, new_data], ignore_index=True)
150-
update_required = True
153+
try:
154+
print("Gathering missing data after current end time in the file.")
155+
new_data = _gather_energy_data(country, current_end_time, end_time)
156+
#print(new_data)
157+
if new_data is not None :
158+
df = pd.concat([df, new_data], ignore_index=True)
159+
update_required = True
160+
else :
161+
print(" No new data available")
162+
except Exception as e :
163+
print("Error in fetching current data. This is possibly because there is no new data to fetch.")
164+
print(e)
165+
151166
if update_required:
152167
df["startTime"] = pd.to_datetime(df["startTime"])
153168
df = df.sort_values(by="startTime")
154169
df.to_csv(csv_file_path, index=False)
155-
metadata["first_start_time"] = int(df.iloc[0]["startTime"].timestamp())
156-
metadata["last_start_time"] = int(df.iloc[-1]["startTime"].timestamp())
170+
first_start_time = df.iloc[0]["startTime"]
171+
last_start_time = df.iloc[-1]["startTime"]
172+
metadata["first_start_time"] = int(first_start_time.timestamp())
173+
metadata["last_start_time"] = int(last_start_time.timestamp())
157174
metadata["updated_on"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
175+
metadata["message"] = f"Data ranges from {first_start_time.strftime('%Y-%m-%d %H:%M:%S')} to {last_start_time.strftime('%Y-%m-%d %H:%M:%S')}"
158176
with open(json_file_path, "w") as f:
159177
json.dump(metadata, f, indent=4)
160178
log_stuff("Successfully synced offline file for "+country)

codegreen_core/utilities/config.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ class ConfigError(Exception):
88

99
class Config:
1010
config_data = None
11+
config_file_path = None
1112
section_name = "codegreen"
1213
all_keys = [
1314
{
@@ -116,6 +117,7 @@ def load_config(self, file_path=None):
116117

117118
self.config_data = configparser.ConfigParser()
118119
self.config_data.read(file_path)
120+
self.config_file_path = file_path
119121

120122
if self.section_name not in self.config_data:
121123
self.config_data[self.section_name] = {}
@@ -164,3 +166,8 @@ def get(self, key):
164166
print("Config not found")
165167
print(key)
166168
raise e
169+
170+
@classmethod
171+
def get_config_file_path(self):
172+
"""Returns the path of the config file"""
173+
return self.config_file_path

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "codegreen_core"
3-
version = "0.0.5"
3+
version = "0.0.6"
44
description = "This package helps you become aware of the carbon footprint of your computation"
55
authors = ["Anne Hartebrodt <anne.hartebrodt@fau.de>","Shubh Vardhan Jain <shubh.v.jain@fau.de>"]
66
readme = "README.md"

0 commit comments

Comments
 (0)