mirror of
https://github.com/home-assistant/core.git
synced 2025-07-20 11:47:06 +00:00
Merge pull request #289 from rmkraus/pip_updates
Update dependency installs and prepare for pip deployment
This commit is contained in:
commit
5aa8814a67
@ -3,7 +3,7 @@ language: python
|
|||||||
python:
|
python:
|
||||||
- "3.4"
|
- "3.4"
|
||||||
install:
|
install:
|
||||||
- pip install -r requirements.txt
|
- pip install -r requirements_all.txt
|
||||||
- pip install flake8 pylint coveralls
|
- pip install flake8 pylint coveralls
|
||||||
script:
|
script:
|
||||||
- flake8 homeassistant --exclude bower_components,external
|
- flake8 homeassistant --exclude bower_components,external
|
||||||
|
@ -4,12 +4,11 @@ from __future__ import print_function
|
|||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import argparse
|
import argparse
|
||||||
import subprocess
|
|
||||||
import importlib
|
import importlib
|
||||||
|
|
||||||
DEPENDENCIES = ['requests>=2.0', 'pyyaml>=3.11', 'pytz>=2015.2']
|
from homeassistant import bootstrap
|
||||||
IS_VIRTUAL = (getattr(sys, 'base_prefix', sys.prefix) != sys.prefix or
|
import homeassistant.config as config_util
|
||||||
hasattr(sys, 'real_prefix'))
|
from homeassistant.const import EVENT_HOMEASSISTANT_START
|
||||||
|
|
||||||
|
|
||||||
def validate_python():
|
def validate_python():
|
||||||
@ -18,7 +17,7 @@ def validate_python():
|
|||||||
|
|
||||||
if major < 3 or (major == 3 and minor < 4):
|
if major < 3 or (major == 3 and minor < 4):
|
||||||
print("Home Assistant requires atleast Python 3.4")
|
print("Home Assistant requires atleast Python 3.4")
|
||||||
sys.exit()
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
def ensure_pip():
|
def ensure_pip():
|
||||||
@ -28,85 +27,43 @@ def ensure_pip():
|
|||||||
print("Home Assistant requires 'pip' to be installed.")
|
print("Home Assistant requires 'pip' to be installed.")
|
||||||
print("Please install pip: "
|
print("Please install pip: "
|
||||||
"https://pip.pypa.io/en/latest/installing.html")
|
"https://pip.pypa.io/en/latest/installing.html")
|
||||||
sys.exit()
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
# Copy of homeassistant.util.package because we can't import yet
|
|
||||||
def install_package(package):
|
|
||||||
"""Install a package on PyPi. Accepts pip compatible package strings.
|
|
||||||
Return boolean if install successfull."""
|
|
||||||
args = [sys.executable, '-m', 'pip', 'install', '--quiet', package]
|
|
||||||
if not IS_VIRTUAL:
|
|
||||||
args.append('--user')
|
|
||||||
try:
|
|
||||||
return 0 == subprocess.call(args)
|
|
||||||
except subprocess.SubprocessError:
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def validate_dependencies():
|
|
||||||
""" Validate all dependencies that HA uses. """
|
|
||||||
ensure_pip()
|
|
||||||
|
|
||||||
print("Validating dependencies...")
|
|
||||||
import_fail = False
|
|
||||||
|
|
||||||
for requirement in DEPENDENCIES:
|
|
||||||
if not install_package(requirement):
|
|
||||||
import_fail = True
|
|
||||||
print('Fatal Error: Unable to install dependency', requirement)
|
|
||||||
|
|
||||||
if import_fail:
|
|
||||||
print(("Install dependencies by running: "
|
|
||||||
"python3 -m pip install -r requirements.txt"))
|
|
||||||
sys.exit()
|
|
||||||
|
|
||||||
|
|
||||||
def ensure_path_and_load_bootstrap():
|
|
||||||
""" Ensure sys load path is correct and load Home Assistant bootstrap. """
|
|
||||||
try:
|
|
||||||
from homeassistant import bootstrap
|
|
||||||
|
|
||||||
except ImportError:
|
|
||||||
# This is to add support to load Home Assistant using
|
|
||||||
# `python3 homeassistant` instead of `python3 -m homeassistant`
|
|
||||||
|
|
||||||
# Insert the parent directory of this file into the module search path
|
|
||||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
|
|
||||||
|
|
||||||
from homeassistant import bootstrap
|
|
||||||
|
|
||||||
return bootstrap
|
|
||||||
|
|
||||||
|
|
||||||
def validate_git_submodules():
|
|
||||||
""" Validate the git submodules are cloned. """
|
|
||||||
try:
|
|
||||||
# pylint: disable=no-name-in-module, unused-variable
|
|
||||||
from homeassistant.external.noop import WORKING # noqa
|
|
||||||
except ImportError:
|
|
||||||
print("Repository submodules have not been initialized")
|
|
||||||
print("Please run: git submodule update --init --recursive")
|
|
||||||
sys.exit()
|
|
||||||
|
|
||||||
|
|
||||||
def ensure_config_path(config_dir):
|
def ensure_config_path(config_dir):
|
||||||
""" Gets the path to the configuration file.
|
""" Gets the path to the configuration file.
|
||||||
Creates one if it not exists. """
|
Creates one if it not exists. """
|
||||||
|
|
||||||
|
lib_dir = os.path.join(config_dir, 'lib')
|
||||||
|
|
||||||
# Test if configuration directory exists
|
# Test if configuration directory exists
|
||||||
if not os.path.isdir(config_dir):
|
if not os.path.isdir(config_dir):
|
||||||
print(('Fatal Error: Unable to find specified configuration '
|
if config_dir != config_util.get_default_config_dir():
|
||||||
'directory {} ').format(config_dir))
|
print(('Fatal Error: Specified configuration directory does '
|
||||||
sys.exit()
|
'not exist {} ').format(config_dir))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
import homeassistant.config as config_util
|
try:
|
||||||
|
os.mkdir(config_dir)
|
||||||
|
except OSError:
|
||||||
|
print(('Fatal Error: Unable to create default configuration '
|
||||||
|
'directory {} ').format(config_dir))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Test if library directory exists
|
||||||
|
if not os.path.isdir(lib_dir):
|
||||||
|
try:
|
||||||
|
os.mkdir(lib_dir)
|
||||||
|
except OSError:
|
||||||
|
print(('Fatal Error: Unable to create library '
|
||||||
|
'directory {} ').format(lib_dir))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
config_path = config_util.ensure_config_exists(config_dir)
|
config_path = config_util.ensure_config_exists(config_dir)
|
||||||
|
|
||||||
if config_path is None:
|
if config_path is None:
|
||||||
print('Error getting configuration path')
|
print('Error getting configuration path')
|
||||||
sys.exit()
|
sys.exit(1)
|
||||||
|
|
||||||
return config_path
|
return config_path
|
||||||
|
|
||||||
@ -117,7 +74,7 @@ def get_arguments():
|
|||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-c', '--config',
|
'-c', '--config',
|
||||||
metavar='path_to_config_dir',
|
metavar='path_to_config_dir',
|
||||||
default="config",
|
default=config_util.get_default_config_dir(),
|
||||||
help="Directory that contains the Home Assistant configuration")
|
help="Directory that contains the Home Assistant configuration")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--demo-mode',
|
'--demo-mode',
|
||||||
@ -134,14 +91,6 @@ def get_arguments():
|
|||||||
def main():
|
def main():
|
||||||
""" Starts Home Assistant. """
|
""" Starts Home Assistant. """
|
||||||
validate_python()
|
validate_python()
|
||||||
validate_dependencies()
|
|
||||||
|
|
||||||
# Windows needs this to pick up new modules
|
|
||||||
importlib.invalidate_caches()
|
|
||||||
|
|
||||||
bootstrap = ensure_path_and_load_bootstrap()
|
|
||||||
|
|
||||||
validate_git_submodules()
|
|
||||||
|
|
||||||
args = get_arguments()
|
args = get_arguments()
|
||||||
|
|
||||||
@ -149,18 +98,14 @@ def main():
|
|||||||
config_path = ensure_config_path(config_dir)
|
config_path = ensure_config_path(config_dir)
|
||||||
|
|
||||||
if args.demo_mode:
|
if args.demo_mode:
|
||||||
from homeassistant.components import frontend, demo
|
|
||||||
|
|
||||||
hass = bootstrap.from_config_dict({
|
hass = bootstrap.from_config_dict({
|
||||||
frontend.DOMAIN: {},
|
'frontend': {},
|
||||||
demo.DOMAIN: {}
|
'demo': {}
|
||||||
})
|
}, config_dir=config_dir)
|
||||||
else:
|
else:
|
||||||
hass = bootstrap.from_config_file(config_path)
|
hass = bootstrap.from_config_file(config_path)
|
||||||
|
|
||||||
if args.open_ui:
|
if args.open_ui:
|
||||||
from homeassistant.const import EVENT_HOMEASSISTANT_START
|
|
||||||
|
|
||||||
def open_browser(event):
|
def open_browser(event):
|
||||||
""" Open the webinterface in a browser. """
|
""" Open the webinterface in a browser. """
|
||||||
if hass.config.api is not None:
|
if hass.config.api is not None:
|
||||||
|
@ -10,6 +10,7 @@ start by calling homeassistant.start_home_assistant(bus)
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
import logging
|
import logging
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
@ -61,13 +62,13 @@ def setup_component(hass, domain, config=None):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def _handle_requirements(component, name):
|
def _handle_requirements(hass, component, name):
|
||||||
""" Installs requirements for component. """
|
""" Installs requirements for component. """
|
||||||
if not hasattr(component, 'REQUIREMENTS'):
|
if not hasattr(component, 'REQUIREMENTS'):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
for req in component.REQUIREMENTS:
|
for req in component.REQUIREMENTS:
|
||||||
if not pkg_util.install_package(req):
|
if not pkg_util.install_package(req, target=hass.config.path('lib')):
|
||||||
_LOGGER.error('Not initializing %s because could not install '
|
_LOGGER.error('Not initializing %s because could not install '
|
||||||
'dependency %s', name, req)
|
'dependency %s', name, req)
|
||||||
return False
|
return False
|
||||||
@ -88,7 +89,7 @@ def _setup_component(hass, domain, config):
|
|||||||
domain, ", ".join(missing_deps))
|
domain, ", ".join(missing_deps))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if not _handle_requirements(component, domain):
|
if not _handle_requirements(hass, component, domain):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -138,14 +139,19 @@ def prepare_setup_platform(hass, config, domain, platform_name):
|
|||||||
component)
|
component)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if not _handle_requirements(platform, platform_path):
|
if not _handle_requirements(hass, platform, platform_path):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return platform
|
return platform
|
||||||
|
|
||||||
|
|
||||||
|
def mount_local_lib_path(config_dir):
|
||||||
|
""" Add local library to Python Path """
|
||||||
|
sys.path.insert(0, os.path.join(config_dir, 'lib'))
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=too-many-branches, too-many-statements
|
# pylint: disable=too-many-branches, too-many-statements
|
||||||
def from_config_dict(config, hass=None):
|
def from_config_dict(config, hass=None, config_dir=None):
|
||||||
"""
|
"""
|
||||||
Tries to configure Home Assistant from a config dict.
|
Tries to configure Home Assistant from a config dict.
|
||||||
|
|
||||||
@ -153,6 +159,10 @@ def from_config_dict(config, hass=None):
|
|||||||
"""
|
"""
|
||||||
if hass is None:
|
if hass is None:
|
||||||
hass = core.HomeAssistant()
|
hass = core.HomeAssistant()
|
||||||
|
if config_dir is not None:
|
||||||
|
config_dir = os.path.abspath(config_dir)
|
||||||
|
hass.config.config_dir = config_dir
|
||||||
|
mount_local_lib_path(config_dir)
|
||||||
|
|
||||||
process_ha_core_config(hass, config.get(core.DOMAIN, {}))
|
process_ha_core_config(hass, config.get(core.DOMAIN, {}))
|
||||||
|
|
||||||
@ -195,7 +205,9 @@ def from_config_file(config_path, hass=None):
|
|||||||
hass = core.HomeAssistant()
|
hass = core.HomeAssistant()
|
||||||
|
|
||||||
# Set config dir to directory holding config file
|
# Set config dir to directory holding config file
|
||||||
hass.config.config_dir = os.path.abspath(os.path.dirname(config_path))
|
config_dir = os.path.abspath(os.path.dirname(config_path))
|
||||||
|
hass.config.config_dir = config_dir
|
||||||
|
mount_local_lib_path(config_dir)
|
||||||
|
|
||||||
config_dict = config_util.load_config_file(config_path)
|
config_dict = config_util.load_config_file(config_path)
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ from homeassistant.components.device_tracker import DOMAIN
|
|||||||
MIN_TIME_BETWEEN_SCANS = timedelta(seconds=5)
|
MIN_TIME_BETWEEN_SCANS = timedelta(seconds=5)
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
REQUIREMENTS = ['pynetgear>=0.3']
|
REQUIREMENTS = ['pynetgear==0.3']
|
||||||
|
|
||||||
|
|
||||||
def get_scanner(hass, config):
|
def get_scanner(hass, config):
|
||||||
|
@ -26,8 +26,12 @@ from collections import namedtuple
|
|||||||
import subprocess
|
import subprocess
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from libnmap.process import NmapProcess
|
try:
|
||||||
from libnmap.parser import NmapParser, NmapParserException
|
from libnmap.process import NmapProcess
|
||||||
|
from libnmap.parser import NmapParser, NmapParserException
|
||||||
|
LIB_LOADED = True
|
||||||
|
except ImportError:
|
||||||
|
LIB_LOADED = False
|
||||||
|
|
||||||
import homeassistant.util.dt as dt_util
|
import homeassistant.util.dt as dt_util
|
||||||
from homeassistant.const import CONF_HOSTS
|
from homeassistant.const import CONF_HOSTS
|
||||||
@ -43,7 +47,7 @@ _LOGGER = logging.getLogger(__name__)
|
|||||||
# interval in minutes to exclude devices from a scan while they are home
|
# interval in minutes to exclude devices from a scan while they are home
|
||||||
CONF_HOME_INTERVAL = "home_interval"
|
CONF_HOME_INTERVAL = "home_interval"
|
||||||
|
|
||||||
REQUIREMENTS = ['python-libnmap>=0.6.3']
|
REQUIREMENTS = ['python-libnmap==0.6.1']
|
||||||
|
|
||||||
|
|
||||||
def get_scanner(hass, config):
|
def get_scanner(hass, config):
|
||||||
@ -52,6 +56,10 @@ def get_scanner(hass, config):
|
|||||||
_LOGGER):
|
_LOGGER):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
if not LIB_LOADED:
|
||||||
|
_LOGGER.error("Error while importing dependency python-libnmap.")
|
||||||
|
return False
|
||||||
|
|
||||||
scanner = NmapDeviceScanner(config[DOMAIN])
|
scanner = NmapDeviceScanner(config[DOMAIN])
|
||||||
|
|
||||||
return scanner if scanner.success_init else None
|
return scanner if scanner.success_init else None
|
||||||
|
@ -19,7 +19,7 @@ from homeassistant.const import (
|
|||||||
|
|
||||||
DOMAIN = "discovery"
|
DOMAIN = "discovery"
|
||||||
DEPENDENCIES = []
|
DEPENDENCIES = []
|
||||||
REQUIREMENTS = ['netdisco>=0.3']
|
REQUIREMENTS = ['netdisco==0.3']
|
||||||
|
|
||||||
SCAN_INTERVAL = 300 # seconds
|
SCAN_INTERVAL = 300 # seconds
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ from homeassistant.const import (
|
|||||||
|
|
||||||
DOMAIN = "isy994"
|
DOMAIN = "isy994"
|
||||||
DEPENDENCIES = []
|
DEPENDENCIES = []
|
||||||
REQUIREMENTS = ['PyISY>=1.0.5']
|
REQUIREMENTS = ['PyISY==1.0.5']
|
||||||
DISCOVER_LIGHTS = "isy994.lights"
|
DISCOVER_LIGHTS = "isy994.lights"
|
||||||
DISCOVER_SWITCHES = "isy994.switches"
|
DISCOVER_SWITCHES = "isy994.switches"
|
||||||
DISCOVER_SENSORS = "isy994.sensors"
|
DISCOVER_SENSORS = "isy994.sensors"
|
||||||
|
@ -14,7 +14,7 @@ from homeassistant.const import (
|
|||||||
|
|
||||||
DOMAIN = "keyboard"
|
DOMAIN = "keyboard"
|
||||||
DEPENDENCIES = []
|
DEPENDENCIES = []
|
||||||
REQUIREMENTS = ['pyuserinput>=0.1.9']
|
REQUIREMENTS = ['pyuserinput==0.1.9']
|
||||||
|
|
||||||
|
|
||||||
def volume_up(hass):
|
def volume_up(hass):
|
||||||
|
@ -16,7 +16,7 @@ from homeassistant.components.light import (
|
|||||||
ATTR_FLASH, FLASH_LONG, FLASH_SHORT, ATTR_EFFECT,
|
ATTR_FLASH, FLASH_LONG, FLASH_SHORT, ATTR_EFFECT,
|
||||||
EFFECT_COLORLOOP)
|
EFFECT_COLORLOOP)
|
||||||
|
|
||||||
REQUIREMENTS = ['phue>=0.8']
|
REQUIREMENTS = ['phue==0.8']
|
||||||
MIN_TIME_BETWEEN_SCANS = timedelta(seconds=10)
|
MIN_TIME_BETWEEN_SCANS = timedelta(seconds=10)
|
||||||
MIN_TIME_BETWEEN_FORCED_SCANS = timedelta(milliseconds=100)
|
MIN_TIME_BETWEEN_FORCED_SCANS = timedelta(milliseconds=100)
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ from homeassistant.components.light import (Light, ATTR_BRIGHTNESS,
|
|||||||
from homeassistant.util.color import color_RGB_to_xy
|
from homeassistant.util.color import color_RGB_to_xy
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
REQUIREMENTS = ['ledcontroller>=1.0.7']
|
REQUIREMENTS = ['ledcontroller==1.0.7']
|
||||||
|
|
||||||
|
|
||||||
def setup_platform(hass, config, add_devices_callback, discovery_info=None):
|
def setup_platform(hass, config, add_devices_callback, discovery_info=None):
|
||||||
|
@ -9,7 +9,7 @@ from homeassistant.components.light import Light, ATTR_BRIGHTNESS
|
|||||||
from homeassistant.const import ATTR_FRIENDLY_NAME
|
from homeassistant.const import ATTR_FRIENDLY_NAME
|
||||||
import tellcore.constants as tellcore_constants
|
import tellcore.constants as tellcore_constants
|
||||||
|
|
||||||
REQUIREMENTS = ['tellcore-py>=1.0.4']
|
REQUIREMENTS = ['tellcore-py==1.0.4']
|
||||||
|
|
||||||
|
|
||||||
def setup_platform(hass, config, add_devices_callback, discovery_info=None):
|
def setup_platform(hass, config, add_devices_callback, discovery_info=None):
|
||||||
|
@ -9,8 +9,8 @@ from homeassistant.components.light import ATTR_BRIGHTNESS
|
|||||||
from homeassistant.components.wink import WinkToggleDevice
|
from homeassistant.components.wink import WinkToggleDevice
|
||||||
from homeassistant.const import CONF_ACCESS_TOKEN
|
from homeassistant.const import CONF_ACCESS_TOKEN
|
||||||
|
|
||||||
REQUIREMENTS = ['https://github.com/balloob/python-wink/archive/master.zip'
|
REQUIREMENTS = ['https://github.com/balloob/python-wink/archive/' +
|
||||||
'#pywink>=0.1']
|
'c2b700e8ca866159566ecf5e644d9c297f69f257.zip']
|
||||||
|
|
||||||
|
|
||||||
def setup_platform(hass, config, add_devices_callback, discovery_info=None):
|
def setup_platform(hass, config, add_devices_callback, discovery_info=None):
|
||||||
|
@ -19,7 +19,7 @@ from homeassistant.components.media_player import (
|
|||||||
SUPPORT_PREVIOUS_TRACK, SUPPORT_NEXT_TRACK,
|
SUPPORT_PREVIOUS_TRACK, SUPPORT_NEXT_TRACK,
|
||||||
MEDIA_TYPE_MUSIC, MEDIA_TYPE_TVSHOW, MEDIA_TYPE_VIDEO)
|
MEDIA_TYPE_MUSIC, MEDIA_TYPE_TVSHOW, MEDIA_TYPE_VIDEO)
|
||||||
|
|
||||||
REQUIREMENTS = ['pychromecast>=0.6.10']
|
REQUIREMENTS = ['pychromecast==0.6.10']
|
||||||
CONF_IGNORE_CEC = 'ignore_cec'
|
CONF_IGNORE_CEC = 'ignore_cec'
|
||||||
CAST_SPLASH = 'https://home-assistant.io/images/cast/splash.png'
|
CAST_SPLASH = 'https://home-assistant.io/images/cast/splash.png'
|
||||||
SUPPORT_CAST = SUPPORT_PAUSE | SUPPORT_VOLUME_SET | SUPPORT_VOLUME_MUTE | \
|
SUPPORT_CAST = SUPPORT_PAUSE | SUPPORT_VOLUME_SET | SUPPORT_VOLUME_MUTE | \
|
||||||
|
@ -48,7 +48,7 @@ except ImportError:
|
|||||||
jsonrpc_requests = None
|
jsonrpc_requests = None
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
REQUIREMENTS = ['jsonrpc-requests>=0.1']
|
REQUIREMENTS = ['jsonrpc-requests==0.1']
|
||||||
|
|
||||||
SUPPORT_KODI = SUPPORT_PAUSE | SUPPORT_VOLUME_SET | SUPPORT_VOLUME_MUTE | \
|
SUPPORT_KODI = SUPPORT_PAUSE | SUPPORT_VOLUME_SET | SUPPORT_VOLUME_MUTE | \
|
||||||
SUPPORT_PREVIOUS_TRACK | SUPPORT_NEXT_TRACK | SUPPORT_SEEK
|
SUPPORT_PREVIOUS_TRACK | SUPPORT_NEXT_TRACK | SUPPORT_SEEK
|
||||||
|
@ -48,7 +48,7 @@ from homeassistant.components.media_player import (
|
|||||||
MEDIA_TYPE_MUSIC)
|
MEDIA_TYPE_MUSIC)
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
REQUIREMENTS = ['python-mpd2>=0.5.4']
|
REQUIREMENTS = ['python-mpd2==0.5.4']
|
||||||
|
|
||||||
SUPPORT_MPD = SUPPORT_PAUSE | SUPPORT_VOLUME_SET | SUPPORT_TURN_OFF | \
|
SUPPORT_MPD = SUPPORT_PAUSE | SUPPORT_VOLUME_SET | SUPPORT_TURN_OFF | \
|
||||||
SUPPORT_PREVIOUS_TRACK | SUPPORT_NEXT_TRACK
|
SUPPORT_PREVIOUS_TRACK | SUPPORT_NEXT_TRACK
|
||||||
|
@ -38,8 +38,8 @@ from homeassistant.const import (EVENT_HOMEASSISTANT_START,
|
|||||||
DOMAIN = "modbus"
|
DOMAIN = "modbus"
|
||||||
|
|
||||||
DEPENDENCIES = []
|
DEPENDENCIES = []
|
||||||
REQUIREMENTS = ['https://github.com/bashwork/pymodbus/archive/python3.zip'
|
REQUIREMENTS = ['https://github.com/bashwork/pymodbus/archive/' +
|
||||||
'#pymodbus>=1.2.0']
|
'd7fc4f1cc975631e0a9011390e8017f64b612661.zip']
|
||||||
|
|
||||||
# Type of network
|
# Type of network
|
||||||
MEDIUM = "type"
|
MEDIUM = "type"
|
||||||
|
@ -46,7 +46,7 @@ The keep alive in seconds for this client. Default is 60.
|
|||||||
import logging
|
import logging
|
||||||
import socket
|
import socket
|
||||||
|
|
||||||
from homeassistant.core import HomeAssistantError
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
import homeassistant.util as util
|
import homeassistant.util as util
|
||||||
from homeassistant.helpers import validate_config
|
from homeassistant.helpers import validate_config
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
@ -66,7 +66,7 @@ SERVICE_PUBLISH = 'publish'
|
|||||||
EVENT_MQTT_MESSAGE_RECEIVED = 'MQTT_MESSAGE_RECEIVED'
|
EVENT_MQTT_MESSAGE_RECEIVED = 'MQTT_MESSAGE_RECEIVED'
|
||||||
|
|
||||||
DEPENDENCIES = []
|
DEPENDENCIES = []
|
||||||
REQUIREMENTS = ['paho-mqtt>=1.1']
|
REQUIREMENTS = ['paho-mqtt==1.1']
|
||||||
|
|
||||||
CONF_BROKER = 'broker'
|
CONF_BROKER = 'broker'
|
||||||
CONF_PORT = 'port'
|
CONF_PORT = 'port'
|
||||||
|
@ -28,7 +28,7 @@ from homeassistant.components.notify import (
|
|||||||
from homeassistant.const import CONF_API_KEY
|
from homeassistant.const import CONF_API_KEY
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
REQUIREMENTS = ['pushbullet.py>=0.7.1']
|
REQUIREMENTS = ['pushbullet.py==0.7.1']
|
||||||
|
|
||||||
|
|
||||||
def get_service(hass, config):
|
def get_service(hass, config):
|
||||||
|
@ -42,7 +42,7 @@ from homeassistant.components.notify import (
|
|||||||
DOMAIN, ATTR_TITLE, BaseNotificationService)
|
DOMAIN, ATTR_TITLE, BaseNotificationService)
|
||||||
from homeassistant.const import CONF_API_KEY
|
from homeassistant.const import CONF_API_KEY
|
||||||
|
|
||||||
REQUIREMENTS = ['python-pushover>=0.2']
|
REQUIREMENTS = ['python-pushover==0.2']
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ from homeassistant.components.notify import (
|
|||||||
DOMAIN, BaseNotificationService)
|
DOMAIN, BaseNotificationService)
|
||||||
from homeassistant.const import CONF_API_KEY
|
from homeassistant.const import CONF_API_KEY
|
||||||
|
|
||||||
REQUIREMENTS = ['slacker>=0.6.8']
|
REQUIREMENTS = ['slacker==0.6.8']
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ from homeassistant.helpers import validate_config
|
|||||||
from homeassistant.components.notify import (
|
from homeassistant.components.notify import (
|
||||||
DOMAIN, ATTR_TITLE, BaseNotificationService)
|
DOMAIN, ATTR_TITLE, BaseNotificationService)
|
||||||
|
|
||||||
REQUIREMENTS = ['sleekxmpp>=1.3.1', 'dnspython3>=1.12.0']
|
REQUIREMENTS = ['sleekxmpp==1.3.1', 'dnspython3==1.12.0']
|
||||||
|
|
||||||
|
|
||||||
def get_service(hass, config):
|
def get_service(hass, config):
|
||||||
|
@ -71,7 +71,7 @@ from homeassistant.util import Throttle
|
|||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers.entity import Entity
|
||||||
|
|
||||||
|
|
||||||
REQUIREMENTS = ['blockchain>=1.1.2']
|
REQUIREMENTS = ['blockchain==1.1.2']
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
OPTION_TYPES = {
|
OPTION_TYPES = {
|
||||||
'wallet': ['Wallet balance', 'BTC'],
|
'wallet': ['Wallet balance', 'BTC'],
|
||||||
|
@ -44,7 +44,8 @@ from homeassistant.const import TEMP_FAHRENHEIT
|
|||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers.entity import Entity
|
||||||
|
|
||||||
# update this requirement to upstream as soon as it supports python3
|
# update this requirement to upstream as soon as it supports python3
|
||||||
REQUIREMENTS = ['git+git://github.com/mala-zaba/Adafruit_Python_DHT']
|
REQUIREMENTS = ['http://github.com/mala-zaba/Adafruit_Python_DHT/archive/' +
|
||||||
|
'4101340de8d2457dd194bca1e8d11cbfc237e919.zip']
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
SENSOR_TYPES = {
|
SENSOR_TYPES = {
|
||||||
'temperature': ['Temperature', ''],
|
'temperature': ['Temperature', ''],
|
||||||
|
@ -49,7 +49,7 @@ Details for the API : https://developer.forecast.io/docs/v2
|
|||||||
import logging
|
import logging
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
|
||||||
REQUIREMENTS = ['python-forecastio>=1.3.3']
|
REQUIREMENTS = ['python-forecastio==1.3.3']
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import forecastio
|
import forecastio
|
||||||
|
@ -36,8 +36,8 @@ ATTR_NODE_ID = "node_id"
|
|||||||
ATTR_CHILD_ID = "child_id"
|
ATTR_CHILD_ID = "child_id"
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
REQUIREMENTS = ['https://github.com/theolind/pymysensors/archive/master.zip'
|
REQUIREMENTS = ['https://github.com/theolind/pymysensors/archive/' +
|
||||||
'#egg=pymysensors-0.1']
|
'35b87d880147a34107da0d40cb815d75e6cb4af7.zip']
|
||||||
|
|
||||||
|
|
||||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||||
|
@ -48,7 +48,7 @@ from homeassistant.util import Throttle
|
|||||||
from homeassistant.const import (CONF_API_KEY, TEMP_CELCIUS, TEMP_FAHRENHEIT)
|
from homeassistant.const import (CONF_API_KEY, TEMP_CELCIUS, TEMP_FAHRENHEIT)
|
||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers.entity import Entity
|
||||||
|
|
||||||
REQUIREMENTS = ['pyowm>=2.2.1']
|
REQUIREMENTS = ['pyowm==2.2.1']
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
SENSOR_TYPES = {
|
SENSOR_TYPES = {
|
||||||
'weather': ['Condition', ''],
|
'weather': ['Condition', ''],
|
||||||
|
@ -26,8 +26,8 @@ from collections import OrderedDict
|
|||||||
from homeassistant.const import (TEMP_CELCIUS)
|
from homeassistant.const import (TEMP_CELCIUS)
|
||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers.entity import Entity
|
||||||
|
|
||||||
REQUIREMENTS = ['https://github.com/Danielhiversen/pyRFXtrx/archive/master.zip'
|
REQUIREMENTS = ['https://github.com/Danielhiversen/pyRFXtrx/archive/' +
|
||||||
'#RFXtrx>=0.15']
|
'ec7a1aaddf8270db6e5da1c13d58c1547effd7cf.zip']
|
||||||
|
|
||||||
DATA_TYPES = OrderedDict([
|
DATA_TYPES = OrderedDict([
|
||||||
('Temperature', TEMP_CELCIUS),
|
('Temperature', TEMP_CELCIUS),
|
||||||
|
@ -53,7 +53,7 @@ DEFAULT_VALUE_HIGH = "HIGH"
|
|||||||
DEFAULT_VALUE_LOW = "LOW"
|
DEFAULT_VALUE_LOW = "LOW"
|
||||||
DEFAULT_BOUNCETIME = 50
|
DEFAULT_BOUNCETIME = 50
|
||||||
|
|
||||||
REQUIREMENTS = ['RPi.GPIO>=0.5.11']
|
REQUIREMENTS = ['RPi.GPIO==0.5.11']
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ import homeassistant.util.dt as dt_util
|
|||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers.entity import Entity
|
||||||
from homeassistant.const import STATE_ON, STATE_OFF
|
from homeassistant.const import STATE_ON, STATE_OFF
|
||||||
|
|
||||||
REQUIREMENTS = ['psutil>=3.0.0']
|
REQUIREMENTS = ['psutil==3.0.0']
|
||||||
SENSOR_TYPES = {
|
SENSOR_TYPES = {
|
||||||
'disk_use_percent': ['Disk Use', '%'],
|
'disk_use_percent': ['Disk Use', '%'],
|
||||||
'disk_use': ['Disk Use', 'GiB'],
|
'disk_use': ['Disk Use', 'GiB'],
|
||||||
|
@ -35,7 +35,7 @@ import homeassistant.util as util
|
|||||||
|
|
||||||
DatatypeDescription = namedtuple("DatatypeDescription", ['name', 'unit'])
|
DatatypeDescription = namedtuple("DatatypeDescription", ['name', 'unit'])
|
||||||
|
|
||||||
REQUIREMENTS = ['tellcore-py>=1.0.4']
|
REQUIREMENTS = ['tellcore-py==1.0.4']
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=unused-argument
|
# pylint: disable=unused-argument
|
||||||
|
@ -18,7 +18,8 @@ from homeassistant.const import CONF_NAME, DEVICE_DEFAULT_NAME
|
|||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
REQUIREMENTS = ['https://github.com/rkabadi/temper-python/archive/master.zip']
|
REQUIREMENTS = ['https://github.com/rkabadi/temper-python/archive/' +
|
||||||
|
'3dbdaf2d87b8db9a3cd6e5585fc704537dd2d09b.zip']
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=unused-argument
|
# pylint: disable=unused-argument
|
||||||
|
@ -67,7 +67,7 @@ from transmissionrpc.error import TransmissionError
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
REQUIREMENTS = ['transmissionrpc>=0.11']
|
REQUIREMENTS = ['transmissionrpc==0.11']
|
||||||
SENSOR_TYPES = {
|
SENSOR_TYPES = {
|
||||||
'current_status': ['Status', ''],
|
'current_status': ['Status', ''],
|
||||||
'download_speed': ['Down Speed', 'MB/s'],
|
'download_speed': ['Down Speed', 'MB/s'],
|
||||||
|
@ -8,8 +8,8 @@ import logging
|
|||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers.entity import Entity
|
||||||
from homeassistant.const import CONF_ACCESS_TOKEN, STATE_OPEN, STATE_CLOSED
|
from homeassistant.const import CONF_ACCESS_TOKEN, STATE_OPEN, STATE_CLOSED
|
||||||
|
|
||||||
REQUIREMENTS = ['https://github.com/balloob/python-wink/archive/master.zip'
|
REQUIREMENTS = ['https://github.com/balloob/python-wink/archive/' +
|
||||||
'#pywink>=0.1']
|
'c2b700e8ca866159566ecf5e644d9c297f69f257.zip']
|
||||||
|
|
||||||
|
|
||||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||||
|
@ -31,7 +31,7 @@ from homeassistant.helpers.entity import Entity
|
|||||||
from homeassistant.components.scheduler import ServiceEventListener
|
from homeassistant.components.scheduler import ServiceEventListener
|
||||||
|
|
||||||
DEPENDENCIES = []
|
DEPENDENCIES = []
|
||||||
REQUIREMENTS = ['astral>=0.8.1']
|
REQUIREMENTS = ['astral==0.8.1']
|
||||||
DOMAIN = "sun"
|
DOMAIN = "sun"
|
||||||
ENTITY_ID = "sun.sun"
|
ENTITY_ID = "sun.sun"
|
||||||
|
|
||||||
|
@ -44,7 +44,8 @@ from homeassistant.const import CONF_HOST, CONF_USERNAME, CONF_PASSWORD,\
|
|||||||
DEFAULT_USERNAME = 'admin'
|
DEFAULT_USERNAME = 'admin'
|
||||||
DEFAULT_PASSWORD = '1234'
|
DEFAULT_PASSWORD = '1234'
|
||||||
DEVICE_DEFAULT_NAME = 'Edimax Smart Plug'
|
DEVICE_DEFAULT_NAME = 'Edimax Smart Plug'
|
||||||
REQUIREMENTS = ['https://github.com/rkabadi/pyedimax/archive/master.zip']
|
REQUIREMENTS = ['https://github.com/rkabadi/pyedimax/archive/' +
|
||||||
|
'365301ce3ff26129a7910c501ead09ea625f3700.zip']
|
||||||
|
|
||||||
# setup logger
|
# setup logger
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
@ -49,7 +49,7 @@ except ImportError:
|
|||||||
hikvision.api = None
|
hikvision.api = None
|
||||||
|
|
||||||
_LOGGING = logging.getLogger(__name__)
|
_LOGGING = logging.getLogger(__name__)
|
||||||
REQUIREMENTS = ['hikvision>=0.4']
|
REQUIREMENTS = ['hikvision==0.4']
|
||||||
# pylint: disable=too-many-arguments
|
# pylint: disable=too-many-arguments
|
||||||
# pylint: disable=too-many-instance-attributes
|
# pylint: disable=too-many-instance-attributes
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ from homeassistant.const import (DEVICE_DEFAULT_NAME,
|
|||||||
|
|
||||||
DEFAULT_INVERT_LOGIC = False
|
DEFAULT_INVERT_LOGIC = False
|
||||||
|
|
||||||
REQUIREMENTS = ['RPi.GPIO>=0.5.11']
|
REQUIREMENTS = ['RPi.GPIO==0.5.11']
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ import tellcore.constants as tellcore_constants
|
|||||||
|
|
||||||
SINGAL_REPETITIONS = 1
|
SINGAL_REPETITIONS = 1
|
||||||
|
|
||||||
REQUIREMENTS = ['tellcore-py>=1.0.4']
|
REQUIREMENTS = ['tellcore-py==1.0.4']
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=unused-argument
|
# pylint: disable=unused-argument
|
||||||
|
@ -48,7 +48,7 @@ from transmissionrpc.error import TransmissionError
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
_LOGGING = logging.getLogger(__name__)
|
_LOGGING = logging.getLogger(__name__)
|
||||||
REQUIREMENTS = ['transmissionrpc>=0.11']
|
REQUIREMENTS = ['transmissionrpc==0.11']
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=unused-argument
|
# pylint: disable=unused-argument
|
||||||
|
@ -8,7 +8,7 @@ import logging
|
|||||||
|
|
||||||
from homeassistant.components.switch import SwitchDevice
|
from homeassistant.components.switch import SwitchDevice
|
||||||
|
|
||||||
REQUIREMENTS = ['pywemo>=0.2']
|
REQUIREMENTS = ['pywemo==0.2']
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=unused-argument
|
# pylint: disable=unused-argument
|
||||||
|
@ -9,8 +9,8 @@ import logging
|
|||||||
from homeassistant.components.wink import WinkToggleDevice
|
from homeassistant.components.wink import WinkToggleDevice
|
||||||
from homeassistant.const import CONF_ACCESS_TOKEN
|
from homeassistant.const import CONF_ACCESS_TOKEN
|
||||||
|
|
||||||
REQUIREMENTS = ['https://github.com/balloob/python-wink/archive/master.zip'
|
REQUIREMENTS = ['https://github.com/balloob/python-wink/archive/' +
|
||||||
'#pywink>=0.1']
|
'c2b700e8ca866159566ecf5e644d9c297f69f257.zip']
|
||||||
|
|
||||||
|
|
||||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||||
|
@ -6,7 +6,7 @@ import logging
|
|||||||
from homeassistant.components.thermostat import ThermostatDevice
|
from homeassistant.components.thermostat import ThermostatDevice
|
||||||
from homeassistant.const import (CONF_USERNAME, CONF_PASSWORD, TEMP_CELCIUS)
|
from homeassistant.const import (CONF_USERNAME, CONF_PASSWORD, TEMP_CELCIUS)
|
||||||
|
|
||||||
REQUIREMENTS = ['python-nest>=2.4.0']
|
REQUIREMENTS = ['python-nest==2.4.0']
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=unused-argument
|
# pylint: disable=unused-argument
|
||||||
|
@ -61,7 +61,8 @@ DISCOVER_SWITCHES = 'verisure.switches'
|
|||||||
|
|
||||||
DEPENDENCIES = []
|
DEPENDENCIES = []
|
||||||
REQUIREMENTS = [
|
REQUIREMENTS = [
|
||||||
'https://github.com/persandstrom/python-verisure/archive/master.zip'
|
'https://github.com/persandstrom/python-verisure/archive/' +
|
||||||
|
'9873c4527f01b1ba1f72ae60f7f35854390d59be.zip'
|
||||||
]
|
]
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
@ -16,8 +16,8 @@ from homeassistant.const import (
|
|||||||
|
|
||||||
DOMAIN = "wink"
|
DOMAIN = "wink"
|
||||||
DEPENDENCIES = []
|
DEPENDENCIES = []
|
||||||
REQUIREMENTS = ['https://github.com/balloob/python-wink/archive/master.zip'
|
REQUIREMENTS = ['https://github.com/balloob/python-wink/archive/' +
|
||||||
'#pywink>=0.1']
|
'c2b700e8ca866159566ecf5e644d9c297f69f257.zip']
|
||||||
|
|
||||||
DISCOVER_LIGHTS = "wink.lights"
|
DISCOVER_LIGHTS = "wink.lights"
|
||||||
DISCOVER_SWITCHES = "wink.switches"
|
DISCOVER_SWITCHES = "wink.switches"
|
||||||
|
@ -12,7 +12,7 @@ from homeassistant.const import (
|
|||||||
|
|
||||||
DOMAIN = "zwave"
|
DOMAIN = "zwave"
|
||||||
DEPENDENCIES = []
|
DEPENDENCIES = []
|
||||||
REQUIREMENTS = ['pydispatcher>=2.0.5']
|
REQUIREMENTS = ['pydispatcher==2.0.5']
|
||||||
|
|
||||||
CONF_USB_STICK_PATH = "usb_path"
|
CONF_USB_STICK_PATH = "usb_path"
|
||||||
DEFAULT_CONF_USB_STICK_PATH = "/zwaveusbstick"
|
DEFAULT_CONF_USB_STICK_PATH = "/zwaveusbstick"
|
||||||
|
@ -7,7 +7,7 @@ Module to help with parsing and generating configuration files.
|
|||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from homeassistant.core import HomeAssistantError
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
CONF_LATITUDE, CONF_LONGITUDE, CONF_TEMPERATURE_UNIT, CONF_NAME,
|
CONF_LATITUDE, CONF_LONGITUDE, CONF_TEMPERATURE_UNIT, CONF_NAME,
|
||||||
CONF_TIME_ZONE)
|
CONF_TIME_ZONE)
|
||||||
@ -16,6 +16,7 @@ import homeassistant.util.location as loc_util
|
|||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
YAML_CONFIG_FILE = 'configuration.yaml'
|
YAML_CONFIG_FILE = 'configuration.yaml'
|
||||||
|
CONFIG_DIR_NAME = '.homeassistant'
|
||||||
|
|
||||||
DEFAULT_CONFIG = (
|
DEFAULT_CONFIG = (
|
||||||
# Tuples (attribute, default, auto detect property, description)
|
# Tuples (attribute, default, auto detect property, description)
|
||||||
@ -39,6 +40,13 @@ DEFAULT_COMPONENTS = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def get_default_config_dir():
|
||||||
|
""" Put together the default configuration directory based on OS. """
|
||||||
|
data_dir = os.getenv('APPDATA') if os.name == "nt" \
|
||||||
|
else os.path.expanduser('~')
|
||||||
|
return os.path.join(data_dir, CONFIG_DIR_NAME)
|
||||||
|
|
||||||
|
|
||||||
def ensure_config_exists(config_dir, detect_location=True):
|
def ensure_config_exists(config_dir, detect_location=True):
|
||||||
""" Ensures a config file exists in given config dir.
|
""" Ensures a config file exists in given config dir.
|
||||||
Creating a default one if needed.
|
Creating a default one if needed.
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
""" Constants used by Home Assistant components. """
|
""" Constants used by Home Assistant components. """
|
||||||
|
|
||||||
|
__version__ = "0.7.0"
|
||||||
|
|
||||||
# Can be used to specify a catch all when registering state or event listeners.
|
# Can be used to specify a catch all when registering state or event listeners.
|
||||||
MATCH_ALL = '*'
|
MATCH_ALL = '*'
|
||||||
|
|
||||||
|
@ -21,9 +21,12 @@ from homeassistant.const import (
|
|||||||
EVENT_CALL_SERVICE, ATTR_NOW, ATTR_DOMAIN, ATTR_SERVICE, MATCH_ALL,
|
EVENT_CALL_SERVICE, ATTR_NOW, ATTR_DOMAIN, ATTR_SERVICE, MATCH_ALL,
|
||||||
EVENT_SERVICE_EXECUTED, ATTR_SERVICE_CALL_ID, EVENT_SERVICE_REGISTERED,
|
EVENT_SERVICE_EXECUTED, ATTR_SERVICE_CALL_ID, EVENT_SERVICE_REGISTERED,
|
||||||
TEMP_CELCIUS, TEMP_FAHRENHEIT, ATTR_FRIENDLY_NAME)
|
TEMP_CELCIUS, TEMP_FAHRENHEIT, ATTR_FRIENDLY_NAME)
|
||||||
|
from homeassistant.exceptions import (
|
||||||
|
HomeAssistantError, InvalidEntityFormatError)
|
||||||
import homeassistant.util as util
|
import homeassistant.util as util
|
||||||
import homeassistant.util.dt as date_util
|
import homeassistant.util.dt as date_util
|
||||||
import homeassistant.helpers.temperature as temp_helper
|
import homeassistant.helpers.temperature as temp_helper
|
||||||
|
from homeassistant.config import get_default_config_dir
|
||||||
|
|
||||||
DOMAIN = "homeassistant"
|
DOMAIN = "homeassistant"
|
||||||
|
|
||||||
@ -660,7 +663,7 @@ class Config(object):
|
|||||||
self.api = None
|
self.api = None
|
||||||
|
|
||||||
# Directory that holds the configuration
|
# Directory that holds the configuration
|
||||||
self.config_dir = os.path.join(os.getcwd(), 'config')
|
self.config_dir = get_default_config_dir()
|
||||||
|
|
||||||
def path(self, *path):
|
def path(self, *path):
|
||||||
""" Returns path to the file within the config dir. """
|
""" Returns path to the file within the config dir. """
|
||||||
@ -695,21 +698,6 @@ class Config(object):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class HomeAssistantError(Exception):
|
|
||||||
""" General Home Assistant exception occured. """
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class InvalidEntityFormatError(HomeAssistantError):
|
|
||||||
""" When an invalid formatted entity is encountered. """
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class NoEntitySpecifiedError(HomeAssistantError):
|
|
||||||
""" When no entity is specified. """
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def create_timer(hass, interval=TIMER_INTERVAL):
|
def create_timer(hass, interval=TIMER_INTERVAL):
|
||||||
""" Creates a timer. Timer will start on HOMEASSISTANT_START. """
|
""" Creates a timer. Timer will start on HOMEASSISTANT_START. """
|
||||||
# We want to be able to fire every time a minute starts (seconds=0).
|
# We want to be able to fire every time a minute starts (seconds=0).
|
||||||
|
16
homeassistant/exceptions.py
Normal file
16
homeassistant/exceptions.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
""" Exceptions used by Home Assistant """
|
||||||
|
|
||||||
|
|
||||||
|
class HomeAssistantError(Exception):
|
||||||
|
""" General Home Assistant exception occured. """
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class InvalidEntityFormatError(HomeAssistantError):
|
||||||
|
""" When an invalid formatted entity is encountered. """
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class NoEntitySpecifiedError(HomeAssistantError):
|
||||||
|
""" When no entity is specified. """
|
||||||
|
pass
|
@ -7,7 +7,7 @@ Provides ABC for entities in HA.
|
|||||||
|
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
from homeassistant.core import NoEntitySpecifiedError
|
from homeassistant.exceptions import NoEntitySpecifiedError
|
||||||
|
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_FRIENDLY_NAME, ATTR_UNIT_OF_MEASUREMENT, ATTR_HIDDEN,
|
ATTR_FRIENDLY_NAME, ATTR_UNIT_OF_MEASUREMENT, ATTR_HIDDEN,
|
||||||
|
@ -18,6 +18,7 @@ import urllib.parse
|
|||||||
import requests
|
import requests
|
||||||
|
|
||||||
import homeassistant.core as ha
|
import homeassistant.core as ha
|
||||||
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
import homeassistant.bootstrap as bootstrap
|
import homeassistant.bootstrap as bootstrap
|
||||||
|
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
@ -84,12 +85,12 @@ class API(object):
|
|||||||
|
|
||||||
except requests.exceptions.ConnectionError:
|
except requests.exceptions.ConnectionError:
|
||||||
_LOGGER.exception("Error connecting to server")
|
_LOGGER.exception("Error connecting to server")
|
||||||
raise ha.HomeAssistantError("Error connecting to server")
|
raise HomeAssistantError("Error connecting to server")
|
||||||
|
|
||||||
except requests.exceptions.Timeout:
|
except requests.exceptions.Timeout:
|
||||||
error = "Timeout when talking to {}".format(self.host)
|
error = "Timeout when talking to {}".format(self.host)
|
||||||
_LOGGER.exception(error)
|
_LOGGER.exception(error)
|
||||||
raise ha.HomeAssistantError(error)
|
raise HomeAssistantError(error)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "API({}, {}, {})".format(
|
return "API({}, {}, {})".format(
|
||||||
@ -102,7 +103,7 @@ class HomeAssistant(ha.HomeAssistant):
|
|||||||
|
|
||||||
def __init__(self, remote_api, local_api=None):
|
def __init__(self, remote_api, local_api=None):
|
||||||
if not remote_api.validate_api():
|
if not remote_api.validate_api():
|
||||||
raise ha.HomeAssistantError(
|
raise HomeAssistantError(
|
||||||
"Remote API at {}:{} not valid: {}".format(
|
"Remote API at {}:{} not valid: {}".format(
|
||||||
remote_api.host, remote_api.port, remote_api.status))
|
remote_api.host, remote_api.port, remote_api.status))
|
||||||
|
|
||||||
@ -121,7 +122,7 @@ class HomeAssistant(ha.HomeAssistant):
|
|||||||
# Ensure a local API exists to connect with remote
|
# Ensure a local API exists to connect with remote
|
||||||
if self.config.api is None:
|
if self.config.api is None:
|
||||||
if not bootstrap.setup_component(self, 'api'):
|
if not bootstrap.setup_component(self, 'api'):
|
||||||
raise ha.HomeAssistantError(
|
raise HomeAssistantError(
|
||||||
'Unable to setup local API to receive events')
|
'Unable to setup local API to receive events')
|
||||||
|
|
||||||
ha.create_timer(self)
|
ha.create_timer(self)
|
||||||
@ -132,7 +133,7 @@ class HomeAssistant(ha.HomeAssistant):
|
|||||||
# Setup that events from remote_api get forwarded to local_api
|
# Setup that events from remote_api get forwarded to local_api
|
||||||
# Do this after we fire START, otherwise HTTP is not started
|
# Do this after we fire START, otherwise HTTP is not started
|
||||||
if not connect_remote_events(self.remote_api, self.config.api):
|
if not connect_remote_events(self.remote_api, self.config.api):
|
||||||
raise ha.HomeAssistantError((
|
raise HomeAssistantError((
|
||||||
'Could not setup event forwarding from api {} to '
|
'Could not setup event forwarding from api {} to '
|
||||||
'local api {}').format(self.remote_api, self.config.api))
|
'local api {}').format(self.remote_api, self.config.api))
|
||||||
|
|
||||||
@ -293,7 +294,7 @@ def validate_api(api):
|
|||||||
else:
|
else:
|
||||||
return APIStatus.UNKNOWN
|
return APIStatus.UNKNOWN
|
||||||
|
|
||||||
except ha.HomeAssistantError:
|
except HomeAssistantError:
|
||||||
return APIStatus.CANNOT_CONNECT
|
return APIStatus.CANNOT_CONNECT
|
||||||
|
|
||||||
|
|
||||||
@ -318,7 +319,7 @@ def connect_remote_events(from_api, to_api):
|
|||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
except ha.HomeAssistantError:
|
except HomeAssistantError:
|
||||||
_LOGGER.exception("Error setting up event forwarding")
|
_LOGGER.exception("Error setting up event forwarding")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -342,7 +343,7 @@ def disconnect_remote_events(from_api, to_api):
|
|||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
except ha.HomeAssistantError:
|
except HomeAssistantError:
|
||||||
_LOGGER.exception("Error removing an event forwarder")
|
_LOGGER.exception("Error removing an event forwarder")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -354,7 +355,7 @@ def get_event_listeners(api):
|
|||||||
|
|
||||||
return req.json() if req.status_code == 200 else {}
|
return req.json() if req.status_code == 200 else {}
|
||||||
|
|
||||||
except (ha.HomeAssistantError, ValueError):
|
except (HomeAssistantError, ValueError):
|
||||||
# ValueError if req.json() can't parse the json
|
# ValueError if req.json() can't parse the json
|
||||||
_LOGGER.exception("Unexpected result retrieving event listeners")
|
_LOGGER.exception("Unexpected result retrieving event listeners")
|
||||||
|
|
||||||
@ -371,7 +372,7 @@ def fire_event(api, event_type, data=None):
|
|||||||
_LOGGER.error("Error firing event: %d - %d",
|
_LOGGER.error("Error firing event: %d - %d",
|
||||||
req.status_code, req.text)
|
req.status_code, req.text)
|
||||||
|
|
||||||
except ha.HomeAssistantError:
|
except HomeAssistantError:
|
||||||
_LOGGER.exception("Error firing event")
|
_LOGGER.exception("Error firing event")
|
||||||
|
|
||||||
|
|
||||||
@ -387,7 +388,7 @@ def get_state(api, entity_id):
|
|||||||
return ha.State.from_dict(req.json()) \
|
return ha.State.from_dict(req.json()) \
|
||||||
if req.status_code == 200 else None
|
if req.status_code == 200 else None
|
||||||
|
|
||||||
except (ha.HomeAssistantError, ValueError):
|
except (HomeAssistantError, ValueError):
|
||||||
# ValueError if req.json() can't parse the json
|
# ValueError if req.json() can't parse the json
|
||||||
_LOGGER.exception("Error fetching state")
|
_LOGGER.exception("Error fetching state")
|
||||||
|
|
||||||
@ -404,7 +405,7 @@ def get_states(api):
|
|||||||
return [ha.State.from_dict(item) for
|
return [ha.State.from_dict(item) for
|
||||||
item in req.json()]
|
item in req.json()]
|
||||||
|
|
||||||
except (ha.HomeAssistantError, ValueError, AttributeError):
|
except (HomeAssistantError, ValueError, AttributeError):
|
||||||
# ValueError if req.json() can't parse the json
|
# ValueError if req.json() can't parse the json
|
||||||
_LOGGER.exception("Error fetching states")
|
_LOGGER.exception("Error fetching states")
|
||||||
|
|
||||||
@ -434,7 +435,7 @@ def set_state(api, entity_id, new_state, attributes=None):
|
|||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
except ha.HomeAssistantError:
|
except HomeAssistantError:
|
||||||
_LOGGER.exception("Error setting state")
|
_LOGGER.exception("Error setting state")
|
||||||
|
|
||||||
return False
|
return False
|
||||||
@ -457,7 +458,7 @@ def get_services(api):
|
|||||||
|
|
||||||
return req.json() if req.status_code == 200 else {}
|
return req.json() if req.status_code == 200 else {}
|
||||||
|
|
||||||
except (ha.HomeAssistantError, ValueError):
|
except (HomeAssistantError, ValueError):
|
||||||
# ValueError if req.json() can't parse the json
|
# ValueError if req.json() can't parse the json
|
||||||
_LOGGER.exception("Got unexpected services result")
|
_LOGGER.exception("Got unexpected services result")
|
||||||
|
|
||||||
@ -475,5 +476,5 @@ def call_service(api, domain, service, service_data=None):
|
|||||||
_LOGGER.error("Error calling service: %d - %s",
|
_LOGGER.error("Error calling service: %d - %s",
|
||||||
req.status_code, req.text)
|
req.status_code, req.text)
|
||||||
|
|
||||||
except ha.HomeAssistantError:
|
except HomeAssistantError:
|
||||||
_LOGGER.exception("Error calling service")
|
_LOGGER.exception("Error calling service")
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
"""Helpers to install PyPi packages."""
|
"""Helpers to install PyPi packages."""
|
||||||
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
@ -8,15 +9,15 @@ from . import environment as env
|
|||||||
INSTALL_USER = not env.is_virtual()
|
INSTALL_USER = not env.is_virtual()
|
||||||
|
|
||||||
|
|
||||||
def install_package(package, upgrade=False, user=INSTALL_USER):
|
def install_package(package, upgrade=False, target=None):
|
||||||
"""Install a package on PyPi. Accepts pip compatible package strings.
|
"""Install a package on PyPi. Accepts pip compatible package strings.
|
||||||
Return boolean if install successfull."""
|
Return boolean if install successfull."""
|
||||||
# Not using 'import pip; pip.main([])' because it breaks the logger
|
# Not using 'import pip; pip.main([])' because it breaks the logger
|
||||||
args = [sys.executable, '-m', 'pip', 'install', '--quiet', package]
|
args = [sys.executable, '-m', 'pip', 'install', '--quiet', package]
|
||||||
if upgrade:
|
if upgrade:
|
||||||
args.append('--upgrade')
|
args.append('--upgrade')
|
||||||
if user:
|
if target:
|
||||||
args.append('--user')
|
args += ['--target', os.path.abspath(target)]
|
||||||
try:
|
try:
|
||||||
return 0 == subprocess.call(args)
|
return 0 == subprocess.call(args)
|
||||||
except subprocess.SubprocessError:
|
except subprocess.SubprocessError:
|
||||||
|
2
pylintrc
2
pylintrc
@ -1,5 +1,5 @@
|
|||||||
[MASTER]
|
[MASTER]
|
||||||
ignore=external
|
ignore=external,setup.py
|
||||||
reports=no
|
reports=no
|
||||||
|
|
||||||
# Reasons disabled:
|
# Reasons disabled:
|
||||||
|
123
requirements.txt
123
requirements.txt
@ -1,119 +1,4 @@
|
|||||||
# Required for Home Assistant core
|
requests>=2,<3
|
||||||
requests>=2.0
|
pyyaml>=3.11,<4
|
||||||
pyyaml>=3.11
|
pytz>=2015.4
|
||||||
pytz>=2015.2
|
pip>=7.0.0
|
||||||
|
|
||||||
# Optional, needed for specific components
|
|
||||||
|
|
||||||
# Sun (sun)
|
|
||||||
astral>=0.8.1
|
|
||||||
|
|
||||||
# Philips Hue library (lights.hue)
|
|
||||||
phue>=0.8
|
|
||||||
|
|
||||||
# Limitlessled/Easybulb/Milight library (lights.limitlessled)
|
|
||||||
ledcontroller>=1.0.7
|
|
||||||
|
|
||||||
# Chromecast bindings (media_player.cast)
|
|
||||||
pychromecast>=0.6.10
|
|
||||||
|
|
||||||
# Keyboard (keyboard)
|
|
||||||
pyuserinput>=0.1.9
|
|
||||||
|
|
||||||
# Tellstick bindings (*.tellstick)
|
|
||||||
tellcore-py>=1.0.4
|
|
||||||
|
|
||||||
# Nmap bindings (device_tracker.nmap)
|
|
||||||
python-libnmap>=0.6.3
|
|
||||||
|
|
||||||
# PushBullet bindings (notify.pushbullet)
|
|
||||||
pushbullet.py>=0.7.1
|
|
||||||
|
|
||||||
# Nest Thermostat bindings (thermostat.nest)
|
|
||||||
python-nest>=2.4.0
|
|
||||||
|
|
||||||
# Z-Wave (*.zwave)
|
|
||||||
pydispatcher>=2.0.5
|
|
||||||
|
|
||||||
# ISY994 bindings (*.isy994)
|
|
||||||
PyISY>=1.0.5
|
|
||||||
|
|
||||||
# PSutil (sensor.systemmonitor)
|
|
||||||
psutil>=3.0.0
|
|
||||||
|
|
||||||
# Pushover bindings (notify.pushover)
|
|
||||||
python-pushover>=0.2
|
|
||||||
|
|
||||||
# Transmission Torrent Client (*.transmission)
|
|
||||||
transmissionrpc>=0.11
|
|
||||||
|
|
||||||
# OpenWeatherMap Web API (sensor.openweathermap)
|
|
||||||
pyowm>=2.2.1
|
|
||||||
|
|
||||||
# XMPP Bindings (notify.xmpp)
|
|
||||||
sleekxmpp>=1.3.1
|
|
||||||
dnspython3>=1.12.0
|
|
||||||
|
|
||||||
# Blockchain (sensor.bitcoin)
|
|
||||||
blockchain>=1.1.2
|
|
||||||
|
|
||||||
# MPD Bindings (media_player.mpd)
|
|
||||||
python-mpd2>=0.5.4
|
|
||||||
|
|
||||||
# Hikvision (switch.hikvisioncam)
|
|
||||||
hikvision>=0.4
|
|
||||||
|
|
||||||
# console log coloring
|
|
||||||
colorlog>=2.6.0
|
|
||||||
|
|
||||||
# JSON-RPC interface (media_player.kodi)
|
|
||||||
jsonrpc-requests>=0.1
|
|
||||||
|
|
||||||
# Forecast.io Bindings (sensor.forecast)
|
|
||||||
python-forecastio>=1.3.3
|
|
||||||
|
|
||||||
# Firmata Bindings (*.arduino)
|
|
||||||
PyMata==2.07a
|
|
||||||
|
|
||||||
# Rfxtrx sensor (sensor.rfxtrx)
|
|
||||||
https://github.com/Danielhiversen/pyRFXtrx/archive/master.zip
|
|
||||||
|
|
||||||
# Mysensors
|
|
||||||
https://github.com/theolind/pymysensors/archive/master.zip#egg=pymysensors-0.1
|
|
||||||
|
|
||||||
# Netgear (device_tracker.netgear)
|
|
||||||
pynetgear>=0.3
|
|
||||||
|
|
||||||
# Netdisco (discovery)
|
|
||||||
netdisco>=0.3
|
|
||||||
|
|
||||||
# Wemo (switch.wemo)
|
|
||||||
pywemo>=0.2
|
|
||||||
|
|
||||||
# Wink (*.wink)
|
|
||||||
https://github.com/balloob/python-wink/archive/master.zip#pywink>=0.1
|
|
||||||
|
|
||||||
# Slack notifier (notify.slack)
|
|
||||||
slacker>=0.6.8
|
|
||||||
|
|
||||||
# Temper sensors (sensor.temper)
|
|
||||||
https://github.com/rkabadi/temper-python/archive/master.zip
|
|
||||||
|
|
||||||
# PyEdimax
|
|
||||||
https://github.com/rkabadi/pyedimax/archive/master.zip
|
|
||||||
|
|
||||||
# RPI-GPIO platform (*.rpi_gpio)
|
|
||||||
RPi.GPIO >=0.5.11
|
|
||||||
|
|
||||||
# Adafruit temperature/humidity sensor
|
|
||||||
# uncomment on a Raspberry Pi / Beaglebone
|
|
||||||
#git+git://github.com/mala-zaba/Adafruit_Python_DHT
|
|
||||||
|
|
||||||
# PAHO MQTT Binding (mqtt)
|
|
||||||
paho-mqtt>=1.1
|
|
||||||
|
|
||||||
# PyModbus (modbus)
|
|
||||||
https://github.com/bashwork/pymodbus/archive/python3.zip#pymodbus>=1.2.0
|
|
||||||
|
|
||||||
# Verisure (verisure)
|
|
||||||
https://github.com/persandstrom/python-verisure/archive/master.zip
|
|
||||||
|
121
requirements_all.txt
Normal file
121
requirements_all.txt
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
# Required for Home Assistant core
|
||||||
|
requests>=2,<3
|
||||||
|
pyyaml>=3.11,<4
|
||||||
|
pytz>=2015.4
|
||||||
|
pip>=7.0.0
|
||||||
|
|
||||||
|
# Optional, needed for specific components
|
||||||
|
|
||||||
|
# Sun (sun)
|
||||||
|
astral==0.8.1
|
||||||
|
|
||||||
|
# Philips Hue library (lights.hue)
|
||||||
|
phue==0.8
|
||||||
|
|
||||||
|
# Limitlessled/Easybulb/Milight library (lights.limitlessled)
|
||||||
|
ledcontroller==1.0.7
|
||||||
|
|
||||||
|
# Chromecast bindings (media_player.cast)
|
||||||
|
pychromecast==0.6.10
|
||||||
|
|
||||||
|
# Keyboard (keyboard)
|
||||||
|
pyuserinput==0.1.9
|
||||||
|
|
||||||
|
# Tellstick bindings (*.tellstick)
|
||||||
|
tellcore-py==1.0.4
|
||||||
|
|
||||||
|
# Nmap bindings (device_tracker.nmap)
|
||||||
|
python-libnmap==0.6.3
|
||||||
|
|
||||||
|
# PushBullet bindings (notify.pushbullet)
|
||||||
|
pushbullet.py==0.7.1
|
||||||
|
|
||||||
|
# Nest Thermostat bindings (thermostat.nest)
|
||||||
|
python-nest==2.4.0
|
||||||
|
|
||||||
|
# Z-Wave (*.zwave)
|
||||||
|
pydispatcher==2.0.5
|
||||||
|
|
||||||
|
# ISY994 bindings (*.isy994)
|
||||||
|
PyISY==1.0.5
|
||||||
|
|
||||||
|
# PSutil (sensor.systemmonitor)
|
||||||
|
psutil==3.0.0
|
||||||
|
|
||||||
|
# Pushover bindings (notify.pushover)
|
||||||
|
python-pushover==0.2
|
||||||
|
|
||||||
|
# Transmission Torrent Client (*.transmission)
|
||||||
|
transmissionrpc==0.11
|
||||||
|
|
||||||
|
# OpenWeatherMap Web API (sensor.openweathermap)
|
||||||
|
pyowm==2.2.1
|
||||||
|
|
||||||
|
# XMPP Bindings (notify.xmpp)
|
||||||
|
sleekxmpp==1.3.1
|
||||||
|
dnspython3==1.12.0
|
||||||
|
|
||||||
|
# Blockchain (sensor.bitcoin)
|
||||||
|
blockchain==1.1.2
|
||||||
|
|
||||||
|
# MPD Bindings (media_player.mpd)
|
||||||
|
python-mpd2==0.5.4
|
||||||
|
|
||||||
|
# Hikvision (switch.hikvisioncam)
|
||||||
|
hikvision==0.4
|
||||||
|
|
||||||
|
# console log coloring
|
||||||
|
colorlog==2.6.0
|
||||||
|
|
||||||
|
# JSON-RPC interface (media_player.kodi)
|
||||||
|
jsonrpc-requests==0.1
|
||||||
|
|
||||||
|
# Forecast.io Bindings (sensor.forecast)
|
||||||
|
python-forecastio==1.3.3
|
||||||
|
|
||||||
|
# Firmata Bindings (*.arduino)
|
||||||
|
PyMata==2.07a
|
||||||
|
|
||||||
|
# Rfxtrx sensor (sensor.rfxtrx)
|
||||||
|
https://github.com/Danielhiversen/pyRFXtrx/archive/ec7a1aaddf8270db6e5da1c13d58c1547effd7cf.zip
|
||||||
|
|
||||||
|
# Mysensors
|
||||||
|
https://github.com/theolind/pymysensors/archive/35b87d880147a34107da0d40cb815d75e6cb4af7.zip
|
||||||
|
|
||||||
|
# Netgear (device_tracker.netgear)
|
||||||
|
pynetgear==0.3
|
||||||
|
|
||||||
|
# Netdisco (discovery)
|
||||||
|
netdisco==0.3
|
||||||
|
|
||||||
|
# Wemo (switch.wemo)
|
||||||
|
pywemo==0.2
|
||||||
|
|
||||||
|
# Wink (*.wink)
|
||||||
|
https://github.com/balloob/python-wink/archive/c2b700e8ca866159566ecf5e644d9c297f69f257.zip
|
||||||
|
|
||||||
|
# Slack notifier (notify.slack)
|
||||||
|
slacker==0.6.8
|
||||||
|
|
||||||
|
# Temper sensors (sensor.temper)
|
||||||
|
https://github.com/rkabadi/temper-python/archive/3dbdaf2d87b8db9a3cd6e5585fc704537dd2d09b.zip
|
||||||
|
|
||||||
|
# PyEdimax
|
||||||
|
https://github.com/rkabadi/pyedimax/archive/365301ce3ff26129a7910c501ead09ea625f3700.zip
|
||||||
|
|
||||||
|
# RPI-GPIO platform (*.rpi_gpio)
|
||||||
|
# Uncomment for Raspberry Pi
|
||||||
|
# RPi.GPIO ==0.5.11
|
||||||
|
|
||||||
|
# Adafruit temperature/humidity sensor
|
||||||
|
# uncomment on a Raspberry Pi / Beaglebone
|
||||||
|
# http://github.com/mala-zaba/Adafruit_Python_DHT/archive/4101340de8d2457dd194bca1e8d11cbfc237e919.zip
|
||||||
|
|
||||||
|
# PAHO MQTT Binding (mqtt)
|
||||||
|
paho-mqtt==1.1
|
||||||
|
|
||||||
|
# PyModbus (modbus)
|
||||||
|
https://github.com/bashwork/pymodbus/archive/d7fc4f1cc975631e0a9011390e8017f64b612661.zip
|
||||||
|
|
||||||
|
# Verisure (verisure)
|
||||||
|
https://github.com/persandstrom/python-verisure/archive/9873c4527f01b1ba1f72ae60f7f35854390d59be.zip
|
53
setup.py
Executable file
53
setup.py
Executable file
@ -0,0 +1,53 @@
|
|||||||
|
import os
|
||||||
|
import re
|
||||||
|
from setuptools import setup, find_packages
|
||||||
|
|
||||||
|
PACKAGE_NAME = 'homeassistant'
|
||||||
|
HERE = os.path.abspath(os.path.dirname(__file__))
|
||||||
|
with open(os.path.join(HERE, PACKAGE_NAME, 'const.py')) as fp:
|
||||||
|
VERSION = re.search("__version__ = ['\"]([^']+)['\"]\n", fp.read()).group(1)
|
||||||
|
DOWNLOAD_URL = \
|
||||||
|
'https://github.com/balloob/home-assistant/tarball/{}'.format(VERSION)
|
||||||
|
|
||||||
|
PACKAGES = find_packages() + \
|
||||||
|
['homeassistant.external', 'homeassistant.external.noop',
|
||||||
|
'homeassistant.external.nzbclients', 'homeassistant.external.vera']
|
||||||
|
|
||||||
|
PACKAGE_DATA = \
|
||||||
|
{'homeassistant.components.frontend': ['index.html.template'],
|
||||||
|
'homeassistant.components.frontend.www_static': ['*.*'],
|
||||||
|
'homeassistant.components.frontend.www_static.images': ['*.*']}
|
||||||
|
|
||||||
|
REQUIRES = \
|
||||||
|
[line.strip() for line in open('requirements.txt', 'r')]
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name=PACKAGE_NAME,
|
||||||
|
version=VERSION,
|
||||||
|
license='MIT License',
|
||||||
|
url='https://home-assistant.io/',
|
||||||
|
download_url=DOWNLOAD_URL,
|
||||||
|
author='Paulus Schoutsen',
|
||||||
|
author_email='paulus@paulusschoutsen.nl',
|
||||||
|
description='Open-source home automation platform running on Python 3.',
|
||||||
|
packages=PACKAGES,
|
||||||
|
include_package_data=True,
|
||||||
|
package_data=PACKAGE_DATA,
|
||||||
|
zip_safe=False,
|
||||||
|
platforms='any',
|
||||||
|
install_requires=REQUIRES,
|
||||||
|
keywords=['home', 'automation'],
|
||||||
|
entry_points={
|
||||||
|
'console_scripts': [
|
||||||
|
'hass = homeassistant.__main__:main'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
classifiers=[
|
||||||
|
'Intended Audience :: End Users/Desktop',
|
||||||
|
'Intended Audience :: Developers',
|
||||||
|
'License :: OSI Approved :: MIT License',
|
||||||
|
'Operating System :: OS Independent',
|
||||||
|
'Programming Language :: Python :: 3.4',
|
||||||
|
'Topic :: Home Automation'
|
||||||
|
]
|
||||||
|
)
|
@ -16,6 +16,8 @@ from datetime import datetime
|
|||||||
import pytz
|
import pytz
|
||||||
|
|
||||||
import homeassistant.core as ha
|
import homeassistant.core as ha
|
||||||
|
from homeassistant.exceptions import (
|
||||||
|
HomeAssistantError, InvalidEntityFormatError)
|
||||||
import homeassistant.util.dt as dt_util
|
import homeassistant.util.dt as dt_util
|
||||||
from homeassistant.helpers.event import track_state_change
|
from homeassistant.helpers.event import track_state_change
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
@ -41,7 +43,7 @@ class TestHomeAssistant(unittest.TestCase):
|
|||||||
""" Stop down stuff we started. """
|
""" Stop down stuff we started. """
|
||||||
try:
|
try:
|
||||||
self.hass.stop()
|
self.hass.stop()
|
||||||
except ha.HomeAssistantError:
|
except HomeAssistantError:
|
||||||
# Already stopped after the block till stopped test
|
# Already stopped after the block till stopped test
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -250,7 +252,7 @@ class TestState(unittest.TestCase):
|
|||||||
def test_init(self):
|
def test_init(self):
|
||||||
""" Test state.init """
|
""" Test state.init """
|
||||||
self.assertRaises(
|
self.assertRaises(
|
||||||
ha.InvalidEntityFormatError, ha.State,
|
InvalidEntityFormatError, ha.State,
|
||||||
'invalid_entity_format', 'test_state')
|
'invalid_entity_format', 'test_state')
|
||||||
|
|
||||||
def test_domain(self):
|
def test_domain(self):
|
||||||
@ -489,18 +491,24 @@ class TestConfig(unittest.TestCase):
|
|||||||
|
|
||||||
def test_config_dir_set_correct(self):
|
def test_config_dir_set_correct(self):
|
||||||
""" Test config dir set correct. """
|
""" Test config dir set correct. """
|
||||||
self.assertEqual(os.path.join(os.getcwd(), "config"),
|
data_dir = os.getenv('APPDATA') if os.name == "nt" \
|
||||||
|
else os.path.expanduser('~')
|
||||||
|
self.assertEqual(os.path.join(data_dir, ".homeassistant"),
|
||||||
self.config.config_dir)
|
self.config.config_dir)
|
||||||
|
|
||||||
def test_path_with_file(self):
|
def test_path_with_file(self):
|
||||||
""" Test get_config_path method. """
|
""" Test get_config_path method. """
|
||||||
self.assertEqual(os.path.join(os.getcwd(), "config", "test.conf"),
|
data_dir = os.getenv('APPDATA') if os.name == "nt" \
|
||||||
|
else os.path.expanduser('~')
|
||||||
|
self.assertEqual(os.path.join(data_dir, ".homeassistant", "test.conf"),
|
||||||
self.config.path("test.conf"))
|
self.config.path("test.conf"))
|
||||||
|
|
||||||
def test_path_with_dir_and_file(self):
|
def test_path_with_dir_and_file(self):
|
||||||
""" Test get_config_path method. """
|
""" Test get_config_path method. """
|
||||||
|
data_dir = os.getenv('APPDATA') if os.name == "nt" \
|
||||||
|
else os.path.expanduser('~')
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
os.path.join(os.getcwd(), "config", "dir", "test.conf"),
|
os.path.join(data_dir, ".homeassistant", "dir", "test.conf"),
|
||||||
self.config.path("dir", "test.conf"))
|
self.config.path("dir", "test.conf"))
|
||||||
|
|
||||||
def test_temperature_not_convert_if_no_preference(self):
|
def test_temperature_not_convert_if_no_preference(self):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user