Skip to content

Commit

Permalink
Merge pull request #35 from lichtteil/dev
Browse files Browse the repository at this point in the history
Release 2.0.0
  • Loading branch information
lichtteil authored Jun 7, 2021
2 parents b7154dc + 790b242 commit 539be1c
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 34 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Download and unzip or clone this repository and copy `custom_components/local_lu
In the end your file structure should look like that:
```
~/.homeassistant/custom_components/local_luftdaten/__init__.py
~/.homeassistant/custom_components/local_luftdaten/const.py
~/.homeassistant/custom_components/local_luftdaten/manifest.json
~/.homeassistant/custom_components/local_luftdaten/sensor.py
```
Expand Down
2 changes: 1 addition & 1 deletion custom_components/local_luftdaten/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
"dependencies": [],
"codeowners": ["@lichtteil"],
"requirements": [],
"version": "1.10",
"version": "2.0.0",
"iot_class": "local_polling"
}
92 changes: 59 additions & 33 deletions custom_components/local_luftdaten/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import asyncio
import aiohttp
import async_timeout
import datetime

import json

Expand Down Expand Up @@ -45,12 +46,15 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
"""Set up the Luftdaten sensor."""
name = config.get(CONF_NAME)
host = config.get(CONF_HOST)
scan_interval = config.get(CONF_SCAN_INTERVAL)

verify_ssl = config.get(CONF_VERIFY_SSL)


resource = config.get(CONF_RESOURCE).format(host)

session = async_get_clientsession(hass, verify_ssl)
rest_client = LuftdatenClient(hass.loop, session, resource)
rest_client = LuftdatenClient(hass.loop, session, resource, scan_interval)

devices = []
for variable in config[CONF_MONITORED_CONDITIONS]:
Expand All @@ -70,7 +74,7 @@ def __init__(self, rest_client, name, sensor_type):
self.sensor_type = sensor_type
self._unit_of_measurement = SENSOR_TYPES[sensor_type][1]
self._device_class = SENSOR_TYPES[sensor_type][2]
self._unique_id = '{} {}'.format(self._name, SENSOR_TYPES[self.sensor_type][0])
self._unique_id = '{}-{}'.format(self._name, self.sensor_type)

@property
def name(self):
Expand Down Expand Up @@ -111,24 +115,14 @@ async def async_update(self):
try:
await self.rest_client.async_update()
except LuftdatenError:
value = None
return
value = self.rest_client.data

try:
parsed_json = json.loads(value)
if not isinstance(parsed_json, dict):
_LOGGER.warning("JSON result was not a dictionary")
return
except ValueError:
_LOGGER.warning("REST result could not be parsed as JSON")
_LOGGER.debug("Erroneous JSON: %s", value)
return
parsed_json = self.rest_client.data

sensordata_values = parsed_json['sensordatavalues']
for sensordata_value in sensordata_values:
if sensordata_value['value_type'] == self.sensor_type:
self._state = sensordata_value['value']
if parsed_json != None:
sensordata_values = parsed_json['sensordatavalues']
for sensordata_value in sensordata_values:
if sensordata_value['value_type'] == self.sensor_type:
self._state = sensordata_value['value']


class LuftdatenError(Exception):
Expand All @@ -138,26 +132,58 @@ class LuftdatenError(Exception):
class LuftdatenClient(object):
"""Class for handling the data retrieval."""

def __init__(self, loop, session, resource):
def __init__(self, loop, session, resource, scan_interval):
"""Initialize the data object."""
self._loop = loop
self._session = session
self._resource = resource
self.lastUpdate = datetime.datetime.now()
self.scan_interval = scan_interval
self.data = None
self.lock = asyncio.Lock()

async def async_update(self):
"""Get the latest data from Luftdaten service."""
_LOGGER.debug("Get data from %s", str(self._resource))
try:
with async_timeout.timeout(30, loop=self._loop):
response = await self._session.get(self._resource)
self.data = await response.text()
_LOGGER.debug("Received data: %s", str(self.data))
except aiohttp.ClientError as err:
_LOGGER.warning("REST request error: {0}".format(err))
self.data = None
raise LuftdatenError
except asyncio.TimeoutError:
_LOGGER.warning("REST request timeout")
self.data = None
raise LuftdatenError

async with self.lock:
# Time difference since last data update
callTimeDiff = datetime.datetime.now() - self.lastUpdate
# Fetch sensor values only once per scan_interval
if (callTimeDiff < self.scan_interval):
if self.data != None:
return

# Handle calltime differences: substract 5 second from current time
self.lastUpdate = datetime.datetime.now() - timedelta(seconds=5)

# Query local device
responseData = None
try:
_LOGGER.debug("Get data from %s", str(self._resource))
with async_timeout.timeout(30, loop=self._loop):
response = await self._session.get(self._resource)
responseData = await response.text()
_LOGGER.debug("Received data: %s", str(self.data))
except aiohttp.ClientError as err:
_LOGGER.warning("REST request error: {0}".format(err))
self.data = None
raise LuftdatenError
except asyncio.TimeoutError:
_LOGGER.warning("REST request timeout")
self.data = None
raise LuftdatenError

# Parse REST response
try:
parsed_json = json.loads(responseData)
if not isinstance(parsed_json, dict):
_LOGGER.warning("JSON result was not a dictionary")
self.data = None
return
# Set parsed json as data
self.data = parsed_json
except ValueError:
_LOGGER.warning("REST result could not be parsed as JSON")
_LOGGER.debug("Erroneous JSON: %s", responseData)
self.data = None
return

0 comments on commit 539be1c

Please sign in to comment.