mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 13:17:32 +00:00
Added WeMo support
This commit is contained in:
parent
bb771d802d
commit
6063ffeb5b
25
README.md
25
README.md
@ -5,37 +5,37 @@ Home Assistant provides a platform for home automation. It does so by having mod
|
||||
|
||||
It is currently able to do the following things:
|
||||
* Track if devices are home by monitoring connected devices to a wireless router (currently supporting modern Netgear routers or routers running Tomato firmware)
|
||||
* Track which lights are on
|
||||
* Track what your Chromecasts are up to
|
||||
* Track and control lights
|
||||
* Track and control WeMo switches
|
||||
* Track and control Chromecasts
|
||||
* Turn on the lights when people get home when the sun is setting or has set
|
||||
* Slowly turn on the lights to compensate for light loss when the sun sets and people are home
|
||||
* Turn off lights and connected devices when everybody leaves the house
|
||||
* Start YouTube video’s on the Chromecast
|
||||
* Quit current running application on a Chromecast
|
||||
* Download files to the host machine
|
||||
* Open a url in the default browser at the host machine
|
||||
* Simulate key presses on the host for Play/Pause, Next track, Prev track, Volume up, Volume Down
|
||||
* Controllable via a REST API and web interface
|
||||
* Support for thin client Home Assistant instances that will forward all their commands to the main instance
|
||||
* Android Tasker project to control Home Assistant from your phone and report charging state. Combine it with AutoVoice to be able to tell your phones to turn the lights off!
|
||||
* Support for remoting Home Assistant instances through a Python API
|
||||
* Android Tasker project to control Home Assistant from your phone and report charging state.
|
||||
|
||||

|
||||
|
||||
Current compatible devices:
|
||||
* Wireless router running [Tomato firmware](http://www.polarcloud.com/tomato)
|
||||
* Netgear wireless routers (tested with R6300)
|
||||
* [WeMo switches](http://www.belkin.com/us/Products/home-automation/c/wemo-home-automation/)
|
||||
* [Philips Hue](http://meethue.com)
|
||||
* [Google Chromecast](http://www.google.com/intl/en/chrome/devices/chromecast)
|
||||
* Wireless router running [Tomato firmware](http://www.polarcloud.com/tomato)
|
||||
* Netgear wireless routers (tested with R6300)
|
||||
|
||||
The system is built modular so support for other wireless routers, other devices or actions can be implemented easily.
|
||||
The system is built modular so support for other devices or actions can be implemented easily.
|
||||
|
||||
Installation instructions
|
||||
-------------------------
|
||||
* Install python modules [PyEphem](http://rhodesmill.org/pyephem/), [Requests](http://python-requests.org) and [PHue](https://github.com/studioimaginaire/phue): `pip install pyephem requests phue`
|
||||
* The core depends on [PyEphem](http://rhodesmill.org/pyephem/) and [Requests](http://python-requests.org). Depending on the components you would like to use you will need [PHue](https://github.com/studioimaginaire/phue) for Philips Hue support, [PyChromecast](https://github.com/balloob/pychromecast) for Chromecast support and [ouimeaux](https://github.com/iancmcc/ouimeaux) for WeMo support. Install these using `pip install pyephem requests phue ouimeaux pychromecast`.
|
||||
* Clone the repository and pull in the submodules `git clone --recursive https://github.com/balloob/home-assistant.git`
|
||||
* Copy home-assistant.conf.default to home-assistant.conf and adjust the config values to match your setup.
|
||||
* For Tomato you will have to not only setup your host, username and password but also a http_id. The http_id can be retrieved by going to the admin console of your router, view the source of any of the pages and search for `http_id`.
|
||||
* Setup PHue by running `python -m phue --host HUE_BRIDGE_IP_ADDRESS` from the commandline.
|
||||
* If you want to use Hue, setup PHue by running `python -m phue --host HUE_BRIDGE_IP_ADDRESS` from the commandline and follow the instructions.
|
||||
* While running the script it will create and maintain a file called `known_devices.csv` which will contain the detected devices. Adjust the track variable for the devices you want the script to act on and restart the script or call the service `device_tracker/reload_devices_csv`.
|
||||
|
||||
Done. Start it now by running `python start.py`
|
||||
@ -205,6 +205,9 @@ Action: sets the state per device and maintains a combined state called `all_dev
|
||||
**Light**
|
||||
Keeps track which lights are turned on and can control the lights.
|
||||
|
||||
**WeMo**
|
||||
Keeps track which WeMo switches are in the network and allows you to control them.
|
||||
|
||||
**device_sun_light_trigger**
|
||||
Turns lights on or off using a light control component based on state of the sun and devices that are home.
|
||||
Depends on: light control, track_sun, DeviceTracker
|
||||
|
@ -128,6 +128,12 @@ def from_config_file(config_path):
|
||||
else:
|
||||
chromecast_started = False
|
||||
|
||||
# WeMo
|
||||
if has_section("wemo"):
|
||||
wemo = load_module('wemo')
|
||||
|
||||
add_status("WeMo", wemo.setup(bus, statemachine))
|
||||
|
||||
# Light control
|
||||
if has_section("light.hue"):
|
||||
light = load_module('light')
|
||||
|
@ -21,6 +21,7 @@ import homeassistant as ha
|
||||
import homeassistant.util as util
|
||||
|
||||
ATTR_ENTITY_ID = 'entity_id'
|
||||
ATTR_FRIENDLY_NAME = "friendly_name"
|
||||
|
||||
STATE_ON = 'on'
|
||||
STATE_OFF = 'off'
|
||||
|
143
homeassistant/components/wemo.py
Normal file
143
homeassistant/components/wemo.py
Normal file
@ -0,0 +1,143 @@
|
||||
"""
|
||||
Component to interface with WeMo devices on the network.
|
||||
"""
|
||||
import logging
|
||||
import socket
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
import homeassistant as ha
|
||||
import homeassistant.util as util
|
||||
from homeassistant.components import (group, STATE_ON, STATE_OFF,
|
||||
SERVICE_TURN_ON, SERVICE_TURN_OFF,
|
||||
ATTR_ENTITY_ID, ATTR_FRIENDLY_NAME)
|
||||
DOMAIN = 'wemo'
|
||||
|
||||
GROUP_NAME_ALL_WEMOS = 'all_wemos'
|
||||
ENTITY_ID_ALL_WEMOS = group.ENTITY_ID_FORMAT.format(
|
||||
GROUP_NAME_ALL_WEMOS)
|
||||
|
||||
ENTITY_ID_FORMAT = DOMAIN + '.{}'
|
||||
|
||||
ATTR_TODAY_KWH = "today_kwh"
|
||||
ATTR_CURRENT_POWER = "current_power"
|
||||
ATTR_TODAY_ON_TIME = "today_on_time"
|
||||
ATTR_TODAY_STANDBY_TIME = "today_standby_time"
|
||||
|
||||
MIN_TIME_BETWEEN_SCANS = timedelta(seconds=10)
|
||||
|
||||
|
||||
# pylint: disable=too-many-branches
|
||||
def setup(bus, statemachine):
|
||||
""" Track states and offer events for WeMo switches. """
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
try:
|
||||
import ouimeaux.environment as wemo_env
|
||||
import ouimeaux.device.switch as wemo_switch
|
||||
import ouimeaux.device.insight as wemo_insight
|
||||
except ImportError:
|
||||
logger.exception(("Failed to import ouimeaux. "
|
||||
"Did you maybe not install the 'ouimeaux' "
|
||||
"dependency?"))
|
||||
|
||||
return False
|
||||
|
||||
env = wemo_env.Environment()
|
||||
|
||||
try:
|
||||
env.start()
|
||||
except socket.error:
|
||||
# If the socket is already in use
|
||||
logger.exception("Error starting WeMo environment")
|
||||
return False
|
||||
|
||||
env.discover(5)
|
||||
|
||||
if len(env.list_switches()) == 0:
|
||||
logger.error("No WeMo switches found")
|
||||
return False
|
||||
|
||||
# Dict mapping serial no to entity IDs
|
||||
sno_to_ent = {}
|
||||
# Dict mapping entity IDs to devices
|
||||
ent_to_dev = {}
|
||||
|
||||
def _update_wemo_state(device):
|
||||
""" Update the state of specified WeMo device. """
|
||||
|
||||
# We currently only support switches
|
||||
if not isinstance(device, wemo_switch.Switch):
|
||||
return
|
||||
|
||||
try:
|
||||
entity_id = sno_to_ent[device.serialnumber]
|
||||
|
||||
except KeyError:
|
||||
# New device, set it up
|
||||
entity_id = ENTITY_ID_FORMAT.format(util.slugify(device.name))
|
||||
|
||||
sno_to_ent[device.serialnumber] = entity_id
|
||||
ent_to_dev[entity_id] = device
|
||||
|
||||
state = STATE_ON if device.get_state(True) else STATE_OFF
|
||||
|
||||
state_attr = {ATTR_FRIENDLY_NAME: device.name}
|
||||
|
||||
if isinstance(device, wemo_insight.Insight):
|
||||
pass
|
||||
# Should work but doesn't..
|
||||
#state_attr[ATTR_TODAY_KWH] = device.today_kwh
|
||||
#state_attr[ATTR_CURRENT_POWER] = device.current_power
|
||||
#state_attr[ATTR_TODAY_ON_TIME] = device.today_on_time
|
||||
#state_attr[ATTR_TODAY_STANDBY_TIME] = device.today_standby_time
|
||||
|
||||
statemachine.set_state(entity_id, state, state_attr)
|
||||
|
||||
# pylint: disable=unused-argument
|
||||
def _update_wemos_state(time, force_reload=False):
|
||||
""" Update states of all WeMo devices. """
|
||||
|
||||
# First time this method gets called, force_reload should be True
|
||||
if (force_reload or
|
||||
datetime.now() - _update_wemos_state.last_updated >
|
||||
MIN_TIME_BETWEEN_SCANS):
|
||||
|
||||
logger.info("Updating WeMo status")
|
||||
_update_wemos_state.last_updated = datetime.now()
|
||||
|
||||
for device in env:
|
||||
_update_wemo_state(device)
|
||||
|
||||
_update_wemos_state(None, True)
|
||||
|
||||
# Track all lights in a group
|
||||
group.setup(bus, statemachine,
|
||||
GROUP_NAME_ALL_WEMOS, sno_to_ent.values())
|
||||
|
||||
def _handle_wemo_service(service):
|
||||
""" Handles calls to the WeMo service. """
|
||||
dat = service.data
|
||||
|
||||
if ATTR_ENTITY_ID in dat:
|
||||
device = ent_to_dev.get(dat[ATTR_ENTITY_ID])
|
||||
|
||||
devices = [device] if device is not None else []
|
||||
else:
|
||||
devices = ent_to_dev.values()
|
||||
|
||||
for device in devices:
|
||||
if service.service == SERVICE_TURN_ON:
|
||||
device.on()
|
||||
else:
|
||||
device.off()
|
||||
|
||||
_update_wemo_state(device)
|
||||
|
||||
# Update WeMo state every 30 seconds
|
||||
ha.track_time_change(bus, _update_wemos_state, second=[0, 30])
|
||||
|
||||
bus.register_service(DOMAIN, SERVICE_TURN_OFF, _handle_wemo_service)
|
||||
|
||||
bus.register_service(DOMAIN, SERVICE_TURN_ON, _handle_wemo_service)
|
||||
|
||||
return True
|
Loading…
x
Reference in New Issue
Block a user