commit
1bc5042bf9
|
@ -55,13 +55,13 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||
if device_id in rfxtrx.RFX_DEVICES:
|
||||
continue
|
||||
|
||||
if entity[CONF_DATA_BITS] is not None:
|
||||
if entity.get(CONF_DATA_BITS) is not None:
|
||||
_LOGGER.debug(
|
||||
"Masked device id: %s", rfxtrx.get_pt2262_deviceid(
|
||||
device_id, entity[CONF_DATA_BITS]))
|
||||
device_id, entity.get(CONF_DATA_BITS)))
|
||||
|
||||
_LOGGER.debug("Add %s rfxtrx.binary_sensor (class %s)",
|
||||
entity[ATTR_NAME], entity[CONF_DEVICE_CLASS])
|
||||
entity[ATTR_NAME], entity.get(CONF_DEVICE_CLASS))
|
||||
|
||||
device = RfxtrxBinarySensor(
|
||||
event, entity.get(CONF_NAME), entity.get(CONF_DEVICE_CLASS),
|
||||
|
|
|
@ -16,7 +16,7 @@ from homeassistant.const import (
|
|||
CONF_USERNAME, CONF_PASSWORD
|
||||
)
|
||||
|
||||
REQUIREMENTS = ['bimmer_connected==0.3.0']
|
||||
REQUIREMENTS = ['bimmer_connected==0.4.1']
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
|
|
@ -47,11 +47,6 @@ CONFIG_SCHEMA = vol.Schema({
|
|||
}),
|
||||
}, extra=vol.ALLOW_EXTRA)
|
||||
|
||||
ALL_EVENT_TYPES = [
|
||||
EVENT_STATE_CHANGED, EVENT_LOGBOOK_ENTRY,
|
||||
EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP
|
||||
]
|
||||
|
||||
GROUP_BY_MINUTES = 15
|
||||
|
||||
CONTINUOUS_DOMAINS = ['proximity', 'sensor']
|
||||
|
@ -271,18 +266,15 @@ def humanify(events):
|
|||
|
||||
def _get_events(hass, config, start_day, end_day):
|
||||
"""Get events for a period of time."""
|
||||
from homeassistant.components.recorder.models import Events, States
|
||||
from homeassistant.components.recorder.models import Events
|
||||
from homeassistant.components.recorder.util import (
|
||||
execute, session_scope)
|
||||
|
||||
with session_scope(hass=hass) as session:
|
||||
query = session.query(Events).order_by(Events.time_fired) \
|
||||
.outerjoin(States, (Events.event_id == States.event_id)) \
|
||||
.filter(Events.event_type.in_(ALL_EVENT_TYPES)) \
|
||||
.filter((Events.time_fired > start_day)
|
||||
& (Events.time_fired < end_day)) \
|
||||
.filter((States.last_updated == States.last_changed)
|
||||
| (States.last_updated.is_(None)))
|
||||
query = session.query(Events).order_by(
|
||||
Events.time_fired).filter(
|
||||
(Events.time_fired > start_day) &
|
||||
(Events.time_fired < end_day))
|
||||
events = execute(query)
|
||||
return humanify(_exclude_events(events, config))
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ https://home-assistant.io/components/media_player.plex/
|
|||
"""
|
||||
import json
|
||||
import logging
|
||||
|
||||
from datetime import timedelta
|
||||
|
||||
import requests
|
||||
|
@ -47,9 +48,14 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||
cv.boolean,
|
||||
})
|
||||
|
||||
PLEX_DATA = "plex"
|
||||
|
||||
|
||||
def setup_platform(hass, config, add_devices_callback, discovery_info=None):
|
||||
"""Set up the Plex platform."""
|
||||
if PLEX_DATA not in hass.data:
|
||||
hass.data[PLEX_DATA] = {}
|
||||
|
||||
# get config from plex.conf
|
||||
file_config = load_json(hass.config.path(PLEX_CONFIG_FILE))
|
||||
|
||||
|
@ -130,7 +136,7 @@ def setup_plexserver(
|
|||
|
||||
_LOGGER.info('Connected to: %s://%s', http_prefix, host)
|
||||
|
||||
plex_clients = {}
|
||||
plex_clients = hass.data[PLEX_DATA]
|
||||
plex_sessions = {}
|
||||
track_utc_time_change(hass, lambda now: update_devices(), second=30)
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ from homeassistant.const import (
|
|||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
REQUIREMENTS = ['samsungctl==0.6.0', 'wakeonlan==1.0.0']
|
||||
REQUIREMENTS = ['samsungctl[websocket]==0.7.1', 'wakeonlan==1.0.0']
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ _LOGGER = logging.getLogger(__name__)
|
|||
|
||||
# Quiet down soco logging to just actual problems.
|
||||
logging.getLogger('soco').setLevel(logging.WARNING)
|
||||
logging.getLogger('soco.data_structures_entry').setLevel(logging.ERROR)
|
||||
_SOCO_SERVICES_LOGGER = logging.getLogger('soco.services')
|
||||
|
||||
SUPPORT_SONOS = SUPPORT_VOLUME_SET | SUPPORT_VOLUME_MUTE |\
|
||||
|
@ -119,6 +120,19 @@ class SonosData:
|
|||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Set up the Sonos platform."""
|
||||
import soco
|
||||
import soco.events
|
||||
import soco.exceptions
|
||||
|
||||
orig_parse_event_xml = soco.events.parse_event_xml
|
||||
|
||||
def safe_parse_event_xml(xml):
|
||||
"""Avoid SoCo 0.14 event thread dying from invalid xml."""
|
||||
try:
|
||||
return orig_parse_event_xml(xml)
|
||||
except soco.exceptions.SoCoException:
|
||||
return {}
|
||||
|
||||
soco.events.parse_event_xml = safe_parse_event_xml
|
||||
|
||||
if DATA_SONOS not in hass.data:
|
||||
hass.data[DATA_SONOS] = SonosData()
|
||||
|
@ -451,14 +465,14 @@ class SonosDevice(MediaPlayerDevice):
|
|||
|
||||
def process_avtransport_event(self, event):
|
||||
"""Process a track change event coming from a coordinator."""
|
||||
variables = event.variables
|
||||
transport_info = self.soco.get_current_transport_info()
|
||||
new_status = transport_info.get('current_transport_state')
|
||||
|
||||
# Ignore transitions, we should get the target state soon
|
||||
new_status = variables.get('transport_state')
|
||||
if new_status == 'TRANSITIONING':
|
||||
return
|
||||
|
||||
self._play_mode = variables.get('current_play_mode', self._play_mode)
|
||||
self._play_mode = self.soco.play_mode
|
||||
|
||||
if self.soco.is_playing_tv:
|
||||
self._refresh_linein(SOURCE_TV)
|
||||
|
@ -472,12 +486,12 @@ class SonosDevice(MediaPlayerDevice):
|
|||
)
|
||||
|
||||
if _is_radio_uri(track_info['uri']):
|
||||
self._refresh_radio(variables, media_info, track_info)
|
||||
self._refresh_radio(event.variables, media_info, track_info)
|
||||
else:
|
||||
self._refresh_music(variables, media_info, track_info)
|
||||
update_position = (new_status != self._status)
|
||||
self._refresh_music(update_position, media_info, track_info)
|
||||
|
||||
if new_status:
|
||||
self._status = new_status
|
||||
self._status = new_status
|
||||
|
||||
self.schedule_update_ha_state()
|
||||
|
||||
|
@ -585,9 +599,7 @@ class SonosDevice(MediaPlayerDevice):
|
|||
)
|
||||
else:
|
||||
# "On Now" field in the sonos pc app
|
||||
current_track_metadata = variables.get(
|
||||
'current_track_meta_data'
|
||||
)
|
||||
current_track_metadata = variables.get('current_track_meta_data')
|
||||
if current_track_metadata:
|
||||
self._media_artist = \
|
||||
current_track_metadata.radio_show.split(',')[0]
|
||||
|
@ -625,7 +637,7 @@ class SonosDevice(MediaPlayerDevice):
|
|||
if fav.reference.get_uri() == media_info['CurrentURI']:
|
||||
self._source_name = fav.title
|
||||
|
||||
def _refresh_music(self, variables, media_info, track_info):
|
||||
def _refresh_music(self, update_media_position, media_info, track_info):
|
||||
"""Update state when playing music tracks."""
|
||||
self._extra_features = SUPPORT_PAUSE | SUPPORT_SHUFFLE_SET |\
|
||||
SUPPORT_PREVIOUS_TRACK | SUPPORT_NEXT_TRACK
|
||||
|
@ -658,25 +670,21 @@ class SonosDevice(MediaPlayerDevice):
|
|||
rel_time = _timespan_secs(position_info.get("RelTime"))
|
||||
|
||||
# player no longer reports position?
|
||||
update_media_position = rel_time is None and \
|
||||
update_media_position |= rel_time is None and \
|
||||
self._media_position is not None
|
||||
|
||||
# player started reporting position?
|
||||
update_media_position |= rel_time is not None and \
|
||||
self._media_position is None
|
||||
|
||||
if self._status != variables.get('transport_state'):
|
||||
update_media_position = True
|
||||
else:
|
||||
# position jumped?
|
||||
if rel_time is not None and self._media_position is not None:
|
||||
time_diff = utcnow() - self._media_position_updated_at
|
||||
time_diff = time_diff.total_seconds()
|
||||
# position jumped?
|
||||
if rel_time is not None and self._media_position is not None:
|
||||
time_diff = utcnow() - self._media_position_updated_at
|
||||
time_diff = time_diff.total_seconds()
|
||||
|
||||
calculated_position = self._media_position + time_diff
|
||||
calculated_position = self._media_position + time_diff
|
||||
|
||||
update_media_position = \
|
||||
abs(calculated_position - rel_time) > 1.5
|
||||
update_media_position |= abs(calculated_position - rel_time) > 1.5
|
||||
|
||||
if update_media_position:
|
||||
self._media_position = rel_time
|
||||
|
|
|
@ -19,7 +19,7 @@ from homeassistant.util import Throttle
|
|||
from homeassistant.util.dt import now, parse_date
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
REQUIREMENTS = ['fedexdeliverymanager==1.0.5']
|
||||
REQUIREMENTS = ['fedexdeliverymanager==1.0.6']
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
|
|
@ -107,7 +107,7 @@ RATING_MAPPING = [{
|
|||
|
||||
|
||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||
vol.Required(CONF_ZIP_CODE): cv.positive_int,
|
||||
vol.Required(CONF_ZIP_CODE): cv.string,
|
||||
vol.Required(CONF_MONITORED_CONDITIONS):
|
||||
vol.All(cv.ensure_list, [vol.In(CONDITIONS)]),
|
||||
})
|
||||
|
@ -209,11 +209,16 @@ class AllergyAverageSensor(BaseSensor):
|
|||
"""Update the status of the sensor."""
|
||||
self.data.update()
|
||||
|
||||
data_attr = getattr(self.data, self._data_params['data_attr'])
|
||||
indices = [
|
||||
p['Index']
|
||||
for p in data_attr['Location']['periods']
|
||||
]
|
||||
try:
|
||||
data_attr = getattr(self.data, self._data_params['data_attr'])
|
||||
indices = [
|
||||
p['Index']
|
||||
for p in data_attr['Location']['periods']
|
||||
]
|
||||
except KeyError:
|
||||
_LOGGER.error("Pollen.com API didn't return any data")
|
||||
return
|
||||
|
||||
average = round(mean(indices), 1)
|
||||
|
||||
self._attrs[ATTR_TREND] = calculate_trend(indices)
|
||||
|
@ -238,7 +243,12 @@ class AllergyIndexSensor(BaseSensor):
|
|||
"""Update the status of the sensor."""
|
||||
self.data.update()
|
||||
|
||||
location_data = self.data.current_data['Location']
|
||||
try:
|
||||
location_data = self.data.current_data['Location']
|
||||
except KeyError:
|
||||
_LOGGER.error("Pollen.com API didn't return any data")
|
||||
return
|
||||
|
||||
[period] = [
|
||||
p for p in location_data['periods']
|
||||
if p['Type'] == self._data_params['key']
|
||||
|
@ -276,6 +286,7 @@ class DataBase(object):
|
|||
"""Get data from a particular point in the API."""
|
||||
from pypollencom.exceptions import HTTPError
|
||||
|
||||
data = {}
|
||||
try:
|
||||
data = getattr(getattr(self._client, module), operation)()
|
||||
_LOGGER.debug('Received "%s_%s" data: %s', module,
|
||||
|
|
|
@ -136,7 +136,7 @@ beautifulsoup4==4.6.0
|
|||
bellows==0.5.1
|
||||
|
||||
# homeassistant.components.bmw_connected_drive
|
||||
bimmer_connected==0.3.0
|
||||
bimmer_connected==0.4.1
|
||||
|
||||
# homeassistant.components.blink
|
||||
blinkpy==0.6.0
|
||||
|
@ -268,7 +268,7 @@ evohomeclient==0.2.5
|
|||
fastdotcom==0.0.3
|
||||
|
||||
# homeassistant.components.sensor.fedex
|
||||
fedexdeliverymanager==1.0.5
|
||||
fedexdeliverymanager==1.0.6
|
||||
|
||||
# homeassistant.components.feedreader
|
||||
# homeassistant.components.sensor.geo_rss_events
|
||||
|
@ -1076,7 +1076,7 @@ russound_rio==0.1.4
|
|||
rxv==0.5.1
|
||||
|
||||
# homeassistant.components.media_player.samsungtv
|
||||
samsungctl==0.6.0
|
||||
samsungctl[websocket]==0.7.1
|
||||
|
||||
# homeassistant.components.satel_integra
|
||||
satel_integra==0.1.0
|
||||
|
|
Loading…
Reference in New Issue