Compare commits
7 Commits
f83bb077c1
...
v1.0.3-rc2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
025a6475dd | ||
|
|
216775e68f | ||
|
|
403efb937b | ||
|
|
559a463140 | ||
|
|
2f73be9010 | ||
|
|
b6184be32f | ||
|
|
70fa0619d4 |
10
.github/workflows/python-app.yml
vendored
10
.github/workflows/python-app.yml
vendored
@@ -50,3 +50,13 @@ jobs:
|
|||||||
- name: Test with pytest
|
- name: Test with pytest
|
||||||
run: |
|
run: |
|
||||||
poetry run pytest
|
poetry run pytest
|
||||||
|
|
||||||
|
validate:
|
||||||
|
runs-on: "ubuntu-latest"
|
||||||
|
steps:
|
||||||
|
- uses: "actions/checkout@v2"
|
||||||
|
- name: HACS validation
|
||||||
|
uses: "hacs/action@main"
|
||||||
|
with:
|
||||||
|
category: "integration"
|
||||||
|
ignore: brands wheels
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ if TYPE_CHECKING:
|
|||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
from .crawler import CovidCrawler, IncidenceData
|
from .crawler import CovidCrawler
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -67,9 +67,12 @@ async def get_coordinator(hass: HomeAssistant):
|
|||||||
if DOMAIN in hass.data:
|
if DOMAIN in hass.data:
|
||||||
return hass.data[DOMAIN]
|
return hass.data[DOMAIN]
|
||||||
|
|
||||||
async def async_get_data() -> IncidenceData:
|
async def async_get_data() -> dict:
|
||||||
crawler = CovidCrawler(hass)
|
crawler = CovidCrawler(hass)
|
||||||
return await crawler.crawl_incidence()
|
return {
|
||||||
|
"incidence": await crawler.crawl_incidence(),
|
||||||
|
"vaccination": await crawler.crawl_vaccination(),
|
||||||
|
}
|
||||||
|
|
||||||
hass.data[DOMAIN] = DataUpdateCoordinator(
|
hass.data[DOMAIN] = DataUpdateCoordinator(
|
||||||
hass,
|
hass,
|
||||||
|
|||||||
@@ -78,6 +78,22 @@ class CovidCrawler(CovidCrawlerBase):
|
|||||||
def __init__(self, hass=None) -> None:
|
def __init__(self, hass=None) -> None:
|
||||||
self.hass = hass
|
self.hass = hass
|
||||||
|
|
||||||
|
async def _fetch(self, url: str) -> str:
|
||||||
|
"""Fetch a URL, using either the current Home Assistant instance or requests"""
|
||||||
|
|
||||||
|
if self.hass:
|
||||||
|
from homeassistant.helpers import aiohttp_client
|
||||||
|
|
||||||
|
result = await aiohttp_client.async_get_clientsession(self.hass).get(url)
|
||||||
|
soup = BeautifulSoup(await result.text(), "html.parser")
|
||||||
|
else:
|
||||||
|
import requests
|
||||||
|
|
||||||
|
result = requests.get(url)
|
||||||
|
result.raise_for_status()
|
||||||
|
soup = BeautifulSoup(result.text, "html.parser")
|
||||||
|
return soup
|
||||||
|
|
||||||
async def crawl_incidence(self) -> IncidenceData:
|
async def crawl_incidence(self) -> IncidenceData:
|
||||||
"""
|
"""
|
||||||
Fetch COVID-19 infection data from the target website.
|
Fetch COVID-19 infection data from the target website.
|
||||||
@@ -88,18 +104,7 @@ class CovidCrawler(CovidCrawlerBase):
|
|||||||
url = (
|
url = (
|
||||||
"https://www.augsburg.de/umwelt-soziales/gesundheit/coronavirus/fallzahlen"
|
"https://www.augsburg.de/umwelt-soziales/gesundheit/coronavirus/fallzahlen"
|
||||||
)
|
)
|
||||||
if self.hass:
|
soup = await self._fetch(url)
|
||||||
from homeassistant.helpers import aiohttp_client
|
|
||||||
|
|
||||||
result = await aiohttp_client.async_get_clientsession(self.hass).get(url)
|
|
||||||
soup = BeautifulSoup(await result.text(), "html.parser")
|
|
||||||
else:
|
|
||||||
import requests
|
|
||||||
|
|
||||||
result = requests.get(url)
|
|
||||||
if not result.ok:
|
|
||||||
result.raise_for_status()
|
|
||||||
soup = BeautifulSoup(result.text, "html.parser")
|
|
||||||
|
|
||||||
match = soup.find(class_="frame--type-textpic")
|
match = soup.find(class_="frame--type-textpic")
|
||||||
text = match.p.text
|
text = match.p.text
|
||||||
@@ -153,22 +158,12 @@ class CovidCrawler(CovidCrawlerBase):
|
|||||||
|
|
||||||
async def crawl_vaccination(self) -> VaccinationData:
|
async def crawl_vaccination(self) -> VaccinationData:
|
||||||
_log.info("Fetching COVID-19 vaccination data update")
|
_log.info("Fetching COVID-19 vaccination data update")
|
||||||
url = "https://www.augsburg.de/umwelt-sozgcoiales/gesundheit/coronavirus/impfzentrum"
|
url = (
|
||||||
|
"https://www.augsburg.de/umwelt-soziales/gesundheit/coronavirus/impfzentrum"
|
||||||
|
)
|
||||||
|
soup = await self._fetch(url)
|
||||||
|
|
||||||
container_id = "c1088140"
|
container_id = "c1088140"
|
||||||
|
|
||||||
if self.hass:
|
|
||||||
from homeassistant.helpers import aiohttp_client
|
|
||||||
|
|
||||||
result = await aiohttp_client.async_get_clientsession(self.hass).get(url)
|
|
||||||
soup = BeautifulSoup(await result.text(), "html.parser")
|
|
||||||
else:
|
|
||||||
import requests
|
|
||||||
|
|
||||||
result = requests.get(url)
|
|
||||||
if not result.ok:
|
|
||||||
result.raise_for_status()
|
|
||||||
soup = BeautifulSoup(result.text, "html.parser")
|
|
||||||
|
|
||||||
result = soup.find(id=container_id)
|
result = soup.find(id=container_id)
|
||||||
text = re.sub(r"\s+", " ", result.text)
|
text = re.sub(r"\s+", " ", result.text)
|
||||||
regexes = [
|
regexes = [
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ from .crawler import CovidCrawler
|
|||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
crawler = CovidCrawler()
|
crawler = CovidCrawler()
|
||||||
# result = await crawler.crawl()
|
result = await crawler.crawl_incidence()
|
||||||
# print(result)
|
print(result)
|
||||||
|
|
||||||
result = await crawler.crawl_vaccination()
|
result = await crawler.crawl_vaccination()
|
||||||
print(result)
|
print(result)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"documentation": "https://github.com/AdrianoKF/home-assistant-covid19-augsburg",
|
"documentation": "https://github.com/AdrianoKF/home-assistant-covid19-augsburg",
|
||||||
|
"issue_tracker": "https://github.com/AdrianoKF/home-assistant-covid19-augsburg/issues",
|
||||||
"requirements": ["beautifulsoup4==4.8.2"],
|
"requirements": ["beautifulsoup4==4.8.2"],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"codeowners": ["@AdrianoKF"]
|
"codeowners": ["@AdrianoKF"]
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
from dataclasses import asdict
|
||||||
|
|
||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers.entity import Entity
|
||||||
|
|
||||||
from . import get_coordinator
|
from . import get_coordinator
|
||||||
@@ -7,7 +9,12 @@ async def async_setup_entry(hass, _, async_add_entities):
|
|||||||
"""Defer sensor setup to the shared sensor module."""
|
"""Defer sensor setup to the shared sensor module."""
|
||||||
coordinator = await get_coordinator(hass)
|
coordinator = await get_coordinator(hass)
|
||||||
|
|
||||||
async_add_entities([CoronaAugsburgSensor(coordinator)])
|
async_add_entities(
|
||||||
|
[
|
||||||
|
CoronaAugsburgSensor(coordinator),
|
||||||
|
CoronaAugsburgVaccinationSensor(coordinator),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class CoronaAugsburgSensor(Entity):
|
class CoronaAugsburgSensor(Entity):
|
||||||
@@ -41,18 +48,59 @@ class CoronaAugsburgSensor(Entity):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def state(self):
|
def state(self):
|
||||||
return self.coordinator.data.incidence
|
return self.coordinator.data["incidence"].incidence
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def device_state_attributes(self):
|
def device_state_attributes(self):
|
||||||
return {
|
data = self.coordinator.data["incidence"]
|
||||||
"date": self.coordinator.data.date,
|
return asdict(data)
|
||||||
"incidence": self.coordinator.data.incidence,
|
|
||||||
"total_cases": self.coordinator.data.total_cases,
|
async def async_added_to_hass(self):
|
||||||
"num_dead": self.coordinator.data.num_dead,
|
"""When entity is added to hass."""
|
||||||
"num_recovered": self.coordinator.data.num_recovered,
|
self.coordinator.async_add_listener(self.async_write_ha_state)
|
||||||
"num_infected": self.coordinator.data.num_infected,
|
|
||||||
}
|
async def async_will_remove_from_hass(self):
|
||||||
|
"""When entity will be removed from hass."""
|
||||||
|
self.coordinator.async_remove_listener(self.async_write_ha_state)
|
||||||
|
|
||||||
|
|
||||||
|
class CoronaAugsburgVaccinationSensor(Entity):
|
||||||
|
"""Representation of vaccination data for the city of Augsburg"""
|
||||||
|
|
||||||
|
def __init__(self, coordinator):
|
||||||
|
"""Initialize sensor."""
|
||||||
|
self.coordinator = coordinator
|
||||||
|
self._name = "COVID-19 Vaccinations Augsburg"
|
||||||
|
self._state = None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def available(self):
|
||||||
|
return self.coordinator.last_update_success and self.coordinator.data
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
return self._name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def unique_id(self):
|
||||||
|
return self._name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def icon(self):
|
||||||
|
return "mdi:biohazard"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def unit_of_measurement(self):
|
||||||
|
return ""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def state(self):
|
||||||
|
return self.coordinator.data["vaccination"].total_vaccinations
|
||||||
|
|
||||||
|
@property
|
||||||
|
def device_state_attributes(self):
|
||||||
|
data = self.coordinator.data["vaccination"]
|
||||||
|
return asdict(data)
|
||||||
|
|
||||||
async def async_added_to_hass(self):
|
async def async_added_to_hass(self):
|
||||||
"""When entity is added to hass."""
|
"""When entity is added to hass."""
|
||||||
|
|||||||
Reference in New Issue
Block a user