Merge pull request #41 from theolind/feature_yaml_config

Support for YAML configuration
This commit is contained in:
Paulus Schoutsen 2015-02-28 15:03:38 -08:00
commit 3ebfc0e917
6 changed files with 138 additions and 116 deletions

View File

@ -0,0 +1,98 @@
homeassistant:
# Location required to calculate the time the sun rises and sets
latitude: '32.87336'
longitude: '-117.22743'
http:
api_password: mypass
# Set to 1 to load each Polymer component separately
# development: 1
#light:
# platform: hue
#wink:
# Get your token at https://winkbearertoken.appspot.com
# access_token: 'YOUR_TOKEN'
#device_tracker:
# The following types are available: netgear, tomato, luci, nmap_tracker
platform: netgear
host: 192.168.1.1
username: admin
password: PASSWORD
# http_id is needed for Tomato routers only
# http_id: ABCDEFGHH
# For nmap_tracker, only the IP addresses to scan are needed:
# hosts: 192.168.1.1/24 # netmask prefix notation or
# hosts: 192.168.1.1-255 # address range
#chromecast:
switch:
platform: wemo
#thermostat:
platform: nest
# Required: username and password that are used to login to the Nest thermostat.
username: myemail@mydomain.com
password: mypassword
downloader:
download_dir: downloads
notify:
platform: pushbullet
api_key: ABCDEFGHJKLMNOPQRSTUVXYZ
device_sun_light_trigger:
# Optional: specify a specific light/group of lights that has to be turned on
light_group: group.living_room
# Optional: specify which light profile to use when turning lights on
light_profile: relax
# Optional: disable lights being turned off when everybody leaves the house
# disable_turn_off: 1
# A comma seperated list of states that have to be tracked as a single group
# Grouped states should share the same type of states (ON/OFF or HOME/NOT_HOME)
group:
living_room: light.Bowl,light.Ceiling,light.TV_back_light
children: device_tracker.child_1,device_tracker.child_2
process:
# items are which processes to look for: <entity_id>: <search string within ps>
xbmc: XBMC.App
example:
simple_alarm:
# Which light/light group has to flash when a known device comes home
known_light: light.Bowl
# Which light/light group has to flash red when light turns on while no one home
unknown_light: group.living_room
browser:
keyboard:
automation:
platform: state
alias: Sun starts shining
state_entity_id: sun.sun
# Next two are optional, omit to match all
state_from: below_horizon
state_to: above_horizon
execute_service: light.turn_off
service_entity_id: group.living_room
automation 2:
platform: time
alias: Beer o Clock
time_hours: 16
time_minutes: 0
time_seconds: 0
execute_service: notify.notify
service_data: {"message":"It's 4, time for beer!"}

View File

@ -1,99 +0,0 @@
[homeassistant]
# Location required to calculate the time the sun rises and sets
latitude=32.87336
longitude=-117.22743
[http]
api_password=mypass
# Set to 1 to load each Polymer component separately
# development=1
[light]
platform=hue
[wink]
# Get your token at https://winkbearertoken.appspot.com
access_token=YOUR_TOKEN
[device_tracker]
# The following types are available: netgear, tomato, luci, nmap_tracker
platform=netgear
host=192.168.1.1
username=admin
password=PASSWORD
# http_id is needed for Tomato routers only
# http_id=ABCDEFGHH
# For nmap_tracker, only the IP addresses to scan are needed:
# hosts=192.168.1.1/24 # netmask prefix notation or
# hosts=192.168.1.1-255 # address range
[chromecast]
[switch]
platform=wemo
[thermostat]
platform=nest
# Required: username and password that are used to login to the Nest thermostat.
username=myemail@mydomain.com
password=mypassword
[downloader]
download_dir=downloads
[notify]
platform=pushbullet
api_key=ABCDEFGHJKLMNOPQRSTUVXYZ
[device_sun_light_trigger]
# Optional: specify a specific light/group of lights that has to be turned on
light_group=group.living_room
# Optional: specify which light profile to use when turning lights on
light_profile=relax
# Optional: disable lights being turned off when everybody leaves the house
# disable_turn_off=1
# A comma seperated list of states that have to be tracked as a single group
# Grouped states should share the same type of states (ON/OFF or HOME/NOT_HOME)
[group]
living_room=light.Bowl,light.Ceiling,light.TV_back_light
children=device_tracker.child_1,device_tracker.child_2
[process]
# items are which processes to look for: <entity_id>=<search string within ps>
xbmc=XBMC.App
[example]
[simple_alarm]
# Which light/light group has to flash when a known device comes home
known_light=light.Bowl
# Which light/light group has to flash red when light turns on while no one home
unknown_light=group.living_room
[browser]
[keyboard]
[automation]
platform=state
alias=Sun starts shining
state_entity_id=sun.sun
# Next two are optional, omit to match all
state_from=below_horizon
state_to=above_horizon
execute_service=light.turn_off
service_entity_id=group.living_room
[automation 2]
platform=time
alias=Beer o Clock
time_hours=16
time_minutes=0
time_seconds=0
execute_service=notify.notify
service_data={"message":"It's 4, time for beer!"}

View File

@ -72,15 +72,19 @@ def ensure_config_path(config_dir):
'directory {} ').format(config_dir))
sys.exit()
config_path = os.path.join(config_dir, 'home-assistant.conf')
# Try to use yaml configuration first
config_path = os.path.join(config_dir, 'configuration.yaml')
if not os.path.isfile(config_path):
config_path = os.path.join(config_dir, 'home-assistant.conf')
# Ensure a config file exists to make first time usage easier
if not os.path.isfile(config_path):
config_path = os.path.join(config_dir, 'configuration.yaml')
try:
with open(config_path, 'w') as conf:
conf.write("[frontend]\n\n")
conf.write("[discovery]\n\n")
conf.write("[history]\n\n")
conf.write("frontend:\n\n")
conf.write("discovery:\n\n")
conf.write("history:\n\n")
except IOError:
print(('Fatal Error: No configuration file found and unable '
'to write a default one to {}').format(config_path))

View File

@ -11,6 +11,8 @@ start by calling homeassistant.start_home_assistant(bus)
import os
import configparser
import yaml
import io
import logging
from collections import defaultdict
@ -77,7 +79,9 @@ def from_config_dict(config, hass=None):
# Make a copy because we are mutating it.
# Convert it to defaultdict so components can always have config dict
config = defaultdict(dict, config)
# Convert values to dictionaries if they are None
config = defaultdict(
dict, {key: value or {} for key, value in config.items()})
# Filter out the repeating and common config section [homeassistant]
components = (key for key in config.keys()
@ -110,17 +114,21 @@ def from_config_file(config_path, hass=None):
# Set config dir to directory holding config file
hass.config_dir = os.path.abspath(os.path.dirname(config_path))
# Read config
config = configparser.ConfigParser()
config.read(config_path)
config_dict = {}
# check config file type
if os.path.splitext(config_path)[1] == '.yaml':
# Read yaml
config_dict = yaml.load(io.open(config_path, 'r'))
else:
# Read config
config = configparser.ConfigParser()
config.read(config_path)
for section in config.sections():
config_dict[section] = {}
for section in config.sections():
config_dict[section] = {}
for key, val in config.items(section):
config_dict[section][key] = val
for key, val in config.items(section):
config_dict[section][key] = val
return from_config_dict(config_dict, hass)

View File

@ -36,6 +36,9 @@ TIME_DEVICE_NOT_FOUND = timedelta(minutes=3)
# Filename to save known devices to
KNOWN_DEVICES_FILE = "known_devices.csv"
CONF_SECONDS = "interval_seconds"
DEFAULT_CONF_SECONDS = 12
_LOGGER = logging.getLogger(__name__)
@ -81,7 +84,10 @@ def setup(hass, config):
return False
tracker = DeviceTracker(hass, device_scanner)
seconds = util.convert(config[DOMAIN].get(CONF_SECONDS), int,
DEFAULT_CONF_SECONDS)
tracker = DeviceTracker(hass, device_scanner, seconds)
# We only succeeded if we got to parse the known devices file
return not tracker.invalid_known_devices_file
@ -90,7 +96,7 @@ def setup(hass, config):
class DeviceTracker(object):
""" Class that tracks which devices are home and which are not. """
def __init__(self, hass, device_scanner):
def __init__(self, hass, device_scanner, seconds):
self.hass = hass
self.device_scanner = device_scanner
@ -126,8 +132,10 @@ class DeviceTracker(object):
if self.invalid_known_devices_file:
return
hass.track_time_change(
update_device_state, second=range(0, 60, 12))
seconds = range(0, 60, seconds)
_LOGGER.info("Device tracker interval second=%s", seconds)
hass.track_time_change(update_device_state, second=seconds)
hass.services.register(DOMAIN,
SERVICE_DEVICE_TRACKER_RELOAD,

View File

@ -29,3 +29,6 @@ pushbullet.py>=0.7.1
# thermostat.nest
python-nest>=2.1
# pyyaml
pyyaml