Skip to content

Commit

Permalink
add start date production
Browse files Browse the repository at this point in the history
  • Loading branch information
Nick Elbers committed Jul 14, 2023
1 parent 4dc5967 commit 4013381
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 22 deletions.
6 changes: 6 additions & 0 deletions custom_components/solaredge_forecast/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@
CONF_STARTMONTH,
CONF_ENDDAY,
CONF_ENDMONTH,
CONF_STARTDATE_PRODUCTION,
DEFAULT_ACCOUNT_KEY,
DEFAULT_SITE_ID,
DEFAULT_STARTDAY,
DEFAULT_STARTMONTH,
DEFAULT_ENDDAY,
DEFAULT_ENDMONTH,
DEFAULT_STARTDATE_PRODUCTION,
DOMAIN
)

Expand Down Expand Up @@ -68,6 +70,7 @@ def __init__(self, hass: HomeAssistant, entry: ConfigEntry) -> None:
CONF_STARTMONTH: data.pop(CONF_STARTMONTH, DEFAULT_STARTMONTH),
CONF_ENDDAY: data.pop(CONF_ENDDAY, DEFAULT_ENDDAY),
CONF_ENDMONTH: data.pop(CONF_ENDMONTH, DEFAULT_ENDMONTH),
CONF_STARTDATE_PRODUCTION: data.pop(CONF_STARTDATE_PRODUCTION, DEFAULT_STARTDATE_PRODUCTION),
}

self.hass.config_entries.async_update_entry(
Expand All @@ -82,6 +85,8 @@ def __init__(self, hass: HomeAssistant, entry: ConfigEntry) -> None:
self.start_month = entry.options[CONF_STARTMONTH]
self.end_day = entry.options[CONF_ENDDAY]
self.end_month = entry.options[CONF_ENDMONTH]
self.start_date_production = entry.options[CONF_STARTDATE_PRODUCTION]\
.replace("/","").replace("-", "").replace(" ", "")
self.unique_id = entry.entry_id
self.name = entry.title

Expand Down Expand Up @@ -122,6 +127,7 @@ async def _async_update_data(self):
SolaredgeForecast,
self.startdate,
self.enddate,
self.start_date_production,
self.site_id,
self.account_key
)
Expand Down
39 changes: 39 additions & 0 deletions custom_components/solaredge_forecast/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@
CONF_STARTMONTH,
CONF_ENDDAY,
CONF_ENDMONTH,
CONF_STARTDATE_PRODUCTION,
DEFAULT_ACCOUNT_KEY,
DEFAULT_SITE_ID,
DEFAULT_STARTDAY,
DEFAULT_STARTMONTH,
DEFAULT_ENDDAY,
DEFAULT_ENDMONTH,
DEFAULT_STARTDATE_PRODUCTION,
DOMAIN,
MONTHS,
)
Expand Down Expand Up @@ -54,6 +56,8 @@ async def async_step_user(self, user_input=None):
self._errors[CONF_STARTDAY] = "invalid_startday"
elif not await self._date_validation(user_input[CONF_ENDDAY], user_input[CONF_ENDMONTH]):
self._errors[CONF_ENDDAY] = "invalid_endday"
elif not await self._startdate_validation(user_input[CONF_STARTDATE_PRODUCTION]):
self._errors[CONF_STARTDATE_PRODUCTION] = "invalid_startdate_production"
elif not await self._period_validation(user_input[CONF_STARTDAY], user_input[CONF_STARTMONTH],
user_input[CONF_ENDDAY],user_input[CONF_ENDMONTH]):
self._errors[CONF_ENDMONTH] = "invalid_period"
Expand All @@ -74,6 +78,7 @@ async def async_step_user(self, user_input=None):
user_input[CONF_STARTMONTH] = DEFAULT_STARTMONTH
user_input[CONF_ENDDAY] = DEFAULT_ENDDAY
user_input[CONF_ENDMONTH] = DEFAULT_ENDMONTH
user_input[CONF_STARTDATE_PRODUCTION] = DEFAULT_STARTDATE_PRODUCTION

return await self._show_config_form(user_input)

Expand Down Expand Up @@ -106,6 +111,9 @@ async def _show_config_form(self, user_input): # pylint: disable=unused-argumen
vol.Optional(
CONF_ENDMONTH, default=user_input.get(CONF_ENDMONTH, DEFAULT_ENDMONTH)
): vol.In(MONTHS),
vol.Optional(
CONF_STARTDATE_PRODUCTION, default=user_input.get(CONF_STARTDATE_PRODUCTION, DEFAULT_STARTDATE_PRODUCTION)
): cv.string,
}
),
errors=self._errors,
Expand All @@ -121,6 +129,18 @@ async def _date_validation(self, day, month) -> bool:
except ValueError:
return False

async def _startdate_validation(self, date) -> bool:
"""Return True if date is a correct date."""
if date == "":
return True
try:
if (datetime.datetime.today() - datetime.datetime.strptime(date.replace("/","").replace("-", "")
.replace(" ", ""), "%d%m%Y")).days < 365:
return False
return True
except ValueError:
return False

async def _period_validation(self, startday, startmonth, endday, endmonth) -> bool:
"""Return True if today is within time period."""
startdate = datetime.datetime.strptime(str(datetime.datetime.now().year) + startmonth + str(startday), "%Y%B%d")
Expand Down Expand Up @@ -167,6 +187,8 @@ async def async_step_user(self, user_input=None):
self._errors[CONF_STARTDAY] = "invalid_startday"
elif not await self._date_validation(user_input[CONF_ENDDAY], user_input[CONF_ENDMONTH]):
self._errors[CONF_ENDDAY] = "invalid_endday"
elif not await self._startdate_validation(user_input[CONF_STARTDATE_PRODUCTION]):
self._errors[CONF_STARTDATE_PRODUCTION] = "invalid_startdate_production"
elif not await self._period_validation(user_input[CONF_STARTDAY], user_input[CONF_STARTMONTH],
user_input[CONF_ENDDAY],user_input[CONF_ENDMONTH]):
self._errors[CONF_ENDMONTH] = "invalid_period"
Expand Down Expand Up @@ -194,6 +216,10 @@ async def async_step_user(self, user_input=None):
vol.Optional(
CONF_ENDMONTH, default=self.options.get(CONF_ENDMONTH, DEFAULT_ENDMONTH)
): vol.In(MONTHS),
vol.Optional(
CONF_STARTDATE_PRODUCTION, default=self.options.get(CONF_STARTDATE_PRODUCTION,
DEFAULT_STARTDATE_PRODUCTION)
): cv.string,
}
),
errors=self._errors,
Expand Down Expand Up @@ -223,6 +249,19 @@ async def _date_validation(self, day, month) -> bool:
except ValueError:
return False

async def _startdate_validation(self, date) -> bool:
"""Return True if date is a correct date."""
if date == "":
return True
try:
if (datetime.datetime.today() - datetime.datetime.strptime(date.replace("/","").replace("-", "")
.replace(" ", ""), "%d%m%Y")).days < 365:
return False
return True
except ValueError:
return False


async def _period_validation(self, startday, startmonth, endday, endmonth) -> bool:
"""Return True if today is within time period."""
startdate = datetime.datetime.strptime(str(datetime.datetime.now().year) + startmonth + str(startday), "%Y%B%d")
Expand Down
10 changes: 10 additions & 0 deletions custom_components/solaredge_forecast/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@
CONF_STARTMONTH = "startmonth"
CONF_ENDDAY = "endday"
CONF_ENDMONTH = "endmonth"
CONF_STARTDATE_PRODUCTION = "startdate production"

DEFAULT_ACCOUNT_KEY = ""
DEFAULT_SITE_ID = ""
DEFAULT_STARTDAY = "01"
DEFAULT_STARTMONTH = "January"
DEFAULT_ENDDAY = "31"
DEFAULT_ENDMONTH = "December"
DEFAULT_STARTDATE_PRODUCTION = ""

MONTHS = [
"January",
Expand Down Expand Up @@ -98,4 +100,12 @@ class SolaredgeForecastSensorEntityDescription(SensorEntityDescription):
device_class=SensorDeviceClass.DATE,
state_class=None,
),
SolaredgeForecastSensorEntityDescription(
key="startdate_production",
name="Start date energy production",
icon="mdi:calendar",
native_unit_of_measurement=None,
device_class=SensorDeviceClass.DATE,
state_class=None,
),
)
18 changes: 14 additions & 4 deletions custom_components/solaredge_forecast/solaredgeforecast/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,18 @@

class SolaredgeForecast(object):
"""Solaredge forecast data"""
def __init__(self, startdate, enddate, site_id, account_key):
def __init__(self, startdate, enddate, startdate_production, site_id, account_key):
self.startdate = datetime.strptime(startdate, '%Y%m%d').date()
self.enddate = datetime.strptime(enddate, '%Y%m%d').date()
self.site_id = site_id
self.account_key = account_key
if startdate_production:
date = (datetime.strptime(startdate_production, '%d%m%Y'))
if date.day > 1:
date += relativedelta(months=1, day=1)
self.startdate_production = date.date()
else:
self.startdate_production = startdate_production

data = self.get_solar_forecast()

Expand All @@ -31,11 +38,14 @@ def get_solar_forecast(self):
data = solaredge.Solaredge(self.account_key)

# Get date when production started
start_production = data.get_data_period(site_id=self.site_id)["dataPeriod"]["startDate"]
if not self.startdate_production:
start_production = data.get_data_period(site_id=self.site_id)["dataPeriod"]["startDate"]
self.startdate_production = (datetime.strptime(start_production, "%Y-%m-%d")
+ relativedelta(months=1, day=1)).date()

# Get energy production per month from production start until now and store in dataframe
energy_month_average = data.get_energy(site_id=self.site_id,
start_date=start_production,
start_date=self.startdate_production,
end_date=last_month,
time_unit="MONTH")
# create dataframe with values per month
Expand Down Expand Up @@ -89,7 +99,7 @@ def average(row):
energy_produced_today_extra = max(0, energy_produced_today - energy_estimated_today)

# calculate the progress of the currently produced energy in relation to the forecast. A positive value means
# that the produced energy is ahead of forecast, a negative value means that it is behibd forecast
# that the produced energy is ahead of forecast, a negative value means that it is behind forecast
energy_production_progress = energy_produced_until_yesterday - energy_estimated_until_yesterday\
+ energy_produced_today_extra

Expand Down
18 changes: 12 additions & 6 deletions custom_components/solaredge_forecast/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,24 @@
"startday": "Startday of the forecast period",
"startmonth": "Startmonth of the forecast period",
"endday": "Endday of the forecast period",
"endmonth": "Endmonth of the forecast period"
"endmonth": "Endmonth of the forecast period",
"startdate production": "OPTIONAL: Date of start solar energy production %d%m%Y"
}
}
},
"error": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
"invalid_startday": "Invalid start date, Please ensure that the day and month combination for the start date is valid)",
"invalid_endday": "Invalid end date, Please ensure that the day and month combination for the end date is valid)",
"invalid_period": "Invalid forecast period. Please verify that the current day falls within the specified forecast period."
"invalid_period": "Invalid forecast period. Please verify that the current day falls within the specified forecast period.",
"invalid_startdate_production": "Invalid date, Please ensure that the date is valid and that it is at least 1 year in the past"
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
"invalid_startday": "Invalid start date, Please ensure that the day and month combination for the start date is valid)",
"invalid_endday": "Invalid end date, Please ensure that the day and month combination for the end date is valid)",
"invalid_period": "Invalid forecast period. Please verify that the current day falls within the specified forecast period."
"invalid_period": "Invalid forecast period. Please verify that the current day falls within the specified forecast period.",
"invalid_startdate_production": "Invalid date, Please ensure that the date is valid and that it is at least 1 year in the past"
}
},
"options": {
Expand All @@ -36,21 +39,24 @@
"startday": "Startday of the forecast period",
"startmonth": "Startmonth of the forecast period",
"endday": "Endday of the forecast period",
"endmonth": "Endmonth of the forecast period"
"endmonth": "Endmonth of the forecast period",
"startdate production": "OPTIONAL: Date of start solar energy production %d%m%Y"
}
}
},
"error": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
"invalid_startday": "Invalid start date, Please ensure that the day and month combination for the start date is valid)",
"invalid_endday": "Invalid end date, Please ensure that the day and month combination for the end date is valid)",
"invalid_period": "Invalid forecast period. Please verify that the current day falls within the specified forecast period."
"invalid_period": "Invalid forecast period. Please verify that the current day falls within the specified forecast period.",
"invalid_startdate_production": "Invalid date, Please ensure that the date is valid and that it is at least 1 year in the past"
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
"invalid_startday": "Invalid start date, Please ensure that the day and month combination for the start date is valid)",
"invalid_endday": "Invalid end date, Please ensure that the day and month combination for the end date is valid)",
"invalid_period": "Invalid forecast period. Please verify that the current day falls within the specified forecast period."
"invalid_period": "Invalid forecast period. Please verify that the current day falls within the specified forecast period.",
"invalid_startdate_production": "Invalid date, Please ensure that the date is valid and that it is at least 1 year in the past"
}
}
}
18 changes: 12 additions & 6 deletions custom_components/solaredge_forecast/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,24 @@
"startday": "Startday of the forecast period",
"startmonth": "Startmonth of the forecast period",
"endday": "Endday of the forecast period",
"endmonth": "Endmonth of the forecast period"
"endmonth": "Endmonth of the forecast period",
"startdate production": "OPTIONAL: Date of start solar energy production %d%m%Y"
}
}
},
"error": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
"invalid_startday": "Invalid start date, Please ensure that the day and month combination for the start date is valid)",
"invalid_endday": "Invalid end date, Please ensure that the day and month combination for the end date is valid)",
"invalid_period": "Invalid forecast period. Please verify that the current day falls within the specified forecast period."
"invalid_period": "Invalid forecast period. Please verify that the current day falls within the specified forecast period.",
"invalid_startdate_production": "Invalid date, Please ensure that the date is valid and that it is at least 1 year in the past"
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
"invalid_startday": "Invalid start date, Please ensure that the day and month combination for the start date is valid)",
"invalid_endday": "Invalid end date, Please ensure that the day and month combination for the end date is valid)",
"invalid_period": "Invalid forecast period. Please verify that the current day falls within the specified forecast period."
"invalid_period": "Invalid forecast period. Please verify that the current day falls within the specified forecast period.",
"invalid_startdate_production": "Invalid date, Please ensure that the date is valid and that it is at least 1 year in the past"
}
},
"options": {
Expand All @@ -36,21 +39,24 @@
"startday": "Startday of the forecast period",
"startmonth": "Startmonth of the forecast period",
"endday": "Endday of the forecast period",
"endmonth": "Endmonth of the forecast period"
"endmonth": "Endmonth of the forecast period",
"startdate production": "OPTIONAL: Date of start solar energy production %d%m%Y"
}
}
},
"error": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
"invalid_startday": "Invalid start date, Please ensure that the day and month combination for the start date is valid)",
"invalid_endday": "Invalid end date, Please ensure that the day and month combination for the end date is valid)",
"invalid_period": "Invalid forecast period. Please verify that the current day falls within the specified forecast period."
"invalid_period": "Invalid forecast period. Please verify that the current day falls within the specified forecast period.",
"invalid_startdate_production": "Invalid date, Please ensure that the date is valid and that it is at least 1 year in the past"
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
"invalid_startday": "Invalid start date, Please ensure that the day and month combination for the start date is valid)",
"invalid_endday": "Invalid end date, Please ensure that the day and month combination for the end date is valid)",
"invalid_period": "Invalid forecast period. Please verify that the current day falls within the specified forecast period."
"invalid_period": "Invalid forecast period. Please verify that the current day falls within the specified forecast period.",
"invalid_startdate_production": "Invalid date, Please ensure that the date is valid and that it is at least 1 year in the past"
}
}
}
Loading

0 comments on commit 4013381

Please sign in to comment.