initial commit
This commit is contained in:
0
custom_components/afvalinfo/__init__.py
Normal file
0
custom_components/afvalinfo/__init__.py
Normal file
BIN
custom_components/afvalinfo/__pycache__/__init__.cpython-310.pyc
Normal file
BIN
custom_components/afvalinfo/__pycache__/__init__.cpython-310.pyc
Normal file
Binary file not shown.
BIN
custom_components/afvalinfo/__pycache__/sensor.cpython-310.pyc
Normal file
BIN
custom_components/afvalinfo/__pycache__/sensor.cpython-310.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
0
custom_components/afvalinfo/const/__init__.py
Normal file
0
custom_components/afvalinfo/const/__init__.py
Normal file
Binary file not shown.
Binary file not shown.
88
custom_components/afvalinfo/const/const.py
Normal file
88
custom_components/afvalinfo/const/const.py
Normal file
@@ -0,0 +1,88 @@
|
||||
import logging
|
||||
from datetime import timedelta
|
||||
|
||||
SENSOR_TYPES = {
|
||||
"gft": ["GFT", "mdi:recycle"],
|
||||
"kerstboom": ["Kerstboom", "mdi:recycle"],
|
||||
"papier": ["Papier", "mdi:recycle"],
|
||||
"pbd": ["PBD", "mdi:recycle"],
|
||||
"restafval": ["Restafval", "mdi:recycle"],
|
||||
"takken": ["Takken", "mdi:recycle"],
|
||||
"textiel": ["Textiel", "mdi:recycle"],
|
||||
"trash_type_today": ["Today", "mdi:recycle"],
|
||||
"trash_type_tomorrow": ["Tomorrow", "mdi:recycle"],
|
||||
}
|
||||
|
||||
SENSOR_LOCATIONS_TO_URL = {
|
||||
"trashapi": [
|
||||
"http://trashapi.azurewebsites.net/trash?Location={0}&ZipCode={1}&HouseNumber={2}&HouseNumberSuffix={3}&DiftarCode={4}"
|
||||
]
|
||||
}
|
||||
|
||||
MONTH_TO_NUMBER = {
|
||||
"jan": "01",
|
||||
"feb": "02",
|
||||
"mrt": "03",
|
||||
"apr": "04",
|
||||
"mei": "05",
|
||||
"jun": "06",
|
||||
"jul": "07",
|
||||
"aug": "08",
|
||||
"sep": "09",
|
||||
"okt": "10",
|
||||
"nov": "11",
|
||||
"dec": "12",
|
||||
"januari": "01",
|
||||
"februari": "02",
|
||||
"maart": "03",
|
||||
"april": "04",
|
||||
"mei": "05",
|
||||
"juni": "06",
|
||||
"juli": "07",
|
||||
"augustus": "08",
|
||||
"september": "09",
|
||||
"oktober": "10",
|
||||
"november": "11",
|
||||
"december": "12",
|
||||
}
|
||||
|
||||
NUMBER_TO_MONTH = {
|
||||
1: "januari",
|
||||
2: "februari",
|
||||
3: "maart",
|
||||
4: "april",
|
||||
5: "mei",
|
||||
6: "juni",
|
||||
7: "juli",
|
||||
8: "augustus",
|
||||
9: "september",
|
||||
10: "oktober",
|
||||
11: "november",
|
||||
12: "december",
|
||||
}
|
||||
|
||||
CONF_CITY = "city"
|
||||
CONF_LOCATION = "location"
|
||||
CONF_POSTCODE = "postcode"
|
||||
CONF_STREET_NUMBER = "streetnumber"
|
||||
CONF_STREET_NUMBER_SUFFIX = "streetnumbersuffix"
|
||||
CONF_DATE_FORMAT = "dateformat"
|
||||
CONF_TIMESPAN_IN_DAYS = "timespanindays"
|
||||
CONF_LOCALE = "locale"
|
||||
CONF_ID = "id"
|
||||
CONF_NO_TRASH_TEXT = "notrashtext"
|
||||
CONF_DIFTAR_CODE = "diftarcode"
|
||||
SENSOR_PREFIX = "Afvalinfo "
|
||||
ATTR_ERROR = "error"
|
||||
ATTR_LAST_UPDATE = "last_update"
|
||||
ATTR_HIDDEN = "hidden"
|
||||
ATTR_IS_COLLECTION_DATE_TODAY = "is_collection_date_today"
|
||||
ATTR_DAYS_UNTIL_COLLECTION_DATE = "days_until_collection_date"
|
||||
ATTR_YEAR_MONTH_DAY_DATE = "year_month_day_date"
|
||||
ATTR_FRIENDLY_NAME = "friendly_name"
|
||||
ATTR_LAST_COLLECTION_DATE = "last_collection_date"
|
||||
ATTR_TOTAL_COLLECTIONS_THIS_YEAR = "total_collections_this_year"
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
MIN_TIME_BETWEEN_UPDATES = timedelta(hours=2, minutes=30)
|
||||
0
custom_components/afvalinfo/location/__init__.py
Normal file
0
custom_components/afvalinfo/location/__init__.py
Normal file
Binary file not shown.
Binary file not shown.
82
custom_components/afvalinfo/location/trashapi.py
Normal file
82
custom_components/afvalinfo/location/trashapi.py
Normal file
@@ -0,0 +1,82 @@
|
||||
from ..const.const import (
|
||||
MONTH_TO_NUMBER,
|
||||
SENSOR_LOCATIONS_TO_URL,
|
||||
_LOGGER,
|
||||
)
|
||||
from datetime import date, datetime, timedelta
|
||||
import urllib.request
|
||||
import urllib.error
|
||||
import requests
|
||||
|
||||
|
||||
class TrashApiAfval(object):
|
||||
def get_data(
|
||||
self,
|
||||
location,
|
||||
postcode,
|
||||
street_number,
|
||||
street_number_suffix,
|
||||
diftar_code,
|
||||
resources,
|
||||
):
|
||||
_LOGGER.debug("Updating Waste collection dates")
|
||||
|
||||
try:
|
||||
API_ENDPOINT = SENSOR_LOCATIONS_TO_URL["trashapi"][0].format(
|
||||
location, postcode, street_number, street_number_suffix, diftar_code
|
||||
)
|
||||
|
||||
r = requests.get(url=API_ENDPOINT)
|
||||
dataList = r.json()
|
||||
|
||||
# Place all possible values in the dictionary even if they are not necessary
|
||||
waste_dict = {}
|
||||
|
||||
# _LOGGER.warning(dataList)
|
||||
|
||||
for data in dataList:
|
||||
|
||||
# find gft.
|
||||
if "gft" in resources and data["name"].lower() == "gft":
|
||||
waste_dict["gft"] = data["date"].split("T")[0]
|
||||
# find kerstboom.
|
||||
if "kerstboom" in resources and data["name"].lower() == "kerstboom":
|
||||
waste_dict["kerstboom"] = data["date"].split("T")[0]
|
||||
# find papier
|
||||
if "papier" in resources and data["name"].lower() == "papier":
|
||||
waste_dict["papier"] = data["date"].split("T")[0]
|
||||
# find pbd.
|
||||
if "pbd" in resources and data["name"].lower() == "pbd":
|
||||
waste_dict["pbd"] = data["date"].split("T")[0]
|
||||
# find restafval.
|
||||
if "restafval" in resources and data["name"].lower() == "restafval":
|
||||
if (
|
||||
date.today()
|
||||
<= datetime.strptime(
|
||||
data["date"].split("T")[0], "%Y-%m-%d"
|
||||
).date()
|
||||
):
|
||||
waste_dict["restafval"] = data["date"].split("T")[0]
|
||||
else:
|
||||
waste_dict["restafvaldiftardate"] = data["date"].split("T")[0]
|
||||
waste_dict["restafvaldiftarcollections"] = data["totalThisYear"]
|
||||
# find takken
|
||||
if "takken" in resources and data["name"].lower() == "takken":
|
||||
waste_dict["takken"] = data["date"].split("T")[0]
|
||||
# find textiel
|
||||
if "textiel" in resources and data["name"].lower() == "textiel":
|
||||
waste_dict["textiel"] = data["date"].split("T")[0]
|
||||
|
||||
return waste_dict
|
||||
except urllib.error.URLError as exc:
|
||||
_LOGGER.error("Error occurred while fetching data: %r", exc.reason)
|
||||
return False
|
||||
except Exception as exc:
|
||||
_LOGGER.error(
|
||||
"""Error occurred. Please check the address with postcode: %r and huisnummer: %r%r on the website of your local waste collector in the gemeente: %r. It's probably a faulty address or the website of the waste collector is unreachable. If the address is working on the website of the local waste collector and this error still occured, please report the issue in the Github repository https://github.com/heyajohnny/afvalinfo with details of the location that isn't working""",
|
||||
postcode,
|
||||
street_number,
|
||||
street_number_suffix,
|
||||
location,
|
||||
)
|
||||
return False
|
||||
15
custom_components/afvalinfo/manifest.json
Normal file
15
custom_components/afvalinfo/manifest.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"domain": "afvalinfo",
|
||||
"name": "Afvalinfo",
|
||||
"version": "1.0.9",
|
||||
"documentation": "https://github.com/heyajohnny/afvalinfo",
|
||||
"issue_tracker": "https://github.com/heyajohnny/afvalinfo/issues",
|
||||
"dependencies": [],
|
||||
"codeowners": [
|
||||
"@heyajohnny"
|
||||
],
|
||||
"requirements": [
|
||||
"Babel==2.8.0",
|
||||
"python-dateutil==2.8.1"
|
||||
]
|
||||
}
|
||||
372
custom_components/afvalinfo/sensor.py
Normal file
372
custom_components/afvalinfo/sensor.py
Normal file
@@ -0,0 +1,372 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Sensor component for Afvalinfo
|
||||
Author: Johnny Visser
|
||||
"""
|
||||
|
||||
import voluptuous as vol
|
||||
from datetime import datetime, date, timedelta
|
||||
from dateutil.relativedelta import relativedelta
|
||||
import urllib.error
|
||||
from babel import Locale
|
||||
from babel.dates import format_date, format_datetime, format_time
|
||||
import re
|
||||
|
||||
from .const.const import (
|
||||
MIN_TIME_BETWEEN_UPDATES,
|
||||
_LOGGER,
|
||||
CONF_CITY,
|
||||
CONF_LOCATION,
|
||||
CONF_POSTCODE,
|
||||
CONF_STREET_NUMBER,
|
||||
CONF_STREET_NUMBER_SUFFIX,
|
||||
CONF_DATE_FORMAT,
|
||||
CONF_TIMESPAN_IN_DAYS,
|
||||
CONF_NO_TRASH_TEXT,
|
||||
CONF_DIFTAR_CODE,
|
||||
CONF_LOCALE,
|
||||
CONF_ID,
|
||||
SENSOR_PREFIX,
|
||||
ATTR_ERROR,
|
||||
ATTR_LAST_UPDATE,
|
||||
ATTR_HIDDEN,
|
||||
ATTR_DAYS_UNTIL_COLLECTION_DATE,
|
||||
ATTR_IS_COLLECTION_DATE_TODAY,
|
||||
ATTR_YEAR_MONTH_DAY_DATE,
|
||||
ATTR_FRIENDLY_NAME,
|
||||
ATTR_LAST_COLLECTION_DATE,
|
||||
ATTR_TOTAL_COLLECTIONS_THIS_YEAR,
|
||||
SENSOR_TYPES,
|
||||
)
|
||||
|
||||
from .location.trashapi import TrashApiAfval
|
||||
from .sensortomorrow import AfvalInfoTomorrowSensor
|
||||
from .sensortoday import AfvalInfoTodaySensor
|
||||
|
||||
from homeassistant.components.sensor import PLATFORM_SCHEMA
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.const import CONF_RESOURCES
|
||||
from homeassistant.util import Throttle
|
||||
from homeassistant.helpers.entity import Entity
|
||||
|
||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
||||
{
|
||||
vol.Required(CONF_RESOURCES, default=[]): vol.All(cv.ensure_list),
|
||||
vol.Optional(CONF_CITY, default=""): cv.string,
|
||||
vol.Optional(CONF_LOCATION, default="sliedrecht"): cv.string,
|
||||
vol.Required(CONF_POSTCODE, default="3361AB"): cv.string,
|
||||
vol.Required(CONF_STREET_NUMBER, default="1"): cv.string,
|
||||
vol.Optional(CONF_STREET_NUMBER_SUFFIX, default=""): cv.string,
|
||||
vol.Optional(CONF_DATE_FORMAT, default="%d-%m-%Y"): cv.string,
|
||||
vol.Optional(CONF_TIMESPAN_IN_DAYS, default="365"): cv.string,
|
||||
vol.Optional(CONF_LOCALE, default="en"): cv.string,
|
||||
vol.Optional(CONF_ID, default=""): cv.string,
|
||||
vol.Optional(CONF_NO_TRASH_TEXT, default="none"): cv.string,
|
||||
vol.Optional(CONF_DIFTAR_CODE, default=""): cv.string,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||
_LOGGER.debug("Setup Afvalinfo sensor")
|
||||
|
||||
location = config.get(CONF_CITY).lower().strip()
|
||||
if len(location) == 0:
|
||||
location = config.get(CONF_LOCATION).lower().strip()
|
||||
postcode = config.get(CONF_POSTCODE).strip()
|
||||
street_number = config.get(CONF_STREET_NUMBER)
|
||||
street_number_suffix = config.get(CONF_STREET_NUMBER_SUFFIX)
|
||||
date_format = config.get(CONF_DATE_FORMAT).strip()
|
||||
timespan_in_days = config.get(CONF_TIMESPAN_IN_DAYS)
|
||||
locale = config.get(CONF_LOCALE)
|
||||
id_name = config.get(CONF_ID)
|
||||
no_trash_text = config.get(CONF_NO_TRASH_TEXT)
|
||||
diftar_code = config.get(CONF_DIFTAR_CODE)
|
||||
|
||||
try:
|
||||
resources = config[CONF_RESOURCES].copy()
|
||||
|
||||
# filter the types from the dict if it's a dictionary
|
||||
if isinstance(resources[0], dict):
|
||||
resourcesMinusTodayAndTomorrow = [obj["type"] for obj in resources]
|
||||
else:
|
||||
resourcesMinusTodayAndTomorrow = resources
|
||||
|
||||
if "trash_type_today" in resourcesMinusTodayAndTomorrow:
|
||||
resourcesMinusTodayAndTomorrow.remove("trash_type_today")
|
||||
if "trash_type_tomorrow" in resourcesMinusTodayAndTomorrow:
|
||||
resourcesMinusTodayAndTomorrow.remove("trash_type_tomorrow")
|
||||
|
||||
data = AfvalinfoData(
|
||||
location,
|
||||
postcode,
|
||||
street_number,
|
||||
street_number_suffix,
|
||||
diftar_code,
|
||||
resourcesMinusTodayAndTomorrow,
|
||||
)
|
||||
except urllib.error.HTTPError as error:
|
||||
_LOGGER.error(error.reason)
|
||||
return False
|
||||
|
||||
entities = []
|
||||
|
||||
for resource in config[CONF_RESOURCES]:
|
||||
# old way, before 20220204
|
||||
if type(resource) == str:
|
||||
sensor_type = resource.lower()
|
||||
sensor_friendly_name = sensor_type
|
||||
# new way
|
||||
else:
|
||||
sensor_type = resource["type"].lower()
|
||||
if "friendly_name" in resource.keys():
|
||||
sensor_friendly_name = resource["friendly_name"]
|
||||
else:
|
||||
# If no friendly name is provided, use the sensor_type as friendly name
|
||||
sensor_friendly_name = sensor_type
|
||||
|
||||
# if sensor_type not in SENSOR_TYPES:
|
||||
if (
|
||||
sensor_type.title().lower() != "trash_type_today"
|
||||
and sensor_type.title().lower() != "trash_type_tomorrow"
|
||||
):
|
||||
entities.append(
|
||||
AfvalinfoSensor(
|
||||
data,
|
||||
sensor_type,
|
||||
sensor_friendly_name,
|
||||
date_format,
|
||||
timespan_in_days,
|
||||
locale,
|
||||
id_name,
|
||||
)
|
||||
)
|
||||
|
||||
# Add sensor -trash_type_today
|
||||
if sensor_type.title().lower() == "trash_type_today":
|
||||
today = AfvalInfoTodaySensor(
|
||||
data,
|
||||
sensor_type,
|
||||
sensor_friendly_name,
|
||||
entities,
|
||||
id_name,
|
||||
no_trash_text,
|
||||
)
|
||||
entities.append(today)
|
||||
# Add sensor -trash_type_tomorrow
|
||||
if sensor_type.title().lower() == "trash_type_tomorrow":
|
||||
tomorrow = AfvalInfoTomorrowSensor(
|
||||
data,
|
||||
sensor_type,
|
||||
sensor_friendly_name,
|
||||
entities,
|
||||
id_name,
|
||||
no_trash_text,
|
||||
)
|
||||
entities.append(tomorrow)
|
||||
|
||||
add_entities(entities)
|
||||
|
||||
|
||||
class AfvalinfoData(object):
|
||||
def __init__(
|
||||
self,
|
||||
location,
|
||||
postcode,
|
||||
street_number,
|
||||
street_number_suffix,
|
||||
diftar_code,
|
||||
resources,
|
||||
):
|
||||
self.data = None
|
||||
self.location = location
|
||||
self.postcode = postcode
|
||||
self.street_number = street_number
|
||||
self.street_number_suffix = street_number_suffix
|
||||
self.diftar_code = diftar_code
|
||||
self.resources = resources
|
||||
|
||||
@Throttle(MIN_TIME_BETWEEN_UPDATES)
|
||||
def update(self):
|
||||
_LOGGER.debug("Updating Waste collection dates")
|
||||
self.data = TrashApiAfval().get_data(
|
||||
self.location,
|
||||
self.postcode,
|
||||
self.street_number,
|
||||
self.street_number_suffix,
|
||||
self.diftar_code,
|
||||
self.resources,
|
||||
)
|
||||
|
||||
|
||||
class AfvalinfoSensor(Entity):
|
||||
def __init__(
|
||||
self,
|
||||
data,
|
||||
sensor_type,
|
||||
sensor_friendly_name,
|
||||
date_format,
|
||||
timespan_in_days,
|
||||
locale,
|
||||
id_name,
|
||||
):
|
||||
self.data = data
|
||||
self.type = sensor_type
|
||||
self.friendly_name = sensor_friendly_name
|
||||
self.date_format = date_format
|
||||
self.timespan_in_days = timespan_in_days
|
||||
self.locale = locale
|
||||
self._name = sensor_friendly_name
|
||||
self.entity_id = "sensor." + (
|
||||
(
|
||||
SENSOR_PREFIX
|
||||
+ (id_name + " " if len(id_name) > 0 else "")
|
||||
+ sensor_friendly_name
|
||||
)
|
||||
.lower()
|
||||
.replace(" ", "_")
|
||||
)
|
||||
self._attr_unique_id = (
|
||||
SENSOR_PREFIX
|
||||
+ (id_name + " " if len(id_name) > 0 else "")
|
||||
+ sensor_friendly_name
|
||||
)
|
||||
self._icon = SENSOR_TYPES[sensor_type][1]
|
||||
self._hidden = False
|
||||
self._error = False
|
||||
self._state = None
|
||||
self._last_update = None
|
||||
self._days_until_collection_date = None
|
||||
self._is_collection_date_today = False
|
||||
self._year_month_day_date = None
|
||||
self._last_collection_date = None
|
||||
self._total_collections_this_year = None
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
return self._icon
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
return self._state
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self):
|
||||
return {
|
||||
ATTR_ERROR: self._error,
|
||||
ATTR_FRIENDLY_NAME: self.friendly_name,
|
||||
ATTR_YEAR_MONTH_DAY_DATE: self._year_month_day_date,
|
||||
ATTR_LAST_UPDATE: self._last_update,
|
||||
ATTR_HIDDEN: self._hidden,
|
||||
ATTR_DAYS_UNTIL_COLLECTION_DATE: self._days_until_collection_date,
|
||||
ATTR_IS_COLLECTION_DATE_TODAY: self._is_collection_date_today,
|
||||
ATTR_LAST_COLLECTION_DATE: self._last_collection_date,
|
||||
ATTR_TOTAL_COLLECTIONS_THIS_YEAR: self._total_collections_this_year,
|
||||
}
|
||||
|
||||
@Throttle(MIN_TIME_BETWEEN_UPDATES)
|
||||
def update(self):
|
||||
self.data.update()
|
||||
waste_data = self.data.data
|
||||
self._error = False
|
||||
|
||||
try:
|
||||
if waste_data:
|
||||
if self.type in waste_data:
|
||||
collection_date = datetime.strptime(
|
||||
waste_data[self.type], "%Y-%m-%d"
|
||||
).date()
|
||||
|
||||
# Date in date format "%Y-%m-%d"
|
||||
self._year_month_day_date = str(collection_date)
|
||||
|
||||
if collection_date:
|
||||
# Set the values of the sensor
|
||||
self._last_update = datetime.today().strftime("%d-%m-%Y %H:%M")
|
||||
|
||||
# Is the collection date today?
|
||||
self._is_collection_date_today = date.today() == collection_date
|
||||
|
||||
if (
|
||||
self.type == "restafval"
|
||||
and "restafvaldiftardate" in waste_data
|
||||
):
|
||||
self._last_collection_date = str(
|
||||
datetime.strptime(
|
||||
waste_data["restafvaldiftardate"], "%Y-%m-%d"
|
||||
).date()
|
||||
)
|
||||
self._total_collections_this_year = waste_data[
|
||||
"restafvaldiftarcollections"
|
||||
]
|
||||
|
||||
# Days until collection date
|
||||
delta = collection_date - date.today()
|
||||
self._days_until_collection_date = delta.days
|
||||
|
||||
# Only show the value if the date is lesser than or equal to (today + timespan_in_days)
|
||||
if collection_date <= date.today() + relativedelta(
|
||||
days=int(self.timespan_in_days)
|
||||
):
|
||||
# if the date does not contain a named day or month, return the date as normal
|
||||
if (
|
||||
self.date_format.find("a") == -1
|
||||
and self.date_format.find("A") == -1
|
||||
and self.date_format.find("b") == -1
|
||||
and self.date_format.find("B") == -1
|
||||
):
|
||||
self._state = collection_date.strftime(self.date_format)
|
||||
# else convert the named values to the locale names
|
||||
else:
|
||||
edited_date_format = self.date_format.replace(
|
||||
"%a", "EEE"
|
||||
)
|
||||
edited_date_format = edited_date_format.replace(
|
||||
"%A", "EEEE"
|
||||
)
|
||||
edited_date_format = edited_date_format.replace(
|
||||
"%b", "MMM"
|
||||
)
|
||||
edited_date_format = edited_date_format.replace(
|
||||
"%B", "MMMM"
|
||||
)
|
||||
|
||||
# half babel, half date string... something like EEEE 04-MMMM-2020
|
||||
half_babel_half_date = collection_date.strftime(
|
||||
edited_date_format
|
||||
)
|
||||
|
||||
# replace the digits with qquoted digits 01 --> '01'
|
||||
half_babel_half_date = re.sub(
|
||||
r"(\d+)", r"'\1'", half_babel_half_date
|
||||
)
|
||||
# transform the EEE, EEEE etc... to a real locale date, with babel
|
||||
locale_date = format_date(
|
||||
collection_date,
|
||||
half_babel_half_date,
|
||||
locale=self.locale,
|
||||
)
|
||||
|
||||
self._state = locale_date
|
||||
else:
|
||||
self._hidden = True
|
||||
else:
|
||||
raise ValueError()
|
||||
else:
|
||||
raise ValueError()
|
||||
else:
|
||||
raise ValueError()
|
||||
except ValueError:
|
||||
self._error = True
|
||||
# self._state = None
|
||||
# self._hidden = True
|
||||
# self._days_until_collection_date = None
|
||||
# self._year_month_day_date = None
|
||||
# self._is_collection_date_today = False
|
||||
# self._last_collection_date = None
|
||||
# self._total_collections_this_year = None
|
||||
self._last_update = datetime.today().strftime("%d-%m-%Y %H:%M")
|
||||
85
custom_components/afvalinfo/sensortoday.py
Normal file
85
custom_components/afvalinfo/sensortoday.py
Normal file
@@ -0,0 +1,85 @@
|
||||
#!/usr/bin/env python3
|
||||
from datetime import datetime, date, timedelta
|
||||
from .const.const import (
|
||||
_LOGGER,
|
||||
ATTR_LAST_UPDATE,
|
||||
ATTR_FRIENDLY_NAME,
|
||||
ATTR_YEAR_MONTH_DAY_DATE,
|
||||
SENSOR_TYPES,
|
||||
SENSOR_PREFIX,
|
||||
)
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.util import Throttle
|
||||
|
||||
|
||||
class AfvalInfoTodaySensor(Entity):
|
||||
def __init__(
|
||||
self, data, sensor_type, sensor_friendly_name, entities, id_name, no_trash_text
|
||||
):
|
||||
self.data = data
|
||||
self.type = sensor_type
|
||||
self.friendly_name = sensor_friendly_name
|
||||
self._last_update = None
|
||||
self._name = sensor_friendly_name
|
||||
self.entity_id = "sensor." + (
|
||||
(
|
||||
SENSOR_PREFIX
|
||||
+ (id_name + " " if len(id_name) > 0 else "")
|
||||
+ sensor_friendly_name
|
||||
)
|
||||
.lower()
|
||||
.replace(" ", "_")
|
||||
)
|
||||
self._attr_unique_id = (
|
||||
SENSOR_PREFIX
|
||||
+ (id_name + " " if len(id_name) > 0 else "")
|
||||
+ sensor_friendly_name
|
||||
)
|
||||
self._no_trash_text = no_trash_text
|
||||
self._state = None
|
||||
self._icon = SENSOR_TYPES[sensor_type][1]
|
||||
self._entities = entities
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
return self._icon
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
return self._state
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self):
|
||||
return {ATTR_LAST_UPDATE: self._last_update}
|
||||
|
||||
@Throttle(timedelta(minutes=1))
|
||||
def update(self):
|
||||
self.data.update()
|
||||
self._last_update = datetime.today().strftime("%d-%m-%Y %H:%M")
|
||||
# use a tempState to change the real state only on a change...
|
||||
tempState = self._no_trash_text
|
||||
numberOfMatches = 0
|
||||
today = str(date.today().strftime("%Y-%m-%d"))
|
||||
for entity in self._entities:
|
||||
if entity.extra_state_attributes.get(ATTR_YEAR_MONTH_DAY_DATE) == today:
|
||||
# reset tempState to empty string
|
||||
if numberOfMatches == 0:
|
||||
tempState = ""
|
||||
numberOfMatches = numberOfMatches + 1
|
||||
# add trash friendly name or if no friendly name is provided, trash type to string
|
||||
tempState = (
|
||||
(
|
||||
tempState
|
||||
+ ", "
|
||||
+ entity.extra_state_attributes.get(ATTR_FRIENDLY_NAME)
|
||||
)
|
||||
).strip()
|
||||
if tempState.startswith(", "):
|
||||
tempState = tempState[2:]
|
||||
# only change state if the new state is different than the last state
|
||||
if tempState != self._state:
|
||||
self._state = tempState
|
||||
85
custom_components/afvalinfo/sensortomorrow.py
Normal file
85
custom_components/afvalinfo/sensortomorrow.py
Normal file
@@ -0,0 +1,85 @@
|
||||
#!/usr/bin/env python3
|
||||
from datetime import datetime, date, timedelta
|
||||
from .const.const import (
|
||||
_LOGGER,
|
||||
ATTR_LAST_UPDATE,
|
||||
ATTR_FRIENDLY_NAME,
|
||||
ATTR_YEAR_MONTH_DAY_DATE,
|
||||
SENSOR_TYPES,
|
||||
SENSOR_PREFIX,
|
||||
)
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.util import Throttle
|
||||
|
||||
|
||||
class AfvalInfoTomorrowSensor(Entity):
|
||||
def __init__(
|
||||
self, data, sensor_type, sensor_friendly_name, entities, id_name, no_trash_text
|
||||
):
|
||||
self.data = data
|
||||
self.type = sensor_type
|
||||
self.friendly_name = sensor_friendly_name
|
||||
self._last_update = None
|
||||
self._name = sensor_friendly_name
|
||||
self.entity_id = "sensor." + (
|
||||
(
|
||||
SENSOR_PREFIX
|
||||
+ (id_name + " " if len(id_name) > 0 else "")
|
||||
+ sensor_friendly_name
|
||||
)
|
||||
.lower()
|
||||
.replace(" ", "_")
|
||||
)
|
||||
self._attr_unique_id = (
|
||||
SENSOR_PREFIX
|
||||
+ (id_name + " " if len(id_name) > 0 else "")
|
||||
+ sensor_friendly_name
|
||||
)
|
||||
self._no_trash_text = no_trash_text
|
||||
self._state = None
|
||||
self._icon = SENSOR_TYPES[sensor_type][1]
|
||||
self._entities = entities
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
return self._icon
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
return self._state
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self):
|
||||
return {ATTR_LAST_UPDATE: self._last_update}
|
||||
|
||||
@Throttle(timedelta(minutes=1))
|
||||
def update(self):
|
||||
self.data.update()
|
||||
self._last_update = datetime.today().strftime("%d-%m-%Y %H:%M")
|
||||
# use a tempState to change the real state only on a change...
|
||||
tempState = self._no_trash_text
|
||||
numberOfMatches = 0
|
||||
tomorrow = str((date.today() + timedelta(days=1)).strftime("%Y-%m-%d"))
|
||||
for entity in self._entities:
|
||||
if entity.extra_state_attributes.get(ATTR_YEAR_MONTH_DAY_DATE) == tomorrow:
|
||||
# reset tempState to empty string
|
||||
if numberOfMatches == 0:
|
||||
tempState = ""
|
||||
numberOfMatches = numberOfMatches + 1
|
||||
# add trash name to string
|
||||
tempState = (
|
||||
(
|
||||
tempState
|
||||
+ ", "
|
||||
+ entity.extra_state_attributes.get(ATTR_FRIENDLY_NAME)
|
||||
)
|
||||
).strip()
|
||||
if tempState.startswith(", "):
|
||||
tempState = tempState[2:]
|
||||
# only change state if the new state is different than the last state
|
||||
if tempState != self._state:
|
||||
self._state = tempState
|
||||
Reference in New Issue
Block a user