hass-core/homeassistant/components/rainbird/switch.py
Petr Vraník 3efdf29dfa Centralize rainbird config and add binary sensor platform (#26393)
* Update pyrainbird to version 0.2.0 to fix zone number issue:

- home-assistant/home-assistant/issues/24519
- jbarrancos/pyrainbird/issues/5
- https://community.home-assistant.io/t/rainbird-zone-switches-5-8-dont-correspond/104705

* requirements_all.txt regenerated

* code formatting

* pyrainbird version 0.3.0

* zone id

* rainsensor return state

* updating rainsensor

* new version of pyrainbird

* binary sensor state

* quiet in check format

* is_on instead of state for binary_sensor

* no unit of measurement for binary sensor

* no monitored conditions config

* get keys of dict directly

* removed redundant update of state

* simplified switch

* right states for switch

* raindelay sensor

* raindelay sensor

* binary sensor state

* binary sensor state

* reorganized imports

* doc on public method

* reformatted

* add irrigation service to rain bird, which allows you to set the duration

* rebased on konikvranik and solved some feedback

* add irrigation service to rain bird

* sensor types to constants

* synchronized register service

* patform discovery

* binary sensor as wrapper to sensor

* version 0.4.0

* new config approach

* sensors cleanup

* bypass if no zones found

* platform schema removed

* Change config schema to list of controllers

some small code improvements as suggested in CR:
 - dictionary acces by []
 - just return instead of return False
 - import order
 - no optional parameter name

* some small code improvements as suggested in CR:
 - supported platforms in constant
 - just return instead of return False
 - removed unused constant

* No single controller configuration

Co-Authored-By: Martin Hjelmare <marhje52@kth.se>

* pyrainbird 0.4.1

* individual switch configuration

* imports order

* generate default name out of entity

* trigger time required for controller

* incorporated CR remarks:
- constant fo rzones
- removed SCAN_INTERVAL
- detection of success on initialization
- removed underscore
- refactored if/else
- empty line on end of file
- hass as first parameter

* import of library on top

* refactored

* Update homeassistant/components/rainbird/__init__.py

Co-Authored-By: Martin Hjelmare <marhje52@kth.se>

* validate time and set defaults

* set defaults on right place

* pylint bypass

* iterate over values

* codeowner

* reverted changes:

* irrigation time just as positive integer. Making it complex does make
sense
* zone edfaults fullfiled at runtime. There is no information about
available zones in configuration time.

* codeowners updated

* accept timedelta in irrigation time

* simplified time calculation

* call total_seconds

* irrigation time as seconds.

* simplified schema
2019-09-26 11:24:03 +02:00

115 lines
3.5 KiB
Python

"""Support for Rain Bird Irrigation system LNK WiFi Module."""
import logging
from pyrainbird import AvailableStations, RainbirdController
import voluptuous as vol
from homeassistant.components.switch import SwitchDevice
from homeassistant.const import ATTR_ENTITY_ID, CONF_FRIENDLY_NAME, CONF_TRIGGER_TIME
from homeassistant.helpers import config_validation as cv
from . import CONF_ZONES, DATA_RAINBIRD, DOMAIN, RAINBIRD_CONTROLLER
_LOGGER = logging.getLogger(__name__)
ATTR_DURATION = "duration"
SERVICE_START_IRRIGATION = "start_irrigation"
SERVICE_SCHEMA_IRRIGATION = vol.Schema(
{
vol.Required(ATTR_ENTITY_ID): cv.entity_id,
vol.Required(ATTR_DURATION): vol.All(vol.Coerce(float), vol.Range(min=0)),
}
)
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up Rain Bird switches over a Rain Bird controller."""
if discovery_info is None:
return
controller: RainbirdController = hass.data[DATA_RAINBIRD][
discovery_info[RAINBIRD_CONTROLLER]
]
available_stations: AvailableStations = controller.get_available_stations()
if not (available_stations and available_stations.stations):
return
devices = []
for zone in range(1, available_stations.stations.count + 1):
if available_stations.stations.active(zone):
zone_config = discovery_info.get(CONF_ZONES, {}).get(zone, {})
time = zone_config.get(CONF_TRIGGER_TIME, discovery_info[CONF_TRIGGER_TIME])
name = zone_config.get(CONF_FRIENDLY_NAME)
devices.append(
RainBirdSwitch(
controller,
zone,
time,
name if name else "Sprinkler {}".format(zone),
)
)
add_entities(devices, True)
def start_irrigation(service):
entity_id = service.data[ATTR_ENTITY_ID]
duration = service.data[ATTR_DURATION]
for device in devices:
if device.entity_id == entity_id:
device.turn_on(duration=duration)
hass.services.register(
DOMAIN,
SERVICE_START_IRRIGATION,
start_irrigation,
schema=SERVICE_SCHEMA_IRRIGATION,
)
class RainBirdSwitch(SwitchDevice):
"""Representation of a Rain Bird switch."""
def __init__(self, controller: RainbirdController, zone, time, name):
"""Initialize a Rain Bird Switch Device."""
self._rainbird = controller
self._zone = zone
self._name = name
self._state = None
self._duration = time
self._attributes = {ATTR_DURATION: self._duration, "zone": self._zone}
@property
def device_state_attributes(self):
"""Return state attributes."""
return self._attributes
@property
def name(self):
"""Get the name of the switch."""
return self._name
def turn_on(self, **kwargs):
"""Turn the switch on."""
if self._rainbird.irrigate_zone(
int(self._zone),
int(kwargs[ATTR_DURATION] if ATTR_DURATION in kwargs else self._duration),
):
self._state = True
def turn_off(self, **kwargs):
"""Turn the switch off."""
if self._rainbird.stop_irrigation():
self._state = False
def update(self):
"""Update switch status."""
self._state = self._rainbird.get_zone_state(self._zone)
@property
def is_on(self):
"""Return true if switch is on."""
return self._state