147 lines
4.4 KiB
Python
147 lines
4.4 KiB
Python
"""
|
|
Support for INSTEON fans via PowerLinc Modem.
|
|
|
|
For more details about this component, please refer to the documentation at
|
|
https://home-assistant.io/components/insteon_plm/
|
|
"""
|
|
import logging
|
|
import asyncio
|
|
|
|
from homeassistant.core import callback
|
|
from homeassistant.components.fan import (SPEED_OFF,
|
|
SPEED_LOW,
|
|
SPEED_MEDIUM,
|
|
SPEED_HIGH,
|
|
FanEntity,
|
|
SUPPORT_SET_SPEED)
|
|
from homeassistant.const import STATE_OFF
|
|
from homeassistant.loader import get_component
|
|
|
|
DEPENDENCIES = ['insteon_plm']
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
@asyncio.coroutine
|
|
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
|
"""Set up the INSTEON PLM device class for the hass platform."""
|
|
|
|
state_list = []
|
|
plm = hass.data['insteon_plm']
|
|
|
|
for deviceInfo in discovery_info:
|
|
address = deviceInfo['address']
|
|
device = plm.devices[address]
|
|
stateKey = deviceInfo['stateKey']
|
|
newnames = deviceInfo['newnames']
|
|
|
|
state_list.append(InsteonPLMFan(hass,
|
|
device,
|
|
stateKey,
|
|
newnames,
|
|
SUPPORT_SET_SPEED))
|
|
|
|
async_add_devices(state_list)
|
|
|
|
|
|
class InsteonPLMFan(FanEntity):
|
|
"""An INSTEON fan component."""
|
|
|
|
def __init__(self, hass, device, stateKey, newnames,
|
|
supported_features: int, ) -> None:
|
|
"""Initialize the entity."""
|
|
self._hass = hass
|
|
self._state = device.states[stateKey]
|
|
self._device = device
|
|
self._newnames = newnames
|
|
self._supported_features = supported_features
|
|
|
|
self._state.register_updates(self.async_fan_update)
|
|
|
|
@property
|
|
def should_poll(self):
|
|
"""No polling needed."""
|
|
return False
|
|
|
|
@property
|
|
def address(self):
|
|
"""Return the address of the node."""
|
|
return self._device.address.human
|
|
|
|
@property
|
|
def name(self):
|
|
"""Return the name of the node. (used for Entity_ID)"""
|
|
name = ''
|
|
if self._newnames:
|
|
name = '{:s}_{:s}'.format(self._device.id, self._state.name)
|
|
else:
|
|
if self._state.group == 0x01:
|
|
name = self._device.id
|
|
else:
|
|
name = '{:s}_{:d}'.format(self._device.id, self._state.group)
|
|
return name
|
|
|
|
@property
|
|
def device_state_attributes(self):
|
|
"""Provide attributes for display on device card."""
|
|
insteon_plm = get_component('insteon_plm')
|
|
return insteon_plm.common_attributes(self._device, self._state)
|
|
|
|
@property
|
|
def speed(self) -> str:
|
|
"""Return the current speed."""
|
|
return self._hex_to_speed(self._state.value)
|
|
|
|
@property
|
|
def speed_list(self) -> list:
|
|
"""Get the list of available speeds."""
|
|
return [STATE_OFF, SPEED_LOW, SPEED_MEDIUM, SPEED_HIGH]
|
|
|
|
def async_turn_on(self, speed: str=None) -> None:
|
|
"""Turn on the entity."""
|
|
if speed is None:
|
|
speed = SPEED_MEDIUM
|
|
self.async_set_speed(speed)
|
|
|
|
def async_turn_off(self) -> None:
|
|
"""Turn off the entity."""
|
|
self.async_set_speed(SPEED_OFF)
|
|
|
|
def async_set_speed(self, speed: str) -> None:
|
|
"""Set the speed of the fan."""
|
|
fanSpeed = self._speed_to_hex(speed)
|
|
if fanSpeed == 0x00:
|
|
self._state.off()
|
|
else:
|
|
self._state.set_level(fanSpeed)
|
|
|
|
@callback
|
|
def async_fan_update(self, deviceid, statename, val):
|
|
"""Receive notification from transport that new data exists."""
|
|
self.hass.async_add_job(self.async_update_ha_state())
|
|
|
|
@property
|
|
def supported_features(self) -> int:
|
|
"""Flag supported features."""
|
|
return self._supported_features
|
|
|
|
def _speed_to_hex(self, speed: str):
|
|
if speed == SPEED_OFF:
|
|
return 0x00
|
|
elif speed == SPEED_LOW:
|
|
return 0x3f
|
|
elif speed == SPEED_MEDIUM:
|
|
return 0xbe
|
|
elif speed == SPEED_HIGH:
|
|
return 0xff
|
|
return 0xbe
|
|
|
|
def _hex_to_speed(self, speed: int):
|
|
if speed > 0xfe:
|
|
return SPEED_HIGH
|
|
elif speed > 0x7f:
|
|
return SPEED_MEDIUM
|
|
elif speed > 0:
|
|
return SPEED_LOW
|
|
return SPEED_OFF
|