diff --git a/homeassistant/components/camera/foscam.py b/homeassistant/components/camera/foscam.py index 15138e2c253..8ea90d5a44e 100644 --- a/homeassistant/components/camera/foscam.py +++ b/homeassistant/components/camera/foscam.py @@ -53,7 +53,7 @@ class FoscamCam(Camera): self._name = device_info.get(CONF_NAME) self._motion_status = False - from foscam import FoscamCamera + from foscam.foscam import FoscamCamera self._foscam_session = FoscamCamera(ip_address, port, self._username, self._password, verbose=False) diff --git a/homeassistant/components/device_tracker/automatic.py b/homeassistant/components/device_tracker/automatic.py index 071edf42642..a4495926f82 100644 --- a/homeassistant/components/device_tracker/automatic.py +++ b/homeassistant/components/device_tracker/automatic.py @@ -23,7 +23,7 @@ from homeassistant.helpers.aiohttp_client import async_get_clientsession import homeassistant.helpers.config_validation as cv from homeassistant.helpers.event import async_track_time_interval -REQUIREMENTS = ['aioautomatic==0.6.0'] +REQUIREMENTS = ['aioautomatic==0.6.2'] DEPENDENCIES = ['http'] _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/device_tracker/icloud.py b/homeassistant/components/device_tracker/icloud.py index f20dad1fceb..e670287dd87 100644 --- a/homeassistant/components/device_tracker/icloud.py +++ b/homeassistant/components/device_tracker/icloud.py @@ -307,12 +307,15 @@ class Icloud(DeviceScanner): self.api.authenticate() currentminutes = dt_util.now().hour * 60 + dt_util.now().minute - for devicename in self.devices: - interval = self._intervals.get(devicename, 1) - if ((currentminutes % interval == 0) or - (interval > 10 and - currentminutes % interval in [2, 4])): - self.update_device(devicename) + try: + for devicename in self.devices: + interval = self._intervals.get(devicename, 1) + if ((currentminutes % interval == 0) or + (interval > 10 and + currentminutes % interval in [2, 4])): + self.update_device(devicename) + except ValueError: + _LOGGER.debug("iCloud API returned an error") def determine_interval(self, devicename, latitude, longitude, battery): """Calculate new interval.""" @@ -397,7 +400,7 @@ class Icloud(DeviceScanner): self.see(**kwargs) self.seen_devices[devicename] = True except PyiCloudNoDevicesException: - _LOGGER.error('No iCloud Devices found!') + _LOGGER.error("No iCloud Devices found") def lost_iphone(self, devicename): """Call the lost iPhone function if the device is found.""" diff --git a/homeassistant/components/ecobee.py b/homeassistant/components/ecobee.py index 9e74299e6bc..c4b0f2e9546 100644 --- a/homeassistant/components/ecobee.py +++ b/homeassistant/components/ecobee.py @@ -15,7 +15,7 @@ from homeassistant.helpers import discovery from homeassistant.const import CONF_API_KEY from homeassistant.util import Throttle -REQUIREMENTS = ['python-ecobee-api==0.0.8'] +REQUIREMENTS = ['python-ecobee-api==0.0.9'] _CONFIGURING = {} _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/notify/pushbullet.py b/homeassistant/components/notify/pushbullet.py index 6d97d544905..0d596fb41ba 100644 --- a/homeassistant/components/notify/pushbullet.py +++ b/homeassistant/components/notify/pushbullet.py @@ -89,7 +89,7 @@ class PushBulletNotificationService(BaseNotificationService): if not targets: # Backward compatibility, notify all devices in own account - self._push_data(filepath, message, title, url) + self._push_data(filepath, message, title, self.pushbullet, url) _LOGGER.info("Sent notification to self") return @@ -104,7 +104,8 @@ class PushBulletNotificationService(BaseNotificationService): # Target is email, send directly, don't use a target object # This also seems works to send to all devices in own account if ttype == 'email': - self._push_data(filepath, message, title, url, tname) + self._push_data(filepath, message, title, url, + self.pushbullet, tname) _LOGGER.info("Sent notification to email %s", tname) continue @@ -123,27 +124,33 @@ class PushBulletNotificationService(BaseNotificationService): # Attempt push_note on a dict value. Keys are types & target # name. Dict pbtargets has all *actual* targets. try: - if url: - self.pbtargets[ttype][tname].push_link( - title, url, body=message) - else: - self.pbtargets[ttype][tname].push_note(title, message) + self._push_data(filepath, message, title, url, + self.pbtargets[ttype][tname]) _LOGGER.info("Sent notification to %s/%s", ttype, tname) except KeyError: _LOGGER.error("No such target: %s/%s", ttype, tname) continue - except self.pushbullet.errors.PushError: - _LOGGER.error("Notify failed to: %s/%s", ttype, tname) - continue - def _push_data(self, filepath, message, title, url, tname=None): - if url: - self.pushbullet.push_link( - title, url, body=message, email=tname) - elif filepath and self.hass.config.is_allowed_path(filepath): - with open(filepath, "rb") as fileh: - filedata = self.pushbullet.upload_file(fileh, filepath) - self.pushbullet.push_file(title=title, body=message, - **filedata) - else: - self.pushbullet.push_note(title, message, email=tname) + def _push_data(self, filepath, message, title, url, pusher, tname=None): + from pushbullet import PushError + from pushbullet import Device + try: + if url: + if isinstance(pusher, Device): + pusher.push_link(title, url, body=message) + else: + pusher.push_link(title, url, body=message, email=tname) + elif filepath and self.hass.config.is_allowed_path(filepath): + with open(filepath, "rb") as fileh: + filedata = self.pushbullet.upload_file(fileh, filepath) + if filedata.get('file_type') == 'application/x-empty': + _LOGGER.error("Failed to send an empty file.") + return + pusher.push_file(title=title, body=message, **filedata) + else: + if isinstance(pusher, Device): + pusher.push_note(title, message) + else: + pusher.push_note(title, message, email=tname) + except PushError as err: + _LOGGER.error("Notify failed: %s", err) diff --git a/homeassistant/const.py b/homeassistant/const.py index a8fefcf26c4..15079b11992 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -2,7 +2,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 MINOR_VERSION = 52 -PATCH_VERSION = '0' +PATCH_VERSION = '1' __short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION) __version__ = '{}.{}'.format(__short_version__, PATCH_VERSION) REQUIRED_PYTHON_VER = (3, 4, 2) diff --git a/homeassistant/helpers/aiohttp_client.py b/homeassistant/helpers/aiohttp_client.py index a8b18351021..29e2a6260fd 100644 --- a/homeassistant/helpers/aiohttp_client.py +++ b/homeassistant/helpers/aiohttp_client.py @@ -90,8 +90,15 @@ def async_aiohttp_proxy_web(hass, request, web_coro, buffer_size=102400, # Something went wrong with the connection raise HTTPBadGateway() from err - yield from async_aiohttp_proxy_stream(hass, request, req.content, - req.headers.get(CONTENT_TYPE)) + try: + yield from async_aiohttp_proxy_stream( + hass, + request, + req.content, + req.headers.get(CONTENT_TYPE) + ) + finally: + req.close() @asyncio.coroutine diff --git a/homeassistant/helpers/template.py b/homeassistant/helpers/template.py index aa6ca186a8e..bdef5541983 100644 --- a/homeassistant/helpers/template.py +++ b/homeassistant/helpers/template.py @@ -209,7 +209,7 @@ class DomainStates(object): def __iter__(self): """Return the iteration over all the states.""" return iter(sorted( - (state for state in self._hass.states.async_all() + (_wrap_state(state) for state in self._hass.states.async_all() if state.domain == self._domain), key=lambda state: state.entity_id)) diff --git a/requirements_all.txt b/requirements_all.txt index f1fc40a2187..7ec81558945 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -42,7 +42,7 @@ TwitterAPI==2.4.6 abodepy==0.7.1 # homeassistant.components.device_tracker.automatic -aioautomatic==0.6.0 +aioautomatic==0.6.2 # homeassistant.components.sensor.dnsip aiodns==1.1.1 @@ -716,7 +716,7 @@ python-clementine-remote==1.0.1 python-digitalocean==1.12 # homeassistant.components.ecobee -python-ecobee-api==0.0.8 +python-ecobee-api==0.0.9 # homeassistant.components.climate.eq3btsmart # python-eq3bt==0.1.5 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 74717aa7d7b..f286555833e 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -27,7 +27,7 @@ PyJWT==1.5.2 SoCo==0.12 # homeassistant.components.device_tracker.automatic -aioautomatic==0.6.0 +aioautomatic==0.6.2 # homeassistant.components.emulated_hue # homeassistant.components.http