New support Digital Loggers relays (#4684)
* initial commit Previous work included with no history. Sorry, I was figuring out how to use git, branches and deal with open source projects. At this point this is a working switch but with the shortcomings of each of the 8 ports causes a network query. This needs to be rewritten so that the SwitchDevice is part of a larger device group that is only queried once, saving traffic and preventing the small device from timing out. * Device polls independent of switches now Used anel_pwrctrl.py as a basis to extract the per-switch polling out to per-device so it can be trottled properly. Likewise, no longer touching the device independently for relay status AND relay name. Getting them both from the same statuslist() return. * Final comments and tweaks Lowered cycle and update time since the device update is working so well now. Effectively no timeouts anymore. * Added dlipower to requirements homeassistant.components.switch.digitalloggers * Tox fixes pydocstyle updates * More tox errors * Yet more tox Removed useful future TODO and helpful details on the structure of the statuslocal list. Good catch on not initializing .update(), though it worked. * Blank line fix * Added file to .coveragercpull/4715/head
parent
53c1b93b61
commit
4d35f2805f
|
@ -318,6 +318,7 @@ omit =
|
|||
homeassistant/components/switch/acer_projector.py
|
||||
homeassistant/components/switch/anel_pwrctrl.py
|
||||
homeassistant/components/switch/arest.py
|
||||
homeassistant/components/switch/digitalloggers.py
|
||||
homeassistant/components/switch/dlink.py
|
||||
homeassistant/components/switch/edimax.py
|
||||
homeassistant/components/switch/hikvisioncam.py
|
||||
|
|
|
@ -0,0 +1,148 @@
|
|||
"""
|
||||
Support for Digital Loggers DIN III Relays.
|
||||
|
||||
Support for Digital Loggers DIN III Relays and possibly other items
|
||||
through Dwight Hubbard's, python-dlipower.
|
||||
|
||||
For more details about python-dlipower, please see
|
||||
https://github.com/dwighthubbard/python-dlipower
|
||||
|
||||
Custom ports are NOT supported due to a limitation of the dlipower
|
||||
library, not the digital loggers switch
|
||||
|
||||
"""
|
||||
import logging
|
||||
from datetime import timedelta
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.switch import (SwitchDevice, PLATFORM_SCHEMA)
|
||||
from homeassistant.const import (
|
||||
CONF_HOST, CONF_NAME, CONF_USERNAME, CONF_PASSWORD, CONF_TIMEOUT)
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.util import Throttle
|
||||
|
||||
|
||||
REQUIREMENTS = ['dlipower==0.7.165']
|
||||
|
||||
CONF_CYCLETIME = 'cycletime'
|
||||
|
||||
DEFAULT_NAME = 'DINRelay'
|
||||
DEFAULT_USERNAME = 'admin'
|
||||
DEFAULT_PASSWORD = 'admin'
|
||||
DEFAULT_TIMEOUT = 20
|
||||
DEFAULT_CYCLETIME = 2
|
||||
|
||||
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=5)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||
vol.Required(CONF_HOST): cv.string,
|
||||
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
||||
vol.Optional(CONF_USERNAME, default=DEFAULT_USERNAME): cv.string,
|
||||
vol.Optional(CONF_PASSWORD, default=DEFAULT_PASSWORD): cv.string,
|
||||
vol.Optional(CONF_TIMEOUT, default=DEFAULT_TIMEOUT):
|
||||
vol.All(vol.Coerce(int), vol.Range(min=1, max=600)),
|
||||
vol.Optional(CONF_CYCLETIME, default=DEFAULT_CYCLETIME):
|
||||
vol.All(vol.Coerce(int), vol.Range(min=1, max=600)),
|
||||
|
||||
})
|
||||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Find and return DIN III Relay switch."""
|
||||
import dlipower
|
||||
|
||||
host = config.get(CONF_HOST)
|
||||
controllername = config.get(CONF_NAME)
|
||||
user = config.get(CONF_USERNAME)
|
||||
pswd = config.get(CONF_PASSWORD)
|
||||
tout = config.get(CONF_TIMEOUT)
|
||||
cycl = config.get(CONF_CYCLETIME)
|
||||
|
||||
power_switch = dlipower.PowerSwitch(
|
||||
hostname=host, userid=user, password=pswd,
|
||||
timeout=tout, cycletime=cycl
|
||||
)
|
||||
|
||||
if not power_switch.verify():
|
||||
_LOGGER.error('Could not connect to DIN III Relay')
|
||||
return False
|
||||
|
||||
devices = []
|
||||
parent_device = DINRelayDevice(power_switch)
|
||||
|
||||
devices.extend(
|
||||
DINRelay(controllername, device.outlet_number, parent_device)
|
||||
for device in power_switch
|
||||
)
|
||||
|
||||
add_devices(devices)
|
||||
|
||||
|
||||
class DINRelay(SwitchDevice):
|
||||
"""Representation of a individual DIN III relay port."""
|
||||
|
||||
def __init__(self, name, outletnumber, parent_device):
|
||||
"""Initialize the DIN III Relay switch."""
|
||||
self._parent_device = parent_device
|
||||
self.controllername = name
|
||||
self.outletnumber = outletnumber
|
||||
self.update()
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the display name of this relay."""
|
||||
return self._outletname
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""Return true if relay is on."""
|
||||
return self._is_on
|
||||
|
||||
@property
|
||||
def should_poll(self):
|
||||
"""Polling is needed."""
|
||||
return True
|
||||
|
||||
def turn_on(self, **kwargs):
|
||||
"""Instruct the relay to turn on."""
|
||||
self._parent_device.turn_on(outlet=self.outletnumber)
|
||||
|
||||
def turn_off(self, **kwargs):
|
||||
"""Instruct the relay to turn off."""
|
||||
self._parent_device.turn_off(outlet=self.outletnumber)
|
||||
|
||||
def update(self):
|
||||
"""Trigger update for all switches on the parent device."""
|
||||
self._parent_device.update()
|
||||
self._is_on = (
|
||||
self._parent_device.statuslocal[self.outletnumber - 1][2] == 'ON'
|
||||
)
|
||||
self._outletname = "{}_{}".format(
|
||||
self.controllername,
|
||||
self._parent_device.statuslocal[self.outletnumber - 1][1]
|
||||
)
|
||||
|
||||
|
||||
class DINRelayDevice(object):
|
||||
"""Device representation for per device throttling."""
|
||||
|
||||
def __init__(self, device):
|
||||
"""Initialize the DINRelay device."""
|
||||
self._device = device
|
||||
self.update()
|
||||
|
||||
def turn_on(self, **kwargs):
|
||||
"""Instruct the relay to turn on."""
|
||||
self._device.on(**kwargs)
|
||||
|
||||
def turn_off(self, **kwargs):
|
||||
"""Instruct the relay to turn off."""
|
||||
self._device.off(**kwargs)
|
||||
|
||||
@Throttle(MIN_TIME_BETWEEN_UPDATES)
|
||||
def update(self):
|
||||
"""Fetch new state data for this device."""
|
||||
self.statuslocal = self._device.statuslist()
|
|
@ -84,6 +84,9 @@ directpy==0.1
|
|||
# homeassistant.components.updater
|
||||
distro==1.0.1
|
||||
|
||||
# homeassistant.components.switch.digitalloggers
|
||||
dlipower==0.7.165
|
||||
|
||||
# homeassistant.components.notify.xmpp
|
||||
dnspython3==1.15.0
|
||||
|
||||
|
|
Loading…
Reference in New Issue