mirror of
https://github.com/home-assistant/core.git
synced 2025-07-21 20:27:08 +00:00
Merge remote-tracking branch 'balloob/dev' into dev
This commit is contained in:
commit
01daac066a
@ -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
|
||||
|
@ -9,11 +9,12 @@ After bootstrapping you can add your own components or
|
||||
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
|
||||
@ -25,7 +26,7 @@ import homeassistant.components as core_components
|
||||
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)
|
||||
|
||||
@ -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:
|
||||
@ -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
|
||||
|
@ -87,7 +87,10 @@ def setup(hass, config):
|
||||
|
||||
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)
|
||||
|
||||
@ -129,7 +132,8 @@ def setup(hass, config):
|
||||
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',
|
||||
|
@ -42,11 +42,19 @@ class GenericCamera(Camera):
|
||||
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
|
||||
|
||||
|
@ -1,2 +1,2 @@
|
||||
""" DO NOT MODIFY. Auto-generated by build_frontend script """
|
||||
VERSION = "75532015507fd544f46081ec0eeb5004"
|
||||
VERSION = "b75e3c9ebd3de2dae0912a89499127a9"
|
||||
|
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
Subproject commit 8e33f925e171fd279adf0338f5440c1d7160311d
|
||||
Subproject commit 99af263595dbbf057d26bb266101fa1e386442c6
|
File diff suppressed because one or more lines are too long
@ -10,8 +10,8 @@ from functools import partial
|
||||
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
|
||||
@ -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.")
|
||||
|
@ -37,6 +37,7 @@ CONF_EVENT_DATA = "event_data"
|
||||
CONF_DELAY = "delay"
|
||||
|
||||
ATTR_LAST_ACTION = 'last_action'
|
||||
ATTR_CAN_CANCEL = 'can_cancel'
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@ -113,6 +114,8 @@ class Script(ToggleEntity):
|
||||
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):
|
||||
@ -126,7 +129,9 @@ class Script(ToggleEntity):
|
||||
@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
|
||||
|
@ -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. """
|
||||
|
@ -16,7 +16,8 @@ from homeassistant.helpers.entity import ToggleEntity
|
||||
|
||||
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 = []
|
||||
@ -38,7 +39,8 @@ DISCOVERY_PLATFORMS = {
|
||||
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 = {
|
||||
|
75
homeassistant/components/switch/orvibo.py
Normal file
75
homeassistant/components/switch/orvibo.py
Normal file
@ -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
homeassistant/components/switch/zwave.py
Normal file
76
homeassistant/components/switch/zwave.py
Normal file
@ -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)
|
57
homeassistant/components/updater.py
Normal file
57
homeassistant/components/updater.py
Normal file
@ -0,0 +1,57 @@
|
||||
"""
|
||||
homeassistant.components.sensor.updater
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Sensor that checks for available updates.
|
||||
|
||||
For more details about this platform, please refer to the documentation at
|
||||
at https://home-assistant.io/components/sensor.updater/
|
||||
"""
|
||||
import logging
|
||||
|
||||
import requests
|
||||
|
||||
from homeassistant.const import __version__ as CURRENT_VERSION
|
||||
from homeassistant.const import ATTR_FRIENDLY_NAME
|
||||
from homeassistant.helpers import event
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
PYPI_URL = 'https://pypi.python.org/pypi/homeassistant/json'
|
||||
DEPENDENCIES = []
|
||||
DOMAIN = 'updater'
|
||||
ENTITY_ID = 'updater.updater'
|
||||
|
||||
|
||||
def setup(hass, config):
|
||||
''' setup the updater component '''
|
||||
|
||||
def check_newest_version(_=None):
|
||||
''' check if a new version is available and report if one is '''
|
||||
newest = get_newest_version()
|
||||
|
||||
if newest != CURRENT_VERSION and newest is not None:
|
||||
hass.states.set(
|
||||
ENTITY_ID, newest, {ATTR_FRIENDLY_NAME: 'Update Available'})
|
||||
|
||||
event.track_time_change(hass, check_newest_version,
|
||||
hour=[0, 12], minute=0, second=0)
|
||||
|
||||
check_newest_version()
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def get_newest_version():
|
||||
''' Get the newest HA version form PyPI '''
|
||||
try:
|
||||
req = requests.get(PYPI_URL)
|
||||
|
||||
return req.json()['info']['version']
|
||||
except requests.RequestException:
|
||||
_LOGGER.exception('Could not contact PyPI to check for updates')
|
||||
return
|
||||
except ValueError:
|
||||
_LOGGER.exception('Received invalid response from PyPI')
|
||||
return
|
||||
except KeyError:
|
||||
_LOGGER.exception('Response from PyPI did not include version')
|
||||
return
|
@ -20,13 +20,18 @@ REQUIREMENTS = ['pydispatcher==2.0.5']
|
||||
CONF_USB_STICK_PATH = "usb_path"
|
||||
DEFAULT_CONF_USB_STICK_PATH = "/zwaveusbstick"
|
||||
CONF_DEBUG = "debug"
|
||||
CONF_POLLING_INTERVAL = "polling_interval"
|
||||
|
||||
DISCOVER_SENSORS = "zwave.sensors"
|
||||
DISCOVER_SWITCHES = "zwave.switch"
|
||||
DISCOVER_LIGHTS = "zwave.light"
|
||||
|
||||
COMMAND_CLASS_SWITCH_MULTILEVEL = 38
|
||||
|
||||
COMMAND_CLASS_SWITCH_BINARY = 37
|
||||
COMMAND_CLASS_SENSOR_BINARY = 48
|
||||
COMMAND_CLASS_SENSOR_MULTILEVEL = 49
|
||||
COMMAND_CLASS_METER = 50
|
||||
COMMAND_CLASS_BATTERY = 128
|
||||
|
||||
GENRE_WHATEVER = None
|
||||
@ -35,20 +40,28 @@ GENRE_USER = "User"
|
||||
TYPE_WHATEVER = None
|
||||
TYPE_BYTE = "Byte"
|
||||
TYPE_BOOL = "Bool"
|
||||
TYPE_DECIMAL = "Decimal"
|
||||
|
||||
# list of tuple (DOMAIN, discovered service, supported command
|
||||
# classes, value type)
|
||||
DISCOVERY_COMPONENTS = [
|
||||
('sensor',
|
||||
DISCOVER_SENSORS,
|
||||
[COMMAND_CLASS_SENSOR_BINARY, COMMAND_CLASS_SENSOR_MULTILEVEL],
|
||||
[COMMAND_CLASS_SENSOR_BINARY,
|
||||
COMMAND_CLASS_SENSOR_MULTILEVEL,
|
||||
COMMAND_CLASS_METER],
|
||||
TYPE_WHATEVER,
|
||||
GENRE_WHATEVER),
|
||||
GENRE_USER),
|
||||
('light',
|
||||
DISCOVER_LIGHTS,
|
||||
[COMMAND_CLASS_SWITCH_MULTILEVEL],
|
||||
TYPE_BYTE,
|
||||
GENRE_USER),
|
||||
('switch',
|
||||
DISCOVER_SWITCHES,
|
||||
[COMMAND_CLASS_SWITCH_BINARY],
|
||||
TYPE_BOOL,
|
||||
GENRE_USER),
|
||||
]
|
||||
|
||||
ATTR_NODE_ID = "node_id"
|
||||
@ -165,6 +178,10 @@ def setup(hass, config):
|
||||
""" Called when Home Assistant starts up. """
|
||||
NETWORK.start()
|
||||
|
||||
polling_interval = config[DOMAIN].get(CONF_POLLING_INTERVAL, None)
|
||||
if polling_interval is not None:
|
||||
NETWORK.setPollInterval(polling_interval)
|
||||
|
||||
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_zwave)
|
||||
|
||||
hass.bus.listen_once(EVENT_HOMEASSISTANT_START, start_zwave)
|
||||
|
@ -29,6 +29,7 @@ def install_package(package, upgrade=True, target=None):
|
||||
try:
|
||||
return 0 == subprocess.call(args)
|
||||
except subprocess.SubprocessError:
|
||||
_LOGGER.exception('Unable to install pacakge %s', package)
|
||||
return False
|
||||
|
||||
|
||||
|
@ -156,3 +156,6 @@ evohomeclient==0.2.3
|
||||
|
||||
# Pushetta (notify.pushetta)
|
||||
pushetta==1.0.15
|
||||
|
||||
# Orvibo S10
|
||||
orvibo==1.0.0
|
||||
|
@ -88,6 +88,8 @@ class TestScript(unittest.TestCase):
|
||||
|
||||
self.assertEqual(1, len(calls))
|
||||
self.assertEqual('world', calls[0].data.get('hello'))
|
||||
self.assertEqual(
|
||||
True, self.hass.states.get(ENTITY_ID).attributes.get('can_cancel'))
|
||||
|
||||
def test_calling_service_old(self):
|
||||
calls = []
|
||||
@ -172,6 +174,9 @@ class TestScript(unittest.TestCase):
|
||||
self.hass.pool.block_till_done()
|
||||
|
||||
self.assertTrue(script.is_on(self.hass, ENTITY_ID))
|
||||
self.assertEqual(
|
||||
False,
|
||||
self.hass.states.get(ENTITY_ID).attributes.get('can_cancel'))
|
||||
|
||||
self.assertEqual(
|
||||
event,
|
||||
|
@ -5,11 +5,13 @@ tests.test_bootstrap
|
||||
Tests bootstrap.
|
||||
"""
|
||||
# pylint: disable=too-many-public-methods,protected-access
|
||||
import os
|
||||
import tempfile
|
||||
import unittest
|
||||
from unittest import mock
|
||||
|
||||
from homeassistant import bootstrap
|
||||
from homeassistant import core, bootstrap
|
||||
from homeassistant.const import __version__
|
||||
import homeassistant.util.dt as dt_util
|
||||
|
||||
from tests.common import mock_detect_location_info
|
||||
@ -39,3 +41,45 @@ class TestBootstrap(unittest.TestCase):
|
||||
|
||||
self.assertEqual(sorted(components),
|
||||
sorted(hass.config.components))
|
||||
|
||||
def test_remove_lib_on_upgrade(self):
|
||||
with tempfile.TemporaryDirectory() as config_dir:
|
||||
version_path = os.path.join(config_dir, '.HA_VERSION')
|
||||
lib_dir = os.path.join(config_dir, 'lib')
|
||||
check_file = os.path.join(lib_dir, 'check')
|
||||
|
||||
with open(version_path, 'wt') as outp:
|
||||
outp.write('0.7.0')
|
||||
|
||||
os.mkdir(lib_dir)
|
||||
|
||||
with open(check_file, 'w'):
|
||||
pass
|
||||
|
||||
hass = core.HomeAssistant()
|
||||
hass.config.config_dir = config_dir
|
||||
|
||||
self.assertTrue(os.path.isfile(check_file))
|
||||
bootstrap.process_ha_config_upgrade(hass)
|
||||
self.assertFalse(os.path.isfile(check_file))
|
||||
|
||||
def test_not_remove_lib_if_not_upgrade(self):
|
||||
with tempfile.TemporaryDirectory() as config_dir:
|
||||
version_path = os.path.join(config_dir, '.HA_VERSION')
|
||||
lib_dir = os.path.join(config_dir, 'lib')
|
||||
check_file = os.path.join(lib_dir, 'check')
|
||||
|
||||
with open(version_path, 'wt') as outp:
|
||||
outp.write(__version__)
|
||||
|
||||
os.mkdir(lib_dir)
|
||||
|
||||
with open(check_file, 'w'):
|
||||
pass
|
||||
|
||||
hass = core.HomeAssistant()
|
||||
hass.config.config_dir = config_dir
|
||||
|
||||
bootstrap.process_ha_config_upgrade(hass)
|
||||
|
||||
self.assertTrue(os.path.isfile(check_file))
|
||||
|
Loading…
x
Reference in New Issue
Block a user