mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 20:57:21 +00:00
Back out insteon hub and fan changes (#3062)
This commit is contained in:
parent
a7a662d224
commit
6fdd7f5350
@ -1,66 +0,0 @@
|
|||||||
"""
|
|
||||||
Support for Insteon FanLinc.
|
|
||||||
|
|
||||||
For more details about this platform, please refer to the documentation at
|
|
||||||
https://home-assistant.io/components/fan.insteon/
|
|
||||||
"""
|
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
from homeassistant.components.fan import (FanEntity, SUPPORT_SET_SPEED,
|
|
||||||
SPEED_OFF, SPEED_LOW, SPEED_MED,
|
|
||||||
SPEED_HIGH)
|
|
||||||
from homeassistant.components.insteon_hub import (InsteonDevice, INSTEON,
|
|
||||||
filter_devices)
|
|
||||||
from homeassistant.const import STATE_UNKNOWN
|
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
DEVICE_CATEGORIES = [
|
|
||||||
{
|
|
||||||
'DevCat': 1,
|
|
||||||
'SubCat': [46]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
DEPENDENCIES = ['insteon_hub']
|
|
||||||
|
|
||||||
|
|
||||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
|
||||||
"""Setup the Insteon Hub fan platform."""
|
|
||||||
devs = []
|
|
||||||
for device in filter_devices(INSTEON.devices, DEVICE_CATEGORIES):
|
|
||||||
devs.append(InsteonFanDevice(device))
|
|
||||||
add_devices(devs)
|
|
||||||
|
|
||||||
|
|
||||||
class InsteonFanDevice(InsteonDevice, FanEntity):
|
|
||||||
"""Represet an insteon fan device."""
|
|
||||||
|
|
||||||
def __init__(self, node: object) -> None:
|
|
||||||
"""Initialize the device."""
|
|
||||||
super(InsteonFanDevice, self).__init__(node)
|
|
||||||
self.speed = STATE_UNKNOWN # Insteon hub can't get state via REST
|
|
||||||
|
|
||||||
def turn_on(self, speed: str=None):
|
|
||||||
"""Turn the fan on."""
|
|
||||||
self.set_speed(speed if speed else SPEED_MED)
|
|
||||||
|
|
||||||
def turn_off(self):
|
|
||||||
"""Turn the fan off."""
|
|
||||||
self.set_speed(SPEED_OFF)
|
|
||||||
|
|
||||||
def set_speed(self, speed: str) -> None:
|
|
||||||
"""Set the fan speed."""
|
|
||||||
if self._send_command('fan', payload={'speed', speed}):
|
|
||||||
self.speed = speed
|
|
||||||
|
|
||||||
@property
|
|
||||||
def supported_features(self) -> int:
|
|
||||||
"""Get the supported features for device."""
|
|
||||||
return SUPPORT_SET_SPEED
|
|
||||||
|
|
||||||
@property
|
|
||||||
def speed_list(self) -> list:
|
|
||||||
"""Get the available speeds for the fan."""
|
|
||||||
return [SPEED_OFF, SPEED_LOW, SPEED_MED, SPEED_HIGH]
|
|
@ -8,93 +8,37 @@ import logging
|
|||||||
|
|
||||||
from homeassistant.const import CONF_API_KEY, CONF_PASSWORD, CONF_USERNAME
|
from homeassistant.const import CONF_API_KEY, CONF_PASSWORD, CONF_USERNAME
|
||||||
from homeassistant.helpers import validate_config, discovery
|
from homeassistant.helpers import validate_config, discovery
|
||||||
from homeassistant.helpers.entity import Entity
|
|
||||||
|
|
||||||
DOMAIN = 'insteon_hub' # type: str
|
|
||||||
REQUIREMENTS = ['insteon_hub==0.5.0'] # type: list
|
|
||||||
INSTEON = None # type: Insteon
|
|
||||||
DEVCAT = 'DevCat' # type: str
|
|
||||||
SUBCAT = 'SubCat' # type: str
|
|
||||||
DEVICE_CLASSES = ['light', 'fan'] # type: list
|
|
||||||
|
|
||||||
|
DOMAIN = "insteon_hub"
|
||||||
|
REQUIREMENTS = ['insteon_hub==0.4.5']
|
||||||
|
INSTEON = None
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def _is_successful(response: dict) -> bool:
|
def setup(hass, config):
|
||||||
"""Check http response for successful status."""
|
"""Setup Insteon Hub component.
|
||||||
return 'status' in response and response['status'] == 'succeeded'
|
|
||||||
|
|
||||||
|
This will automatically import associated lights.
|
||||||
def filter_devices(devices: list, categories: list) -> list:
|
"""
|
||||||
"""Filter insteon device list by category/subcategory."""
|
|
||||||
categories = (categories
|
|
||||||
if isinstance(categories, list)
|
|
||||||
else [categories])
|
|
||||||
matching_devices = []
|
|
||||||
for device in devices:
|
|
||||||
if any(
|
|
||||||
device.DevCat == c[DEVCAT] and
|
|
||||||
(SUBCAT not in c or device.SubCat in c[SUBCAT])
|
|
||||||
for c in categories):
|
|
||||||
matching_devices.append(device)
|
|
||||||
return matching_devices
|
|
||||||
|
|
||||||
|
|
||||||
def setup(hass, config: dict) -> bool:
|
|
||||||
"""Setup Insteon Hub component."""
|
|
||||||
if not validate_config(
|
if not validate_config(
|
||||||
config,
|
config,
|
||||||
{DOMAIN: [CONF_USERNAME, CONF_PASSWORD, CONF_API_KEY]},
|
{DOMAIN: [CONF_USERNAME, CONF_PASSWORD, CONF_API_KEY]},
|
||||||
_LOGGER):
|
_LOGGER):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
from insteon import Insteon
|
import insteon
|
||||||
|
|
||||||
username = config[DOMAIN][CONF_USERNAME]
|
username = config[DOMAIN][CONF_USERNAME]
|
||||||
password = config[DOMAIN][CONF_PASSWORD]
|
password = config[DOMAIN][CONF_PASSWORD]
|
||||||
api_key = config[DOMAIN][CONF_API_KEY]
|
api_key = config[DOMAIN][CONF_API_KEY]
|
||||||
|
|
||||||
global INSTEON
|
global INSTEON
|
||||||
INSTEON = Insteon(username, password, api_key)
|
INSTEON = insteon.Insteon(username, password, api_key)
|
||||||
|
|
||||||
if INSTEON is None:
|
if INSTEON is None:
|
||||||
_LOGGER.error('Could not connect to Insteon service.')
|
_LOGGER.error("Could not connect to Insteon service.")
|
||||||
return
|
return
|
||||||
|
|
||||||
for device_class in DEVICE_CLASSES:
|
discovery.load_platform(hass, 'light', DOMAIN, {}, config)
|
||||||
discovery.load_platform(hass, device_class, DOMAIN, {}, config)
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
class InsteonDevice(Entity):
|
|
||||||
"""Represents an insteon device."""
|
|
||||||
|
|
||||||
def __init__(self: Entity, node: object) -> None:
|
|
||||||
"""Initialize the insteon device."""
|
|
||||||
self._node = node
|
|
||||||
|
|
||||||
def update(self: Entity) -> None:
|
|
||||||
"""Update state of the device."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
@property
|
|
||||||
def name(self: Entity) -> str:
|
|
||||||
"""Name of the insteon device."""
|
|
||||||
return self._node.DeviceName
|
|
||||||
|
|
||||||
@property
|
|
||||||
def unique_id(self: Entity) -> str:
|
|
||||||
"""Unique identifier for the device."""
|
|
||||||
return self._node.DeviceID
|
|
||||||
|
|
||||||
@property
|
|
||||||
def supported_features(self: Entity) -> int:
|
|
||||||
"""Supported feature flags."""
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def _send_command(self: Entity, command: str, level: int=None,
|
|
||||||
payload: dict=None) -> bool:
|
|
||||||
"""Send command to insteon device."""
|
|
||||||
resp = self._node.send_command(command, payload=payload, level=level,
|
|
||||||
wait=True)
|
|
||||||
return _is_successful(resp)
|
|
||||||
|
@ -4,76 +4,74 @@ Support for Insteon Hub lights.
|
|||||||
For more details about this platform, please refer to the documentation at
|
For more details about this platform, please refer to the documentation at
|
||||||
https://home-assistant.io/components/insteon_hub/
|
https://home-assistant.io/components/insteon_hub/
|
||||||
"""
|
"""
|
||||||
from homeassistant.components.insteon_hub import (INSTEON, InsteonDevice)
|
from homeassistant.components.insteon_hub import INSTEON
|
||||||
from homeassistant.components.light import (ATTR_BRIGHTNESS,
|
from homeassistant.components.light import (ATTR_BRIGHTNESS,
|
||||||
SUPPORT_BRIGHTNESS, Light)
|
SUPPORT_BRIGHTNESS, Light)
|
||||||
|
|
||||||
SUPPORT_INSTEON_HUB = SUPPORT_BRIGHTNESS
|
SUPPORT_INSTEON_HUB = SUPPORT_BRIGHTNESS
|
||||||
|
|
||||||
DEPENDENCIES = ['insteon_hub']
|
|
||||||
|
|
||||||
|
|
||||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||||
"""Setup the Insteon Hub light platform."""
|
"""Setup the Insteon Hub light platform."""
|
||||||
devs = []
|
devs = []
|
||||||
for device in INSTEON.devices:
|
for device in INSTEON.devices:
|
||||||
if device.DeviceCategory == "Switched Lighting Control":
|
if device.DeviceCategory == "Switched Lighting Control":
|
||||||
devs.append(InsteonLightDevice(device))
|
devs.append(InsteonToggleDevice(device))
|
||||||
if device.DeviceCategory == "Dimmable Lighting Control":
|
if device.DeviceCategory == "Dimmable Lighting Control":
|
||||||
devs.append(InsteonDimmableDevice(device))
|
devs.append(InsteonToggleDevice(device))
|
||||||
add_devices(devs)
|
add_devices(devs)
|
||||||
|
|
||||||
|
|
||||||
class InsteonLightDevice(InsteonDevice, Light):
|
class InsteonToggleDevice(Light):
|
||||||
"""A representation of a light device."""
|
"""An abstract Class for an Insteon node."""
|
||||||
|
|
||||||
def __init__(self, node: object) -> None:
|
def __init__(self, node):
|
||||||
"""Initialize the device."""
|
"""Initialize the device."""
|
||||||
super(InsteonLightDevice, self).__init__(node)
|
self.node = node
|
||||||
self._value = 0
|
self._value = 0
|
||||||
|
|
||||||
def update(self) -> None:
|
@property
|
||||||
"""Update state of the device."""
|
def name(self):
|
||||||
resp = self._node.send_command('get_status', wait=True)
|
"""Return the the name of the node."""
|
||||||
|
return self.node.DeviceName
|
||||||
|
|
||||||
|
@property
|
||||||
|
def unique_id(self):
|
||||||
|
"""Return the ID of this insteon node."""
|
||||||
|
return self.node.DeviceID
|
||||||
|
|
||||||
|
@property
|
||||||
|
def brightness(self):
|
||||||
|
"""Return the brightness of this light between 0..255."""
|
||||||
|
return self._value / 100 * 255
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
"""Update state of the sensor."""
|
||||||
|
resp = self.node.send_command('get_status', wait=True)
|
||||||
try:
|
try:
|
||||||
self._value = resp['response']['level']
|
self._value = resp['response']['level']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_on(self) -> None:
|
def is_on(self):
|
||||||
"""Return the boolean response if the node is on."""
|
"""Return the boolean response if the node is on."""
|
||||||
return self._value != 0
|
return self._value != 0
|
||||||
|
|
||||||
def turn_on(self, **kwargs) -> None:
|
|
||||||
"""Turn device on."""
|
|
||||||
if self._send_command('on'):
|
|
||||||
self._value = 100
|
|
||||||
|
|
||||||
def turn_off(self, **kwargs) -> None:
|
|
||||||
"""Turn device off."""
|
|
||||||
if self._send_command('off'):
|
|
||||||
self._value = 0
|
|
||||||
|
|
||||||
|
|
||||||
class InsteonDimmableDevice(InsteonLightDevice):
|
|
||||||
"""A representation for a dimmable device."""
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def brightness(self) -> int:
|
def supported_features(self):
|
||||||
"""Return the brightness of this light between 0..255."""
|
|
||||||
return round(self._value / 100 * 255, 0) # type: int
|
|
||||||
|
|
||||||
@property
|
|
||||||
def supported_features(self) -> int:
|
|
||||||
"""Flag supported features."""
|
"""Flag supported features."""
|
||||||
return SUPPORT_INSTEON_HUB
|
return SUPPORT_INSTEON_HUB
|
||||||
|
|
||||||
def turn_on(self, **kwargs) -> None:
|
def turn_on(self, **kwargs):
|
||||||
"""Turn device on."""
|
"""Turn device on."""
|
||||||
level = 100 # type: int
|
|
||||||
if ATTR_BRIGHTNESS in kwargs:
|
if ATTR_BRIGHTNESS in kwargs:
|
||||||
level = round(kwargs[ATTR_BRIGHTNESS] / 255 * 100, 0) # type: int
|
self._value = kwargs[ATTR_BRIGHTNESS] / 255 * 100
|
||||||
|
self.node.send_command('on', self._value)
|
||||||
|
else:
|
||||||
|
self._value = 100
|
||||||
|
self.node.send_command('on')
|
||||||
|
|
||||||
if self._send_command('on', level=level):
|
def turn_off(self, **kwargs):
|
||||||
self._value = level
|
"""Turn device off."""
|
||||||
|
self.node.send_command('off')
|
||||||
|
@ -207,7 +207,7 @@ https://github.com/wokar/pylgnetcast/archive/v0.2.0.zip#pylgnetcast==0.2.0
|
|||||||
influxdb==3.0.0
|
influxdb==3.0.0
|
||||||
|
|
||||||
# homeassistant.components.insteon_hub
|
# homeassistant.components.insteon_hub
|
||||||
insteon_hub==0.5.0
|
insteon_hub==0.4.5
|
||||||
|
|
||||||
# homeassistant.components.media_player.kodi
|
# homeassistant.components.media_player.kodi
|
||||||
jsonrpc-requests==0.3
|
jsonrpc-requests==0.3
|
||||||
|
@ -1,73 +0,0 @@
|
|||||||
"""Tests for the insteon hub fan platform."""
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
from homeassistant.const import (STATE_OFF, STATE_ON)
|
|
||||||
from homeassistant.components.fan import (SPEED_LOW, SPEED_MED, SPEED_HIGH,
|
|
||||||
ATTR_SPEED)
|
|
||||||
from homeassistant.components.fan.insteon_hub import (InsteonFanDevice,
|
|
||||||
SUPPORT_SET_SPEED)
|
|
||||||
|
|
||||||
|
|
||||||
class Node(object):
|
|
||||||
"""Fake insteon node."""
|
|
||||||
|
|
||||||
def __init__(self, name, id, dev_cat, sub_cat):
|
|
||||||
"""Initialize fake insteon node."""
|
|
||||||
self.DeviceName = name
|
|
||||||
self.DeviceID = id
|
|
||||||
self.DevCat = dev_cat
|
|
||||||
self.SubCat = sub_cat
|
|
||||||
self.response = None
|
|
||||||
|
|
||||||
def send_command(self, command, payload, level, wait):
|
|
||||||
"""Send fake command."""
|
|
||||||
return self.response
|
|
||||||
|
|
||||||
|
|
||||||
class TestInsteonHubFanDevice(unittest.TestCase):
|
|
||||||
"""Test around insteon hub fan device methods."""
|
|
||||||
|
|
||||||
_NODE = Node('device', '12345', '1', '46')
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
"""Initialize test data."""
|
|
||||||
self._DEVICE = InsteonFanDevice(self._NODE)
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
"""Tear down test data."""
|
|
||||||
self._DEVICE = None
|
|
||||||
|
|
||||||
def test_properties(self):
|
|
||||||
"""Test basic properties."""
|
|
||||||
self.assertEqual(self._NODE.DeviceName, self._DEVICE.name)
|
|
||||||
self.assertEqual(self._NODE.DeviceID, self._DEVICE.unique_id)
|
|
||||||
self.assertEqual(SUPPORT_SET_SPEED, self._DEVICE.supported_features)
|
|
||||||
|
|
||||||
for speed in [STATE_OFF, SPEED_LOW, SPEED_MED, SPEED_HIGH]:
|
|
||||||
self.assertIn(speed, self._DEVICE.speed_list)
|
|
||||||
|
|
||||||
def test_turn_on(self):
|
|
||||||
"""Test the turning on device."""
|
|
||||||
self._NODE.response = {
|
|
||||||
'status': 'succeeded'
|
|
||||||
}
|
|
||||||
self.assertEqual(STATE_OFF, self._DEVICE.state)
|
|
||||||
self._DEVICE.turn_on()
|
|
||||||
|
|
||||||
self.assertEqual(STATE_ON, self._DEVICE.state)
|
|
||||||
|
|
||||||
self._DEVICE.turn_on(SPEED_MED)
|
|
||||||
|
|
||||||
self.assertEqual(STATE_ON, self._DEVICE.state)
|
|
||||||
self.assertEqual(SPEED_MED, self._DEVICE.state_attributes[ATTR_SPEED])
|
|
||||||
|
|
||||||
def test_turn_off(self):
|
|
||||||
"""Test turning off device."""
|
|
||||||
self._NODE.response = {
|
|
||||||
'status': 'succeeded'
|
|
||||||
}
|
|
||||||
self.assertEqual(STATE_OFF, self._DEVICE.state)
|
|
||||||
self._DEVICE.turn_on()
|
|
||||||
self.assertEqual(STATE_ON, self._DEVICE.state)
|
|
||||||
self._DEVICE.turn_off()
|
|
||||||
self.assertEqual(STATE_OFF, self._DEVICE.state)
|
|
Loading…
x
Reference in New Issue
Block a user