Skip to content

Commit

Permalink
Merge remote-tracking branch 'balloob/dev' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
rmkraus committed Nov 15, 2015
2 parents eabf908 + 5d96ca1 commit 01daac0
Show file tree
Hide file tree
Showing 20 changed files with 391 additions and 71 deletions.
1 change: 1 addition & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ omit =
homeassistant/components/sensor/glances.py
homeassistant/components/sensor/mysensors.py
homeassistant/components/sensor/openweathermap.py
homeassistant/components/switch/orvibo.py
homeassistant/components/sensor/rest.py
homeassistant/components/sensor/rpi_gpio.py
homeassistant/components/sensor/sabnzbd.py
Expand Down
35 changes: 31 additions & 4 deletions homeassistant/bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@
start by calling homeassistant.start_home_assistant(bus)
"""

import os
import sys
from collections import defaultdict
import logging
import logging.handlers
from collections import defaultdict
import os
import shutil
import sys

import homeassistant.core as core
import homeassistant.util.dt as date_util
Expand All @@ -25,7 +26,7 @@
import homeassistant.components.group as group
from homeassistant.helpers.entity import Entity
from homeassistant.const import (
EVENT_COMPONENT_LOADED, CONF_LATITUDE, CONF_LONGITUDE,
__version__, EVENT_COMPONENT_LOADED, CONF_LATITUDE, CONF_LONGITUDE,
CONF_TEMPERATURE_UNIT, CONF_NAME, CONF_TIME_ZONE, CONF_CUSTOMIZE,
TEMP_CELCIUS, TEMP_FAHRENHEIT)

Expand Down Expand Up @@ -168,6 +169,7 @@ def from_config_dict(config, hass=None, config_dir=None, enable_log=True,
hass.config.config_dir = config_dir
mount_local_lib_path(config_dir)

process_ha_config_upgrade(hass)
process_ha_core_config(hass, config.get(core.DOMAIN, {}))

if enable_log:
Expand Down Expand Up @@ -281,6 +283,31 @@ def enable_logging(hass, verbose=False, daemon=False, log_rotate_days=None):
'Unable to setup error log %s (access denied)', err_log_path)


def process_ha_config_upgrade(hass):
""" Upgrade config if necessary. """
version_path = hass.config.path('.HA_VERSION')

try:
with open(version_path, 'rt') as inp:
conf_version = inp.readline().strip()
except FileNotFoundError:
# Last version to not have this file
conf_version = '0.7.7'

if conf_version == __version__:
return

_LOGGER.info('Upgrading config directory from %s to %s', conf_version,
__version__)

lib_path = hass.config.path('lib')
if os.path.isdir(lib_path):
shutil.rmtree(lib_path)

with open(version_path, 'wt') as outp:
outp.write(__version__)


def process_ha_core_config(hass, config):
""" Processes the [homeassistant] section from the config. """
hac = hass.config
Expand Down
8 changes: 6 additions & 2 deletions homeassistant/components/camera/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,10 @@ def _proxy_camera_image(handler, path_match, data):

if camera:
response = camera.camera_image()
handler.wfile.write(response)
if response is not None:
handler.wfile.write(response)
else:
handler.send_response(HTTP_NOT_FOUND)
else:
handler.send_response(HTTP_NOT_FOUND)

Expand Down Expand Up @@ -129,7 +132,8 @@ def _proxy_camera_mjpeg_stream(handler, path_match, data):
while True:

img_bytes = camera.camera_image()

if img_bytes is None:
continue
headers_str = '\r\n'.join((
'Content-length: {}'.format(len(img_bytes)),
'Content-type: image/jpeg',
Expand Down
16 changes: 12 additions & 4 deletions homeassistant/components/camera/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,19 @@ def __init__(self, device_info):
def camera_image(self):
""" Return a still image reponse from the camera. """
if self._username and self._password:
response = requests.get(
self._still_image_url,
auth=HTTPBasicAuth(self._username, self._password))
try:
response = requests.get(
self._still_image_url,
auth=HTTPBasicAuth(self._username, self._password))
except requests.exceptions.RequestException as error:
_LOGGER.error('Error getting camera image: %s', error)
return None
else:
response = requests.get(self._still_image_url)
try:
response = requests.get(self._still_image_url)
except requests.exceptions.RequestException as error:
_LOGGER.error('Error getting camera image: %s', error)
return None

return response.content

Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/frontend/version.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
""" DO NOT MODIFY. Auto-generated by build_frontend script """
VERSION = "75532015507fd544f46081ec0eeb5004"
VERSION = "b75e3c9ebd3de2dae0912a89499127a9"
85 changes: 38 additions & 47 deletions homeassistant/components/frontend/www_static/frontend.html

Large diffs are not rendered by default.

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions homeassistant/components/notify/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
import logging
import os

import homeassistant.bootstrap as bootstrap
from homeassistant.config import load_yaml_config_file
from homeassistant.loader import get_component
from homeassistant.helpers import config_per_platform

from homeassistant.const import CONF_NAME
Expand Down Expand Up @@ -45,8 +45,8 @@ def setup(hass, config):

for platform, p_config in config_per_platform(config, DOMAIN, _LOGGER):
# get platform
notify_implementation = get_component(
'notify.{}'.format(platform))
notify_implementation = bootstrap.prepare_setup_platform(
hass, config, DOMAIN, platform)

if notify_implementation is None:
_LOGGER.error("Unknown notification service specified.")
Expand Down
7 changes: 6 additions & 1 deletion homeassistant/components/script.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
CONF_DELAY = "delay"

ATTR_LAST_ACTION = 'last_action'
ATTR_CAN_CANCEL = 'can_cancel'

_LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -113,6 +114,8 @@ def __init__(self, hass, object_id, name, sequence):
self._cur = -1
self._last_action = None
self._listener = None
self._can_cancel = not any(CONF_DELAY in action for action
in self.sequence)

@property
def should_poll(self):
Expand All @@ -126,7 +129,9 @@ def name(self):
@property
def state_attributes(self):
""" Returns the state attributes. """
attrs = {}
attrs = {
ATTR_CAN_CANCEL: self._can_cancel
}

if self._last_action:
attrs[ATTR_LAST_ACTION] = self._last_action
Expand Down
4 changes: 4 additions & 0 deletions homeassistant/components/sensor/zwave.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
elif value.command_class == zwave.COMMAND_CLASS_SENSOR_MULTILEVEL:
add_devices([ZWaveMultilevelSensor(value)])

elif (value.command_class == zwave.COMMAND_CLASS_METER and
value.type == zwave.TYPE_DECIMAL):
add_devices([ZWaveMultilevelSensor(value)])


class ZWaveSensor(Entity):
""" Represents a Z-Wave sensor. """
Expand Down
6 changes: 4 additions & 2 deletions homeassistant/components/switch/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@

from homeassistant.const import (
STATE_ON, SERVICE_TURN_ON, SERVICE_TURN_OFF, ATTR_ENTITY_ID)
from homeassistant.components import group, discovery, wink, isy994, verisure
from homeassistant.components import (
group, discovery, wink, isy994, verisure, zwave)

DOMAIN = 'switch'
DEPENDENCIES = []
Expand All @@ -38,7 +39,8 @@
discovery.SERVICE_WEMO: 'wemo',
wink.DISCOVER_SWITCHES: 'wink',
isy994.DISCOVER_SWITCHES: 'isy994',
verisure.DISCOVER_SWITCHES: 'verisure'
verisure.DISCOVER_SWITCHES: 'verisure',
zwave.DISCOVER_SWITCHES: 'zwave',
}

PROP_TO_ATTR = {
Expand Down
75 changes: 75 additions & 0 deletions homeassistant/components/switch/orvibo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
"""
homeassistant.components.switch.orvibo
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Support for Orvibo S20 Wifi Smart Switches.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/switch.orvibo/
"""
import logging

from homeassistant.components.switch import SwitchDevice

from orvibo.s20 import S20, S20Exception

DEFAULT_NAME = "Orvibo S20 Switch"
REQUIREMENTS = ['orvibo==1.0.0']
_LOGGER = logging.getLogger(__name__)


# pylint: disable=unused-argument
def setup_platform(hass, config, add_devices_callback, discovery_info=None):
""" Find and return S20 switches. """
if config.get('host') is None:
_LOGGER.error("Missing required variable: host")
return
try:
s20 = S20(config.get('host'))
add_devices_callback([S20Switch(config.get('name', DEFAULT_NAME),
s20)])
except S20Exception:
_LOGGER.exception("S20 couldn't be initialized")


class S20Switch(SwitchDevice):
""" Represents an S20 switch. """
def __init__(self, name, s20):
self._name = name
self._s20 = s20
self._state = False

@property
def should_poll(self):
""" Poll. """
return True

@property
def name(self):
""" The name of the switch. """
return self._name

@property
def is_on(self):
""" True if device is on. """
return self._state

def update(self):
""" Update device state. """
try:
self._state = self._s20.on
except S20Exception:
_LOGGER.exception("Error while fetching S20 state")

def turn_on(self, **kwargs):
""" Turn the device on. """
try:
self._s20.on = True
except S20Exception:
_LOGGER.exception("Error while turning on S20")

def turn_off(self, **kwargs):
""" Turn the device off. """
try:
self._s20.on = False
except S20Exception:
_LOGGER.exception("Error while turning off S20")
76 changes: 76 additions & 0 deletions homeassistant/components/switch/zwave.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
"""
homeassistant.components.switch.zwave
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Zwave platform that handles simple binary switches.
"""
# pylint: disable=import-error
from openzwave.network import ZWaveNetwork
from pydispatch import dispatcher

import homeassistant.components.zwave as zwave

from homeassistant.components.switch import SwitchDevice


# pylint: disable=unused-argument
def setup_platform(hass, config, add_devices, discovery_info=None):
""" Find and return demo switches. """
if discovery_info is None:
return

node = zwave.NETWORK.nodes[discovery_info[zwave.ATTR_NODE_ID]]
value = node.values[discovery_info[zwave.ATTR_VALUE_ID]]

if value.command_class != zwave.COMMAND_CLASS_SWITCH_BINARY:
return
if value.type != zwave.TYPE_BOOL:
return
if value.genre != zwave.GENRE_USER:
return

value.set_change_verified(False)
add_devices([ZwaveSwitch(value)])


class ZwaveSwitch(SwitchDevice):
""" Provides a zwave switch. """
def __init__(self, value):
self._value = value
self._node = value.node

self._state = value.data

dispatcher.connect(
self._value_changed, ZWaveNetwork.SIGNAL_VALUE_CHANGED)

def _value_changed(self, value):
""" Called when a value has changed on the network. """
if self._value.value_id == value.value_id:
self._state = value.data
self.update_ha_state()

@property
def should_poll(self):
""" No polling needed for a demo switch. """
return False

@property
def name(self):
""" Returns the name of the device if any. """
name = self._node.name or "{}".format(self._node.product_name)

return "{}".format(name or self._value.label)

@property
def is_on(self):
""" True if device is on. """
return self._state

def turn_on(self, **kwargs):
""" Turn the device on. """
self._node.set_switch(self._value.value_id, True)

def turn_off(self, **kwargs):
""" Turn the device off. """
self._node.set_switch(self._value.value_id, False)
Loading

0 comments on commit 01daac0

Please sign in to comment.