mirror of
https://github.com/home-assistant/core.git
synced 2025-07-17 10:17:09 +00:00
parent
74f1f08ab5
commit
e88fc33eef
@ -28,6 +28,12 @@ import homeassistant.helpers.config_validation as cv
|
|||||||
_RESOURCE = 'http://www.bom.gov.au/fwo/{}/{}.{}.json'
|
_RESOURCE = 'http://www.bom.gov.au/fwo/{}/{}.{}.json'
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
ATTR_LAST_UPDATE = 'last_update'
|
||||||
|
ATTR_SENSOR_ID = 'sensor_id'
|
||||||
|
ATTR_STATION_ID = 'station_id'
|
||||||
|
ATTR_STATION_NAME = 'station_name'
|
||||||
|
ATTR_ZONE_ID = 'zone_id'
|
||||||
|
|
||||||
CONF_ATTRIBUTION = "Data provided by the Australian Bureau of Meteorology"
|
CONF_ATTRIBUTION = "Data provided by the Australian Bureau of Meteorology"
|
||||||
CONF_STATION = 'station'
|
CONF_STATION = 'station'
|
||||||
CONF_ZONE_ID = 'zone_id'
|
CONF_ZONE_ID = 'zone_id'
|
||||||
@ -35,7 +41,6 @@ CONF_WMO_ID = 'wmo_id'
|
|||||||
|
|
||||||
MIN_TIME_BETWEEN_UPDATES = datetime.timedelta(minutes=35)
|
MIN_TIME_BETWEEN_UPDATES = datetime.timedelta(minutes=35)
|
||||||
|
|
||||||
# Sensor types are defined like: Name, units
|
|
||||||
SENSOR_TYPES = {
|
SENSOR_TYPES = {
|
||||||
'wmo': ['wmo', None],
|
'wmo': ['wmo', None],
|
||||||
'name': ['Station Name', None],
|
'name': ['Station Name', None],
|
||||||
@ -70,7 +75,7 @@ SENSOR_TYPES = {
|
|||||||
'weather': ['Weather', None],
|
'weather': ['Weather', None],
|
||||||
'wind_dir': ['Wind Direction', None],
|
'wind_dir': ['Wind Direction', None],
|
||||||
'wind_spd_kmh': ['Wind Speed kmh', 'km/h'],
|
'wind_spd_kmh': ['Wind Speed kmh', 'km/h'],
|
||||||
'wind_spd_kt': ['Wind Direction kt', 'kt']
|
'wind_spd_kt': ['Wind Speed kt', 'kt']
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -98,6 +103,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||||||
"""Set up the BOM sensor."""
|
"""Set up the BOM sensor."""
|
||||||
station = config.get(CONF_STATION)
|
station = config.get(CONF_STATION)
|
||||||
zone_id, wmo_id = config.get(CONF_ZONE_ID), config.get(CONF_WMO_ID)
|
zone_id, wmo_id = config.get(CONF_ZONE_ID), config.get(CONF_WMO_ID)
|
||||||
|
|
||||||
if station is not None:
|
if station is not None:
|
||||||
if zone_id and wmo_id:
|
if zone_id and wmo_id:
|
||||||
_LOGGER.warning(
|
_LOGGER.warning(
|
||||||
@ -111,17 +117,18 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||||||
hass.config.config_dir)
|
hass.config.config_dir)
|
||||||
if station is None:
|
if station is None:
|
||||||
_LOGGER.error("Could not get BOM weather station from lat/lon")
|
_LOGGER.error("Could not get BOM weather station from lat/lon")
|
||||||
return False
|
return
|
||||||
|
|
||||||
bom_data = BOMCurrentData(hass, station)
|
bom_data = BOMCurrentData(hass, station)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
bom_data.update()
|
bom_data.update()
|
||||||
except ValueError as err:
|
except ValueError as err:
|
||||||
_LOGGER.error("Received error from BOM_Current: %s", err)
|
_LOGGER.error("Received error from BOM Current: %s", err)
|
||||||
return False
|
return
|
||||||
|
|
||||||
add_devices([BOMCurrentSensor(bom_data, variable, config.get(CONF_NAME))
|
add_devices([BOMCurrentSensor(bom_data, variable, config.get(CONF_NAME))
|
||||||
for variable in config[CONF_MONITORED_CONDITIONS]])
|
for variable in config[CONF_MONITORED_CONDITIONS]])
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
class BOMCurrentSensor(Entity):
|
class BOMCurrentSensor(Entity):
|
||||||
@ -150,14 +157,17 @@ class BOMCurrentSensor(Entity):
|
|||||||
@property
|
@property
|
||||||
def device_state_attributes(self):
|
def device_state_attributes(self):
|
||||||
"""Return the state attributes of the device."""
|
"""Return the state attributes of the device."""
|
||||||
attr = {}
|
attr = {
|
||||||
attr['Sensor Id'] = self._condition
|
ATTR_ATTRIBUTION: CONF_ATTRIBUTION,
|
||||||
attr['Zone Id'] = self.bom_data.latest_data['history_product']
|
ATTR_LAST_UPDATE: datetime.datetime.strptime(
|
||||||
attr['Station Id'] = self.bom_data.latest_data['wmo']
|
str(self.bom_data.latest_data['local_date_time_full']),
|
||||||
attr['Station Name'] = self.bom_data.latest_data['name']
|
'%Y%m%d%H%M%S'),
|
||||||
attr['Last Update'] = datetime.datetime.strptime(str(
|
ATTR_SENSOR_ID: self._condition,
|
||||||
self.bom_data.latest_data['local_date_time_full']), '%Y%m%d%H%M%S')
|
ATTR_STATION_ID: self.bom_data.latest_data['wmo'],
|
||||||
attr[ATTR_ATTRIBUTION] = CONF_ATTRIBUTION
|
ATTR_STATION_NAME: self.bom_data.latest_data['name'],
|
||||||
|
ATTR_ZONE_ID: self.bom_data.latest_data['history_product'],
|
||||||
|
}
|
||||||
|
|
||||||
return attr
|
return attr
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -180,8 +190,9 @@ class BOMCurrentData(object):
|
|||||||
self._data = None
|
self._data = None
|
||||||
|
|
||||||
def _build_url(self):
|
def _build_url(self):
|
||||||
|
"""Build the URL for the requests."""
|
||||||
url = _RESOURCE.format(self._zone_id, self._zone_id, self._wmo_id)
|
url = _RESOURCE.format(self._zone_id, self._zone_id, self._wmo_id)
|
||||||
_LOGGER.info("BOM URL %s", url)
|
_LOGGER.debug("BOM URL: %s", url)
|
||||||
return url
|
return url
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -200,7 +211,7 @@ class BOMCurrentData(object):
|
|||||||
for the latest value that is not `-`.
|
for the latest value that is not `-`.
|
||||||
|
|
||||||
Iterators are used in this method to avoid iterating needlessly
|
Iterators are used in this method to avoid iterating needlessly
|
||||||
iterating through the entire BOM provided dataset
|
iterating through the entire BOM provided dataset.
|
||||||
"""
|
"""
|
||||||
condition_readings = (entry[condition] for entry in self._data)
|
condition_readings = (entry[condition] for entry in self._data)
|
||||||
return next((x for x in condition_readings if x != '-'), None)
|
return next((x for x in condition_readings if x != '-'), None)
|
||||||
@ -257,7 +268,7 @@ def _get_bom_stations():
|
|||||||
def bom_stations(cache_dir):
|
def bom_stations(cache_dir):
|
||||||
"""Return {CONF_STATION: (lat, lon)} for all stations, for auto-config.
|
"""Return {CONF_STATION: (lat, lon)} for all stations, for auto-config.
|
||||||
|
|
||||||
Results from internet requests are cached as compressed json, making
|
Results from internet requests are cached as compressed JSON, making
|
||||||
subsequent calls very much faster.
|
subsequent calls very much faster.
|
||||||
"""
|
"""
|
||||||
cache_file = os.path.join(cache_dir, '.bom-stations.json.gz')
|
cache_file = os.path.join(cache_dir, '.bom-stations.json.gz')
|
||||||
@ -277,7 +288,7 @@ def closest_station(lat, lon, cache_dir):
|
|||||||
stations = bom_stations(cache_dir)
|
stations = bom_stations(cache_dir)
|
||||||
|
|
||||||
def comparable_dist(wmo_id):
|
def comparable_dist(wmo_id):
|
||||||
"""Create a psudeo-distance from lat/lon."""
|
"""Create a psudeo-distance from latitude/longitude."""
|
||||||
station_lat, station_lon = stations[wmo_id]
|
station_lat, station_lon = stations[wmo_id]
|
||||||
return (lat - station_lat) ** 2 + (lon - station_lon) ** 2
|
return (lat - station_lat) ** 2 + (lon - station_lon) ** 2
|
||||||
|
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
"""The tests for the BOM Weather sensor platform."""
|
"""The tests for the BOM Weather sensor platform."""
|
||||||
|
import json
|
||||||
import re
|
import re
|
||||||
import unittest
|
import unittest
|
||||||
import json
|
|
||||||
import requests
|
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
from homeassistant.setup import setup_component
|
import requests
|
||||||
from homeassistant.components import sensor
|
|
||||||
|
|
||||||
from tests.common import (
|
from tests.common import (
|
||||||
get_test_home_assistant, assert_setup_component, load_fixture)
|
assert_setup_component, get_test_home_assistant, load_fixture)
|
||||||
|
|
||||||
|
from homeassistant.components import sensor
|
||||||
|
from homeassistant.setup import setup_component
|
||||||
|
|
||||||
VALID_CONFIG = {
|
VALID_CONFIG = {
|
||||||
'platform': 'bom',
|
'platform': 'bom',
|
||||||
@ -89,9 +89,11 @@ class TestBOMWeatherSensor(unittest.TestCase):
|
|||||||
self.assertTrue(setup_component(
|
self.assertTrue(setup_component(
|
||||||
self.hass, sensor.DOMAIN, {'sensor': VALID_CONFIG}))
|
self.hass, sensor.DOMAIN, {'sensor': VALID_CONFIG}))
|
||||||
|
|
||||||
self.assertEqual('Fine', self.hass.states.get(
|
weather = self.hass.states.get('sensor.bom_fake_weather').state
|
||||||
'sensor.bom_fake_weather').state)
|
self.assertEqual('Fine', weather)
|
||||||
self.assertEqual('1021.7', self.hass.states.get(
|
|
||||||
'sensor.bom_fake_pressure_mb').state)
|
pressure = self.hass.states.get('sensor.bom_fake_pressure_mb').state
|
||||||
self.assertEqual('25.0', self.hass.states.get(
|
self.assertEqual('1021.7', pressure)
|
||||||
'sensor.bom_fake_feels_like_c').state)
|
|
||||||
|
feels_like = self.hass.states.get('sensor.bom_fake_feels_like_c').state
|
||||||
|
self.assertEqual('25.0', feels_like)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user