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