From 625eb8a47672bfc4bc301d4380c3030b33bb876d Mon Sep 17 00:00:00 2001 From: dynasticorpheus Date: Sun, 12 Dec 2021 12:50:48 +0100 Subject: [PATCH 1/6] Import volume cubic meter symbol from const.py Import volume cubic meter symbol from const.py https://developers.home-assistant.io/docs/creating_component_code_review https://github.com/home-assistant/core/blob/dev/homeassistant/const.py#L535 --- custom_components/mindergas/sensor.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/custom_components/mindergas/sensor.py b/custom_components/mindergas/sensor.py index 70744c7..f9a3c8a 100644 --- a/custom_components/mindergas/sensor.py +++ b/custom_components/mindergas/sensor.py @@ -7,7 +7,7 @@ from homeassistant.util import dt from homeassistant.components.sensor import PLATFORM_SCHEMA from homeassistant.const import ( - ATTR_ATTRIBUTION, CONF_NAME, CONF_PASSWORD, CONF_SCAN_INTERVAL, CONF_USERNAME) + ATTR_ATTRIBUTION, CONF_NAME, CONF_PASSWORD, CONF_SCAN_INTERVAL, CONF_USERNAME, VOLUME_CUBIC_METERS) import homeassistant.helpers.config_validation as cv from homeassistant.helpers.entity import Entity from homeassistant.helpers.restore_state import RestoreEntity @@ -53,7 +53,7 @@ def name(self): @property def unit_of_measurement(self): # Return the unit of measurement of this entity, if any. - return 'm3' + return VOLUME_CUBIC_METERS @property def state(self): @@ -141,7 +141,7 @@ def name(self): @property def unit_of_measurement(self): # Return the unit of measurement of this entity, if any. - return 'm3' + return VOLUME_CUBIC_METERS @property def state(self): @@ -226,7 +226,7 @@ def name(self): @property def unit_of_measurement(self): # Return the unit of measurement of this entity, if any. - return 'm3' + return VOLUME_CUBIC_METERS @property def state(self): From c3ba2e6fa159ca2d97cafbf11e8b6698dcee0c4f Mon Sep 17 00:00:00 2001 From: dynasticorpheus Date: Sun, 12 Dec 2021 13:00:48 +0100 Subject: [PATCH 2/6] Remove deprecated device_state_attributes Remove deprecated device_state_attributes --- custom_components/mindergas/sensor.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/custom_components/mindergas/sensor.py b/custom_components/mindergas/sensor.py index f9a3c8a..dedc459 100644 --- a/custom_components/mindergas/sensor.py +++ b/custom_components/mindergas/sensor.py @@ -60,7 +60,7 @@ def state(self): return self._state @property - def device_state_attributes(self): + def extra_state_attributes(self): # Return the state attributes. return self._attributes @@ -148,7 +148,7 @@ def state(self): return self._state @property - def device_state_attributes(self): + def extra_state_attributes(self): # Return the state attributes. return self._attributes @@ -233,7 +233,7 @@ def state(self): return self._state @property - def device_state_attributes(self): + def extra_state_attributes(self): # Return the state attributes. return self._attributes From de4631bb237e4851bff29b1aa40bc3a0f28af716 Mon Sep 17 00:00:00 2001 From: dynasticorpheus Date: Wed, 5 Jan 2022 08:20:22 +0100 Subject: [PATCH 3/6] Downgrade to lxml==4.6.3 --- custom_components/mindergas/manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/mindergas/manifest.json b/custom_components/mindergas/manifest.json index 2c11b48..fb39366 100644 --- a/custom_components/mindergas/manifest.json +++ b/custom_components/mindergas/manifest.json @@ -3,7 +3,7 @@ "name": "mindergas", "documentation": "https://www.example.com", "requirements": [ - "lxml==4.6.4", + "lxml==4.6.3", "bs4==0.0.1" ], "dependencies": [], From fe0b0a8cfda7263c9168115c84a238f8f28248cc Mon Sep 17 00:00:00 2001 From: dynasticorpheus Date: Wed, 19 Jan 2022 10:15:33 +0100 Subject: [PATCH 4/6] remove lazy import, isort, black --- .isort.cfg | 2 + custom_components/mindergas/__init__.py | 6 +- custom_components/mindergas/sensor.py | 618 +++++++++++++----------- 3 files changed, 328 insertions(+), 298 deletions(-) create mode 100644 .isort.cfg diff --git a/.isort.cfg b/.isort.cfg new file mode 100644 index 0000000..79a6550 --- /dev/null +++ b/.isort.cfg @@ -0,0 +1,2 @@ +[settings] +multi_line_output=4 diff --git a/custom_components/mindergas/__init__.py b/custom_components/mindergas/__init__.py index a701b97..a7d0299 100644 --- a/custom_components/mindergas/__init__.py +++ b/custom_components/mindergas/__init__.py @@ -1,3 +1,3 @@ -"""Mindergas Sensor.""" - -__version__ = '0.0.1' +"""Mindergas Sensor.""" + +__version__ = "0.0.1" diff --git a/custom_components/mindergas/sensor.py b/custom_components/mindergas/sensor.py index dedc459..f9d7f56 100644 --- a/custom_components/mindergas/sensor.py +++ b/custom_components/mindergas/sensor.py @@ -1,295 +1,323 @@ -# Sensor for scrape Mindergas -import logging -import datetime -import json -import voluptuous as vol - -from homeassistant.util import dt -from homeassistant.components.sensor import PLATFORM_SCHEMA -from homeassistant.const import ( - ATTR_ATTRIBUTION, CONF_NAME, CONF_PASSWORD, CONF_SCAN_INTERVAL, CONF_USERNAME, VOLUME_CUBIC_METERS) -import homeassistant.helpers.config_validation as cv -from homeassistant.helpers.entity import Entity -from homeassistant.helpers.restore_state import RestoreEntity - -_LOGGER = logging.getLogger(__name__) - -ATTRIBUTION = 'Information provided by Mindergas' - -DEFAULT_NAME = 'mindergas' - -SCAN_INTERVAL = datetime.timedelta(seconds=3600) - -PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ - vol.Required(CONF_USERNAME): cv.string, - vol.Required(CONF_PASSWORD): cv.string, - vol.Optional(CONF_SCAN_INTERVAL, default=SCAN_INTERVAL): - cv.time_period, - vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, -}) - -def setup_platform(hass, config, add_entities, discovery_info=None): - username = config.get(CONF_USERNAME) - password = config.get(CONF_PASSWORD) - name = config.get(CONF_NAME) - add_entities([GasPrognose(username, password, name)], True) - add_entities([GasUsed(username, password, name)], True) - add_entities([GraadDag(username, password, name)], True) - -class GasPrognose(RestoreEntity): - def __init__(self, username, password, name): - # initialiseren sensor - self._username = username - self._password = password - self._name = name + '_prognose' - self._state = 0 - self._attributes = {'last_update': None} - self.update() - - @property - def name(self): - return self._name - - @property - def unit_of_measurement(self): - # Return the unit of measurement of this entity, if any. - return VOLUME_CUBIC_METERS - - @property - def state(self): - return self._state - - @property - def extra_state_attributes(self): - # Return the state attributes. - return self._attributes - - @property - def icon(self): - # Icon to use in the frontend. - return 'mdi:chart-line' - - def update(self): - import requests - from lxml import html - from bs4 import BeautifulSoup - LOGIN_URL = "https://www.mindergas.nl/users/sign_in/" - URL_DATA = "https://www.mindergas.nl/member/year_overview/new" - URL_DASHBOARD = "https://www.mindergas.nl/member/dashboard" - URL_RESULT = 'none' - n = 0 - while not URL_RESULT == URL_DASHBOARD : - if n == 10: - _LOGGER.error('Update of ' + str(self._name) + 'failed after ' + str(n) + 'attempts') - break - session_requests = requests.session() - - # Get login csrf token - result = session_requests.get(LOGIN_URL) - tree = html.fromstring(result.text) - authenticity_token = list(set(tree.xpath("//input[@name='authenticity_token']/@value")))[0] - - # Create payload - payload = { - "user[email]": self._username, - "user[password]": self._password, - "authenticity_token": authenticity_token} - - # Perform login - result = session_requests.post(LOGIN_URL, data=payload, headers=dict(referer=LOGIN_URL)) - URL_RESULT = result.url - n += 1 - - if URL_RESULT == URL_DASHBOARD: - try: - # Scrape url - raw_html = session_requests.get(URL_DATA, headers=dict(referer=URL_DATA)).text - data = BeautifulSoup(raw_html, 'html.parser') - - # Scrape prognose - div = data.find_all("div", class_="table_cell")[9] - result = round(eval(div.get_text().replace('m3','').replace(',' , '.').rstrip())) - self._attributes['last_update'] = dt.now().isoformat('T') - self._state = result - except: - self._state = 0 - else: - pass - - async def async_added_to_hass(self) -> None: - """Handle entity which will be added.""" - await super().async_added_to_hass() - state = await self.async_get_last_state() - if not state: - return - self._state = state.state - -class GasUsed(RestoreEntity): - def __init__(self, username, password, name): - # initialiseren sensor - self._username = username - self._password = password - self._name = name + '_used' - self._state = None - self._attributes = {'last_update': None} - self.update() - - @property - def name(self): - return self._name - - @property - def unit_of_measurement(self): - # Return the unit of measurement of this entity, if any. - return VOLUME_CUBIC_METERS - - @property - def state(self): - return self._state - - @property - def extra_state_attributes(self): - # Return the state attributes. - return self._attributes - - @property - def icon(self): - # Icon to use in the frontend. - return 'mdi:chart-line' - - def update(self): - import requests - from lxml import html - from bs4 import BeautifulSoup - LOGIN_URL = "https://www.mindergas.nl/users/sign_in/" - URL_DATA = "https://www.mindergas.nl/member/year_overview/new" - URL_DASHBOARD = "https://www.mindergas.nl/member/dashboard" - URL_RESULT = 'none' - n = 0 - while not URL_RESULT == URL_DASHBOARD : - if n == 10: - _LOGGER.error('Update of ' + str(self._name) + 'failed after ' + str(n) + 'attempts') - break - session_requests = requests.session() - - # Get login csrf token - result = session_requests.get(LOGIN_URL) - tree = html.fromstring(result.text) - authenticity_token = list(set(tree.xpath("//input[@name='authenticity_token']/@value")))[0] - - # Create payload - payload = { - "user[email]": self._username, - "user[password]": self._password, - "authenticity_token": authenticity_token} - - # Perform login - result = session_requests.post(LOGIN_URL, data=payload, headers=dict(referer=LOGIN_URL)) - URL_RESULT = result.url - n += 1 - - if URL_RESULT == URL_DASHBOARD: - # Scrape url - raw_html = session_requests.get(URL_DATA, headers=dict(referer=URL_DATA)).text - data = BeautifulSoup(raw_html, 'html.parser') - - # Scrape gas used - div = data.find_all("div", class_="table_cell")[1] - result = round(eval(div.get_text().replace('m3','').replace(',' , '.').rstrip())) - self._attributes['last_update'] = dt.now().isoformat('T') - self._state = result - else: - pass - - async def async_added_to_hass(self) -> None: - """Handle entity which will be added.""" - await super().async_added_to_hass() - state = await self.async_get_last_state() - if not state: - return - self._state = state.state - -class GraadDag(RestoreEntity): - def __init__(self, username, password, name): - # initialiseren sensor - self._username = username - self._password = password - self._name = name + '_graaddag' - self._state = None - self._attributes = {'last_update': None} - self.update() - - @property - def name(self): - return self._name - - @property - def unit_of_measurement(self): - # Return the unit of measurement of this entity, if any. - return VOLUME_CUBIC_METERS - - @property - def state(self): - return self._state - - @property - def extra_state_attributes(self): - # Return the state attributes. - return self._attributes - - @property - def icon(self): - # Icon to use in the frontend. - return 'mdi:chart-line' - - def update(self): - import requests - from lxml import html - from bs4 import BeautifulSoup - LOGIN_URL = "https://www.mindergas.nl/users/sign_in/" - URL_DATA = "https://www.mindergas.nl/member/year_overview/new" - URL_DASHBOARD = "https://www.mindergas.nl/member/dashboard" - URL_RESULT = 'none' - n = 0 - while not URL_RESULT == URL_DASHBOARD : - if n == 10: - _LOGGER.error('Update of ' + str(self._name) + 'failed after ' + str(n) + 'attempts') - break - session_requests = requests.session() - - # Get login csrf token - result = session_requests.get(LOGIN_URL) - tree = html.fromstring(result.text) - authenticity_token = list(set(tree.xpath("//input[@name='authenticity_token']/@value")))[0] - - # Create payload - payload = { - "user[email]": self._username, - "user[password]": self._password, - "authenticity_token": authenticity_token} - - # Perform login - result = session_requests.post(LOGIN_URL, data=payload, headers=dict(referer=LOGIN_URL)) - URL_RESULT = result.url - n += 1 - - if URL_RESULT == URL_DASHBOARD: - # Scrape url - raw_html = session_requests.get(URL_DATA, headers=dict(referer=URL_DATA)).text - data = BeautifulSoup(raw_html, 'html.parser') - - # Scrape graaddag - div = data.find_all("div", class_="table_cell")[5] - result = eval(div.get_text().replace('m3', '').replace(',', '.').rstrip()) - self._attributes['last_update'] = dt.now().isoformat('T') - self._state = result - else: - pass - - async def async_added_to_hass(self) -> None: - """Handle entity which will be added.""" - await super().async_added_to_hass() - state = await self.async_get_last_state() - if not state: - return - self._state = state.state +# Sensor for scrape Mindergas +import datetime +import logging + +import homeassistant.helpers.config_validation as cv +import requests +import voluptuous as vol +from bs4 import BeautifulSoup +from homeassistant.components.sensor import PLATFORM_SCHEMA +from homeassistant.const import ( + CONF_NAME, + CONF_PASSWORD, + CONF_SCAN_INTERVAL, + CONF_USERNAME, + VOLUME_CUBIC_METERS, +) +from homeassistant.helpers.restore_state import RestoreEntity +from homeassistant.util import dt +from lxml import html + +_LOGGER = logging.getLogger(__name__) + +ATTRIBUTION = "Information provided by Mindergas" + +DEFAULT_NAME = "mindergas" + +SCAN_INTERVAL = datetime.timedelta(seconds=21600) + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( + { + vol.Required(CONF_USERNAME): cv.string, + vol.Required(CONF_PASSWORD): cv.string, + vol.Optional(CONF_SCAN_INTERVAL, default=SCAN_INTERVAL): cv.time_period, + vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, + } +) + + +def setup_platform(hass, config, add_entities, discovery_info=None): + username = config.get(CONF_USERNAME) + password = config.get(CONF_PASSWORD) + name = config.get(CONF_NAME) + add_entities([GasPrognose(username, password, name)], True) + add_entities([GasUsed(username, password, name)], True) + add_entities([GraadDag(username, password, name)], True) + + +class GasPrognose(RestoreEntity): + def __init__(self, username, password, name): + # initialiseren sensor + self._username = username + self._password = password + self._name = name + "_prognose" + self._state = 0 + self._attributes = {"last_update": None} + self.update() + + @property + def name(self): + return self._name + + @property + def unit_of_measurement(self): + # Return the unit of measurement of this entity, if any. + return VOLUME_CUBIC_METERS + + @property + def state(self): + return self._state + + @property + def extra_state_attributes(self): + # Return the state attributes. + return self._attributes + + @property + def icon(self): + # Icon to use in the frontend. + return "mdi:chart-line" + + def update(self): + + LOGIN_URL = "https://www.mindergas.nl/users/sign_in/" + URL_DATA = "https://www.mindergas.nl/member/year_overview/new" + URL_DASHBOARD = "https://www.mindergas.nl/member/dashboard" + URL_RESULT = "none" + n = 0 + while not URL_RESULT == URL_DASHBOARD: + if n == 10: + _LOGGER.error( + "Update of " + str(self._name) + "failed after " + str(n) + "attempts" + ) + break + session_requests = requests.session() + + # Get login csrf token + result = session_requests.get(LOGIN_URL) + tree = html.fromstring(result.text) + authenticity_token = list( + set(tree.xpath("//input[@name='authenticity_token']/@value")) + )[0] + + # Create payload + payload = { + "user[email]": self._username, + "user[password]": self._password, + "authenticity_token": authenticity_token, + } + + # Perform login + result = session_requests.post(LOGIN_URL, data=payload, headers=dict(referer=LOGIN_URL)) + URL_RESULT = result.url + n += 1 + + if URL_RESULT == URL_DASHBOARD: + try: + # Scrape url + raw_html = session_requests.get(URL_DATA, headers=dict(referer=URL_DATA)).text + data = BeautifulSoup(raw_html, "html.parser") + + # Scrape prognose + div = data.find_all("div", class_="table_cell")[9] + result = round( + eval(div.get_text().replace("m3", "").replace(",", ".").rstrip()) + ) + self._attributes["last_update"] = dt.now().isoformat("T") + self._state = result + except: + self._state = 0 + else: + pass + + async def async_added_to_hass(self) -> None: + """Handle entity which will be added.""" + await super().async_added_to_hass() + state = await self.async_get_last_state() + if not state: + return + self._state = state.state + + +class GasUsed(RestoreEntity): + def __init__(self, username, password, name): + # initialiseren sensor + self._username = username + self._password = password + self._name = name + "_used" + self._state = None + self._attributes = {"last_update": None} + self.update() + + @property + def name(self): + return self._name + + @property + def unit_of_measurement(self): + # Return the unit of measurement of this entity, if any. + return VOLUME_CUBIC_METERS + + @property + def state(self): + return self._state + + @property + def extra_state_attributes(self): + # Return the state attributes. + return self._attributes + + @property + def icon(self): + # Icon to use in the frontend. + return "mdi:chart-line" + + def update(self): + import requests + from bs4 import BeautifulSoup + from lxml import html + + LOGIN_URL = "https://www.mindergas.nl/users/sign_in/" + URL_DATA = "https://www.mindergas.nl/member/year_overview/new" + URL_DASHBOARD = "https://www.mindergas.nl/member/dashboard" + URL_RESULT = "none" + n = 0 + while not URL_RESULT == URL_DASHBOARD: + if n == 10: + _LOGGER.error( + "Update of " + str(self._name) + "failed after " + str(n) + "attempts" + ) + break + session_requests = requests.session() + + # Get login csrf token + result = session_requests.get(LOGIN_URL) + tree = html.fromstring(result.text) + authenticity_token = list( + set(tree.xpath("//input[@name='authenticity_token']/@value")) + )[0] + + # Create payload + payload = { + "user[email]": self._username, + "user[password]": self._password, + "authenticity_token": authenticity_token, + } + + # Perform login + result = session_requests.post(LOGIN_URL, data=payload, headers=dict(referer=LOGIN_URL)) + URL_RESULT = result.url + n += 1 + + if URL_RESULT == URL_DASHBOARD: + # Scrape url + raw_html = session_requests.get(URL_DATA, headers=dict(referer=URL_DATA)).text + data = BeautifulSoup(raw_html, "html.parser") + + # Scrape gas used + div = data.find_all("div", class_="table_cell")[1] + result = round(eval(div.get_text().replace("m3", "").replace(",", ".").rstrip())) + self._attributes["last_update"] = dt.now().isoformat("T") + self._state = result + else: + pass + + async def async_added_to_hass(self) -> None: + """Handle entity which will be added.""" + await super().async_added_to_hass() + state = await self.async_get_last_state() + if not state: + return + self._state = state.state + + +class GraadDag(RestoreEntity): + def __init__(self, username, password, name): + # initialiseren sensor + self._username = username + self._password = password + self._name = name + "_graaddag" + self._state = None + self._attributes = {"last_update": None} + self.update() + + @property + def name(self): + return self._name + + @property + def unit_of_measurement(self): + # Return the unit of measurement of this entity, if any. + return VOLUME_CUBIC_METERS + + @property + def state(self): + return self._state + + @property + def extra_state_attributes(self): + # Return the state attributes. + return self._attributes + + @property + def icon(self): + # Icon to use in the frontend. + return "mdi:chart-line" + + def update(self): + import requests + from bs4 import BeautifulSoup + from lxml import html + + LOGIN_URL = "https://www.mindergas.nl/users/sign_in/" + URL_DATA = "https://www.mindergas.nl/member/year_overview/new" + URL_DASHBOARD = "https://www.mindergas.nl/member/dashboard" + URL_RESULT = "none" + n = 0 + while not URL_RESULT == URL_DASHBOARD: + if n == 10: + _LOGGER.error( + "Update of " + str(self._name) + "failed after " + str(n) + "attempts" + ) + break + session_requests = requests.session() + + # Get login csrf token + result = session_requests.get(LOGIN_URL) + tree = html.fromstring(result.text) + authenticity_token = list( + set(tree.xpath("//input[@name='authenticity_token']/@value")) + )[0] + + # Create payload + payload = { + "user[email]": self._username, + "user[password]": self._password, + "authenticity_token": authenticity_token, + } + + # Perform login + result = session_requests.post(LOGIN_URL, data=payload, headers=dict(referer=LOGIN_URL)) + URL_RESULT = result.url + n += 1 + + if URL_RESULT == URL_DASHBOARD: + # Scrape url + raw_html = session_requests.get(URL_DATA, headers=dict(referer=URL_DATA)).text + data = BeautifulSoup(raw_html, "html.parser") + + # Scrape graaddag + div = data.find_all("div", class_="table_cell")[5] + result = eval(div.get_text().replace("m3", "").replace(",", ".").rstrip()) + self._attributes["last_update"] = dt.now().isoformat("T") + self._state = result + else: + pass + + async def async_added_to_hass(self) -> None: + """Handle entity which will be added.""" + await super().async_added_to_hass() + state = await self.async_get_last_state() + if not state: + return + self._state = state.state From eb5a9662d877eaeb1c8550886378b2febedbb2ec Mon Sep 17 00:00:00 2001 From: dynasticorpheus Date: Wed, 19 Jan 2022 10:31:54 +0100 Subject: [PATCH 5/6] remove lazy imports, global vars --- custom_components/mindergas/sensor.py | 19 +- custom_components/mindergas/sensor.py.save | 321 +++++++++++++++++++++ 2 files changed, 325 insertions(+), 15 deletions(-) create mode 100644 custom_components/mindergas/sensor.py.save diff --git a/custom_components/mindergas/sensor.py b/custom_components/mindergas/sensor.py index f9d7f56..0f2b33d 100644 --- a/custom_components/mindergas/sensor.py +++ b/custom_components/mindergas/sensor.py @@ -35,6 +35,10 @@ } ) +LOGIN_URL = "https://www.mindergas.nl/users/sign_in/" +URL_DATA = "https://www.mindergas.nl/member/year_overview/new" +URL_DASHBOARD = "https://www.mindergas.nl/member/dashboard" + def setup_platform(hass, config, add_entities, discovery_info=None): username = config.get(CONF_USERNAME) @@ -80,9 +84,6 @@ def icon(self): def update(self): - LOGIN_URL = "https://www.mindergas.nl/users/sign_in/" - URL_DATA = "https://www.mindergas.nl/member/year_overview/new" - URL_DASHBOARD = "https://www.mindergas.nl/member/dashboard" URL_RESULT = "none" n = 0 while not URL_RESULT == URL_DASHBOARD: @@ -173,13 +174,7 @@ def icon(self): return "mdi:chart-line" def update(self): - import requests - from bs4 import BeautifulSoup - from lxml import html - LOGIN_URL = "https://www.mindergas.nl/users/sign_in/" - URL_DATA = "https://www.mindergas.nl/member/year_overview/new" - URL_DASHBOARD = "https://www.mindergas.nl/member/dashboard" URL_RESULT = "none" n = 0 while not URL_RESULT == URL_DASHBOARD: @@ -265,13 +260,7 @@ def icon(self): return "mdi:chart-line" def update(self): - import requests - from bs4 import BeautifulSoup - from lxml import html - LOGIN_URL = "https://www.mindergas.nl/users/sign_in/" - URL_DATA = "https://www.mindergas.nl/member/year_overview/new" - URL_DASHBOARD = "https://www.mindergas.nl/member/dashboard" URL_RESULT = "none" n = 0 while not URL_RESULT == URL_DASHBOARD: diff --git a/custom_components/mindergas/sensor.py.save b/custom_components/mindergas/sensor.py.save new file mode 100644 index 0000000..79d91ad --- /dev/null +++ b/custom_components/mindergas/sensor.py.save @@ -0,0 +1,321 @@ +# Sensor for scrape Mindergas +import datetime +import logging + +import homeassistant.helpers.config_validation as cv +import requests +import voluptuous as vol +from bs4 import BeautifulSoup +from homeassistant.components.sensor import PLATFORM_SCHEMA +from homeassistant.const import ( + CONF_NAME, + CONF_PASSWORD, + CONF_SCAN_INTERVAL, + CONF_USERNAME, + VOLUME_CUBIC_METERS, +) +from homeassistant.helpers.restore_state import RestoreEntity +from homeassistant.util import dt +from lxml import html + +_LOGGER = logging.getLogger(__name__) + +ATTRIBUTION = "Information provided by Mindergas" + +DEFAULT_NAME = "mindergas" + +SCAN_INTERVAL = datetime.timedelta(seconds=21600) + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( + { + vol.Required(CONF_USERNAME): cv.string, + vol.Required(CONF_PASSWORD): cv.string, + vol.Optional(CONF_SCAN_INTERVAL, default=SCAN_INTERVAL): cv.time_period, + vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, + } +) + + + +def setup_platform(hass, config, add_entities, discovery_info=None): + username = config.get(CONF_USERNAME) + password = config.get(CONF_PASSWORD) + name = config.get(CONF_NAME) + add_entities([GasPrognose(username, password, name)], True) + add_entities([GasUsed(username, password, name)], True) + add_entities([GraadDag(username, password, name)], True) + + +class GasPrognose(RestoreEntity): + def __init__(self, username, password, name): + # initialiseren sensor + self._username = username + self._password = password + self._name = name + "_prognose" + self._state = 0 + self._attributes = {"last_update": None} + self.update() + + @property + def name(self): + return self._name + + @property + def unit_of_measurement(self): + # Return the unit of measurement of this entity, if any. + return VOLUME_CUBIC_METERS + + @property + def state(self): + return self._state + + @property + def extra_state_attributes(self): + # Return the state attributes. + return self._attributes + + @property + def icon(self): + # Icon to use in the frontend. + return "mdi:chart-line" + + def update(self): + + URL_RESULT = "none" + n = 0 + while not URL_RESULT == URL_DASHBOARD: + if n == 10: + _LOGGER.error( + "Update of " + str(self._name) + "failed after " + str(n) + "attempts" + ) + break + session_requests = requests.session() + + # Get login csrf token + result = session_requests.get(LOGIN_URL) + tree = html.fromstring(result.text) + authenticity_token = list( + set(tree.xpath("//input[@name='authenticity_token']/@value")) + )[0] + + # Create payload + payload = { + "user[email]": self._username, + "user[password]": self._password, + "authenticity_token": authenticity_token, + } + + # Perform login + result = session_requests.post(LOGIN_URL, data=payload, headers=dict(referer=LOGIN_URL)) + URL_RESULT = result.url + n += 1 + + if URL_RESULT == URL_DASHBOARD: + try: + # Scrape url + raw_html = session_requests.get(URL_DATA, headers=dict(referer=URL_DATA)).text + data = BeautifulSoup(raw_html, "html.parser") + + # Scrape prognose + div = data.find_all("div", class_="table_cell")[9] + result = round( + eval(div.get_text().replace("m3", "").replace(",", ".").rstrip()) + ) + self._attributes["last_update"] = dt.now().isoformat("T") + self._state = result + except: + self._state = 0 + else: + pass + + async def async_added_to_hass(self) -> None: + """Handle entity which will be added.""" + await super().async_added_to_hass() + state = await self.async_get_last_state() + if not state: + return + self._state = state.state + + +class GasUsed(RestoreEntity): + def __init__(self, username, password, name): + # initialiseren sensor + self._username = username + self._password = password + self._name = name + "_used" + self._state = None + self._attributes = {"last_update": None} + self.update() + + @property + def name(self): + return self._name + + @property + def unit_of_measurement(self): + # Return the unit of measurement of this entity, if any. + return VOLUME_CUBIC_METERS + + @property + def state(self): + return self._state + + @property + def extra_state_attributes(self): + # Return the state attributes. + return self._attributes + + @property + def icon(self): + # Icon to use in the frontend. + return "mdi:chart-line" + + def update(self): + import requests + from bs4 import BeautifulSoup + from lxml import html + + LOGIN_URL = "https://www.mindergas.nl/users/sign_in/" + URL_DATA = "https://www.mindergas.nl/member/year_overview/new" + URL_DASHBOARD = "https://www.mindergas.nl/member/dashboard" + URL_RESULT = "none" + n = 0 + while not URL_RESULT == URL_DASHBOARD: + if n == 10: + _LOGGER.error( + "Update of " + str(self._name) + "failed after " + str(n) + "attempts" + ) + break + session_requests = requests.session() + + # Get login csrf token + result = session_requests.get(LOGIN_URL) + tree = html.fromstring(result.text) + authenticity_token = list( + set(tree.xpath("//input[@name='authenticity_token']/@value")) + )[0] + + # Create payload + payload = { + "user[email]": self._username, + "user[password]": self._password, + "authenticity_token": authenticity_token, + } + + # Perform login + result = session_requests.post(LOGIN_URL, data=payload, headers=dict(referer=LOGIN_URL)) + URL_RESULT = result.url + n += 1 + + if URL_RESULT == URL_DASHBOARD: + # Scrape url + raw_html = session_requests.get(URL_DATA, headers=dict(referer=URL_DATA)).text + data = BeautifulSoup(raw_html, "html.parser") + + # Scrape gas used + div = data.find_all("div", class_="table_cell")[1] + result = round(eval(div.get_text().replace("m3", "").replace(",", ".").rstrip())) + self._attributes["last_update"] = dt.now().isoformat("T") + self._state = result + else: + pass + + async def async_added_to_hass(self) -> None: + """Handle entity which will be added.""" + await super().async_added_to_hass() + state = await self.async_get_last_state() + if not state: + return + self._state = state.state + + +class GraadDag(RestoreEntity): + def __init__(self, username, password, name): + # initialiseren sensor + self._username = username + self._password = password + self._name = name + "_graaddag" + self._state = None + self._attributes = {"last_update": None} + self.update() + + @property + def name(self): + return self._name + + @property + def unit_of_measurement(self): + # Return the unit of measurement of this entity, if any. + return VOLUME_CUBIC_METERS + + @property + def state(self): + return self._state + + @property + def extra_state_attributes(self): + # Return the state attributes. + return self._attributes + + @property + def icon(self): + # Icon to use in the frontend. + return "mdi:chart-line" + + def update(self): + import requests + from bs4 import BeautifulSoup + from lxml import html + + LOGIN_URL = "https://www.mindergas.nl/users/sign_in/" + URL_DATA = "https://www.mindergas.nl/member/year_overview/new" + URL_DASHBOARD = "https://www.mindergas.nl/member/dashboard" + URL_RESULT = "none" + n = 0 + while not URL_RESULT == URL_DASHBOARD: + if n == 10: + _LOGGER.error( + "Update of " + str(self._name) + "failed after " + str(n) + "attempts" + ) + break + session_requests = requests.session() + + # Get login csrf token + result = session_requests.get(LOGIN_URL) + tree = html.fromstring(result.text) + authenticity_token = list( + set(tree.xpath("//input[@name='authenticity_token']/@value")) + )[0] + + # Create payload + payload = { + "user[email]": self._username, + "user[password]": self._password, + "authenticity_token": authenticity_token, + } + + # Perform login + result = session_requests.post(LOGIN_URL, data=payload, headers=dict(referer=LOGIN_URL)) + URL_RESULT = result.url + n += 1 + + if URL_RESULT == URL_DASHBOARD: + # Scrape url + raw_html = session_requests.get(URL_DATA, headers=dict(referer=URL_DATA)).text + data = BeautifulSoup(raw_html, "html.parser") + + # Scrape graaddag + div = data.find_all("div", class_="table_cell")[5] + result = eval(div.get_text().replace("m3", "").replace(",", ".").rstrip()) + self._attributes["last_update"] = dt.now().isoformat("T") + self._state = result + else: + pass + + async def async_added_to_hass(self) -> None: + """Handle entity which will be added.""" + await super().async_added_to_hass() + state = await self.async_get_last_state() + if not state: + return + self._state = state.state From 44832a169c11960daca65fcd6344bfe5ff41cce6 Mon Sep 17 00:00:00 2001 From: dynasticorpheus Date: Wed, 19 Jan 2022 10:37:47 +0100 Subject: [PATCH 6/6] remove backup --- custom_components/mindergas/sensor.py.save | 321 --------------------- 1 file changed, 321 deletions(-) delete mode 100644 custom_components/mindergas/sensor.py.save diff --git a/custom_components/mindergas/sensor.py.save b/custom_components/mindergas/sensor.py.save deleted file mode 100644 index 79d91ad..0000000 --- a/custom_components/mindergas/sensor.py.save +++ /dev/null @@ -1,321 +0,0 @@ -# Sensor for scrape Mindergas -import datetime -import logging - -import homeassistant.helpers.config_validation as cv -import requests -import voluptuous as vol -from bs4 import BeautifulSoup -from homeassistant.components.sensor import PLATFORM_SCHEMA -from homeassistant.const import ( - CONF_NAME, - CONF_PASSWORD, - CONF_SCAN_INTERVAL, - CONF_USERNAME, - VOLUME_CUBIC_METERS, -) -from homeassistant.helpers.restore_state import RestoreEntity -from homeassistant.util import dt -from lxml import html - -_LOGGER = logging.getLogger(__name__) - -ATTRIBUTION = "Information provided by Mindergas" - -DEFAULT_NAME = "mindergas" - -SCAN_INTERVAL = datetime.timedelta(seconds=21600) - -PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( - { - vol.Required(CONF_USERNAME): cv.string, - vol.Required(CONF_PASSWORD): cv.string, - vol.Optional(CONF_SCAN_INTERVAL, default=SCAN_INTERVAL): cv.time_period, - vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, - } -) - - - -def setup_platform(hass, config, add_entities, discovery_info=None): - username = config.get(CONF_USERNAME) - password = config.get(CONF_PASSWORD) - name = config.get(CONF_NAME) - add_entities([GasPrognose(username, password, name)], True) - add_entities([GasUsed(username, password, name)], True) - add_entities([GraadDag(username, password, name)], True) - - -class GasPrognose(RestoreEntity): - def __init__(self, username, password, name): - # initialiseren sensor - self._username = username - self._password = password - self._name = name + "_prognose" - self._state = 0 - self._attributes = {"last_update": None} - self.update() - - @property - def name(self): - return self._name - - @property - def unit_of_measurement(self): - # Return the unit of measurement of this entity, if any. - return VOLUME_CUBIC_METERS - - @property - def state(self): - return self._state - - @property - def extra_state_attributes(self): - # Return the state attributes. - return self._attributes - - @property - def icon(self): - # Icon to use in the frontend. - return "mdi:chart-line" - - def update(self): - - URL_RESULT = "none" - n = 0 - while not URL_RESULT == URL_DASHBOARD: - if n == 10: - _LOGGER.error( - "Update of " + str(self._name) + "failed after " + str(n) + "attempts" - ) - break - session_requests = requests.session() - - # Get login csrf token - result = session_requests.get(LOGIN_URL) - tree = html.fromstring(result.text) - authenticity_token = list( - set(tree.xpath("//input[@name='authenticity_token']/@value")) - )[0] - - # Create payload - payload = { - "user[email]": self._username, - "user[password]": self._password, - "authenticity_token": authenticity_token, - } - - # Perform login - result = session_requests.post(LOGIN_URL, data=payload, headers=dict(referer=LOGIN_URL)) - URL_RESULT = result.url - n += 1 - - if URL_RESULT == URL_DASHBOARD: - try: - # Scrape url - raw_html = session_requests.get(URL_DATA, headers=dict(referer=URL_DATA)).text - data = BeautifulSoup(raw_html, "html.parser") - - # Scrape prognose - div = data.find_all("div", class_="table_cell")[9] - result = round( - eval(div.get_text().replace("m3", "").replace(",", ".").rstrip()) - ) - self._attributes["last_update"] = dt.now().isoformat("T") - self._state = result - except: - self._state = 0 - else: - pass - - async def async_added_to_hass(self) -> None: - """Handle entity which will be added.""" - await super().async_added_to_hass() - state = await self.async_get_last_state() - if not state: - return - self._state = state.state - - -class GasUsed(RestoreEntity): - def __init__(self, username, password, name): - # initialiseren sensor - self._username = username - self._password = password - self._name = name + "_used" - self._state = None - self._attributes = {"last_update": None} - self.update() - - @property - def name(self): - return self._name - - @property - def unit_of_measurement(self): - # Return the unit of measurement of this entity, if any. - return VOLUME_CUBIC_METERS - - @property - def state(self): - return self._state - - @property - def extra_state_attributes(self): - # Return the state attributes. - return self._attributes - - @property - def icon(self): - # Icon to use in the frontend. - return "mdi:chart-line" - - def update(self): - import requests - from bs4 import BeautifulSoup - from lxml import html - - LOGIN_URL = "https://www.mindergas.nl/users/sign_in/" - URL_DATA = "https://www.mindergas.nl/member/year_overview/new" - URL_DASHBOARD = "https://www.mindergas.nl/member/dashboard" - URL_RESULT = "none" - n = 0 - while not URL_RESULT == URL_DASHBOARD: - if n == 10: - _LOGGER.error( - "Update of " + str(self._name) + "failed after " + str(n) + "attempts" - ) - break - session_requests = requests.session() - - # Get login csrf token - result = session_requests.get(LOGIN_URL) - tree = html.fromstring(result.text) - authenticity_token = list( - set(tree.xpath("//input[@name='authenticity_token']/@value")) - )[0] - - # Create payload - payload = { - "user[email]": self._username, - "user[password]": self._password, - "authenticity_token": authenticity_token, - } - - # Perform login - result = session_requests.post(LOGIN_URL, data=payload, headers=dict(referer=LOGIN_URL)) - URL_RESULT = result.url - n += 1 - - if URL_RESULT == URL_DASHBOARD: - # Scrape url - raw_html = session_requests.get(URL_DATA, headers=dict(referer=URL_DATA)).text - data = BeautifulSoup(raw_html, "html.parser") - - # Scrape gas used - div = data.find_all("div", class_="table_cell")[1] - result = round(eval(div.get_text().replace("m3", "").replace(",", ".").rstrip())) - self._attributes["last_update"] = dt.now().isoformat("T") - self._state = result - else: - pass - - async def async_added_to_hass(self) -> None: - """Handle entity which will be added.""" - await super().async_added_to_hass() - state = await self.async_get_last_state() - if not state: - return - self._state = state.state - - -class GraadDag(RestoreEntity): - def __init__(self, username, password, name): - # initialiseren sensor - self._username = username - self._password = password - self._name = name + "_graaddag" - self._state = None - self._attributes = {"last_update": None} - self.update() - - @property - def name(self): - return self._name - - @property - def unit_of_measurement(self): - # Return the unit of measurement of this entity, if any. - return VOLUME_CUBIC_METERS - - @property - def state(self): - return self._state - - @property - def extra_state_attributes(self): - # Return the state attributes. - return self._attributes - - @property - def icon(self): - # Icon to use in the frontend. - return "mdi:chart-line" - - def update(self): - import requests - from bs4 import BeautifulSoup - from lxml import html - - LOGIN_URL = "https://www.mindergas.nl/users/sign_in/" - URL_DATA = "https://www.mindergas.nl/member/year_overview/new" - URL_DASHBOARD = "https://www.mindergas.nl/member/dashboard" - URL_RESULT = "none" - n = 0 - while not URL_RESULT == URL_DASHBOARD: - if n == 10: - _LOGGER.error( - "Update of " + str(self._name) + "failed after " + str(n) + "attempts" - ) - break - session_requests = requests.session() - - # Get login csrf token - result = session_requests.get(LOGIN_URL) - tree = html.fromstring(result.text) - authenticity_token = list( - set(tree.xpath("//input[@name='authenticity_token']/@value")) - )[0] - - # Create payload - payload = { - "user[email]": self._username, - "user[password]": self._password, - "authenticity_token": authenticity_token, - } - - # Perform login - result = session_requests.post(LOGIN_URL, data=payload, headers=dict(referer=LOGIN_URL)) - URL_RESULT = result.url - n += 1 - - if URL_RESULT == URL_DASHBOARD: - # Scrape url - raw_html = session_requests.get(URL_DATA, headers=dict(referer=URL_DATA)).text - data = BeautifulSoup(raw_html, "html.parser") - - # Scrape graaddag - div = data.find_all("div", class_="table_cell")[5] - result = eval(div.get_text().replace("m3", "").replace(",", ".").rstrip()) - self._attributes["last_update"] = dt.now().isoformat("T") - self._state = result - else: - pass - - async def async_added_to_hass(self) -> None: - """Handle entity which will be added.""" - await super().async_added_to_hass() - state = await self.async_get_last_state() - if not state: - return - self._state = state.state