From ec79e0c3ffaf0f2fd37b8fcd93648288e9478b55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Vran=C3=ADk?= Date: Mon, 19 Aug 2019 11:03:31 +0200 Subject: [PATCH 01/60] 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 --- homeassistant/components/rainbird/manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/rainbird/manifest.json b/homeassistant/components/rainbird/manifest.json index 584ea22afe23e..0d16123afd3e1 100644 --- a/homeassistant/components/rainbird/manifest.json +++ b/homeassistant/components/rainbird/manifest.json @@ -3,7 +3,7 @@ "name": "Rainbird", "documentation": "https://www.home-assistant.io/components/rainbird", "requirements": [ - "pyrainbird==0.2.1" + "pyrainbird==0.3.0" ], "dependencies": [], "codeowners": [] From d747c587855829737810b67778c9f41e633a8dfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Vran=C3=ADk?= Date: Mon, 19 Aug 2019 11:18:31 +0200 Subject: [PATCH 02/60] requirements_all.txt regenerated --- requirements_all.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_all.txt b/requirements_all.txt index a5670313692bb..356225dfd0d91 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1387,7 +1387,7 @@ pyqwikswitch==0.93 pyrail==0.0.3 # homeassistant.components.rainbird -pyrainbird==0.2.1 +pyrainbird==0.3.0 # homeassistant.components.recswitch pyrecswitch==1.0.2 From fa2a54fa6852990f8f60b21f42fb21feaeae9072 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Vran=C3=ADk?= Date: Mon, 19 Aug 2019 11:39:50 +0200 Subject: [PATCH 03/60] code formatting --- script/check_format | 1 - 1 file changed, 1 deletion(-) diff --git a/script/check_format b/script/check_format index bed35ec63e48c..c92544696453d 100755 --- a/script/check_format +++ b/script/check_format @@ -6,5 +6,4 @@ cd "$(dirname "$0")/.." black \ --check \ --fast \ - --quiet \ homeassistant tests script *.py From b18237d762dafe0de9df5c05157c7a7050ac9415 Mon Sep 17 00:00:00 2001 From: konikvranik Date: Sun, 1 Sep 2019 12:31:47 +0200 Subject: [PATCH 04/60] pyrainbird version 0.3.0 --- homeassistant/components/rainbird/__init__.py | 4 ++-- homeassistant/components/rainbird/sensor.py | 8 ++++---- homeassistant/components/rainbird/switch.py | 13 +++++-------- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/homeassistant/components/rainbird/__init__.py b/homeassistant/components/rainbird/__init__.py index 1d8ed8e37b169..3ba84cee54ba1 100644 --- a/homeassistant/components/rainbird/__init__.py +++ b/homeassistant/components/rainbird/__init__.py @@ -33,8 +33,8 @@ def setup(hass, config): _LOGGER.debug("Rain Bird Controller set to: %s", server) - initial_status = controller.currentIrrigation() - if initial_status and initial_status["type"] != "CurrentStationsActiveResponse": + initial_status = controller.command("ModelAndVersion") + if initial_status and initial_status["type"] != "ModelAndVersionResponse": _LOGGER.error("Error getting state. Possible configuration issues") return False diff --git a/homeassistant/components/rainbird/sensor.py b/homeassistant/components/rainbird/sensor.py index 2d4549a21d5db..070e0bb01e6fe 100644 --- a/homeassistant/components/rainbird/sensor.py +++ b/homeassistant/components/rainbird/sensor.py @@ -3,11 +3,11 @@ import voluptuous as vol +import homeassistant.helpers.config_validation as cv from homeassistant.components.sensor import PLATFORM_SCHEMA from homeassistant.const import CONF_MONITORED_CONDITIONS -import homeassistant.helpers.config_validation as cv from homeassistant.helpers.entity import Entity - +from pyrainbird import RainbirdController from . import DATA_RAINBIRD _LOGGER = logging.getLogger(__name__) @@ -38,7 +38,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None): class RainBirdSensor(Entity): """A sensor implementation for Rain Bird device.""" - def __init__(self, controller, sensor_type): + def __init__(self, controller: RainbirdController, sensor_type): """Initialize the Rain Bird sensor.""" self._sensor_type = sensor_type self._controller = controller @@ -56,7 +56,7 @@ def update(self): """Get the latest data and updates the states.""" _LOGGER.debug("Updating sensor: %s", self._name) if self._sensor_type == "rainsensor": - result = self._controller.currentRainSensorState() + result = self._controller.get_rain_sensor_state() if result and result["type"] == "CurrentRainSensorStateResponse": self._state = result["sensorState"] else: diff --git a/homeassistant/components/rainbird/switch.py b/homeassistant/components/rainbird/switch.py index 868e8ff4c7d65..a714864860638 100644 --- a/homeassistant/components/rainbird/switch.py +++ b/homeassistant/components/rainbird/switch.py @@ -13,6 +13,7 @@ CONF_ZONE, ) from homeassistant.helpers import config_validation as cv +from pyrainbird import RainbirdController from . import DATA_RAINBIRD @@ -48,7 +49,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None): class RainBirdSwitch(SwitchDevice): """Representation of a Rain Bird switch.""" - def __init__(self, rb, dev, dev_id): + def __init__(self, rb: RainbirdController, dev, dev_id): """Initialize a Rain Bird Switch Device.""" self._rainbird = rb self._devid = dev_id @@ -70,23 +71,19 @@ def name(self): def turn_on(self, **kwargs): """Turn the switch on.""" - response = self._rainbird.startIrrigation(int(self._zone), int(self._duration)) + response = self._rainbird.irrigate_zone(int(self._zone), int(self._duration)) if response and response["type"] == "AcknowledgeResponse": self._state = True def turn_off(self, **kwargs): """Turn the switch off.""" - response = self._rainbird.stopIrrigation() + response = self._rainbird.stop_irrigation() if response and response["type"] == "AcknowledgeResponse": self._state = False def get_device_status(self): """Get the status of the switch from Rain Bird Controller.""" - response = self._rainbird.currentIrrigation() - if response is None: - return None - if isinstance(response, dict) and "sprinklers" in response: - return response["sprinklers"][self._zone] + return self._rainbird.zone_state(self._devid) def update(self): """Update switch status.""" From b84a89c1bd24763680e44c2caeff1c7f9550e57d Mon Sep 17 00:00:00 2001 From: konikvranik Date: Sun, 1 Sep 2019 12:57:28 +0200 Subject: [PATCH 05/60] zone id --- homeassistant/components/rainbird/switch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/rainbird/switch.py b/homeassistant/components/rainbird/switch.py index a714864860638..98ac16d3d8fd7 100644 --- a/homeassistant/components/rainbird/switch.py +++ b/homeassistant/components/rainbird/switch.py @@ -83,7 +83,7 @@ def turn_off(self, **kwargs): def get_device_status(self): """Get the status of the switch from Rain Bird Controller.""" - return self._rainbird.zone_state(self._devid) + return self._rainbird.zone_state(self._zone) def update(self): """Update switch status.""" From 22dad98869eb881dd6fc475038285d6030e7695d Mon Sep 17 00:00:00 2001 From: konikvranik Date: Sun, 1 Sep 2019 16:00:28 +0200 Subject: [PATCH 06/60] rainsensor return state --- homeassistant/components/rainbird/sensor.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/homeassistant/components/rainbird/sensor.py b/homeassistant/components/rainbird/sensor.py index 070e0bb01e6fe..04844fb798708 100644 --- a/homeassistant/components/rainbird/sensor.py +++ b/homeassistant/components/rainbird/sensor.py @@ -56,11 +56,7 @@ def update(self): """Get the latest data and updates the states.""" _LOGGER.debug("Updating sensor: %s", self._name) if self._sensor_type == "rainsensor": - result = self._controller.get_rain_sensor_state() - if result and result["type"] == "CurrentRainSensorStateResponse": - self._state = result["sensorState"] - else: - self._state = None + return self._controller.get_rain_sensor_state() @property def name(self): From f2c96bbb9f82e4c5d99f5e0b7a30e732f78b8e61 Mon Sep 17 00:00:00 2001 From: konikvranik Date: Sun, 1 Sep 2019 16:10:02 +0200 Subject: [PATCH 07/60] updating rainsensor --- .../components/rainbird/binary_sensor.py | 74 +++++++++++++++++++ homeassistant/components/rainbird/sensor.py | 2 +- 2 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 homeassistant/components/rainbird/binary_sensor.py diff --git a/homeassistant/components/rainbird/binary_sensor.py b/homeassistant/components/rainbird/binary_sensor.py new file mode 100644 index 0000000000000..8ee032cecf46b --- /dev/null +++ b/homeassistant/components/rainbird/binary_sensor.py @@ -0,0 +1,74 @@ +"""Support for Rain Bird Irrigation system LNK WiFi Module.""" +import logging + +import voluptuous as vol + +import homeassistant.helpers.config_validation as cv +from homeassistant.components.sensor import PLATFORM_SCHEMA +from homeassistant.const import CONF_MONITORED_CONDITIONS +from homeassistant.helpers.entity import Entity +from pyrainbird import RainbirdController +from . import DATA_RAINBIRD + +_LOGGER = logging.getLogger(__name__) + +# sensor_type [ description, unit, icon ] +SENSOR_TYPES = {"rainsensor": ["Rainsensor", None, "mdi:water"]} + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( + { + vol.Optional(CONF_MONITORED_CONDITIONS, default=list(SENSOR_TYPES)): vol.All( + cv.ensure_list, [vol.In(SENSOR_TYPES)] + ) + } +) + + +def setup_platform(hass, config, add_entities, discovery_info=None): + """Set up a Rain Bird sensor.""" + controller = hass.data[DATA_RAINBIRD] + + sensors = [] + for sensor_type in config.get(CONF_MONITORED_CONDITIONS): + sensors.append(RainBirdSensor(controller, sensor_type)) + + add_entities(sensors, True) + + +class RainBirdSensor(Entity): + """A sensor implementation for Rain Bird device.""" + + def __init__(self, controller: RainbirdController, sensor_type): + """Initialize the Rain Bird sensor.""" + self._sensor_type = sensor_type + self._controller = controller + self._name = SENSOR_TYPES[self._sensor_type][0] + self._icon = SENSOR_TYPES[self._sensor_type][2] + self._unit_of_measurement = SENSOR_TYPES[self._sensor_type][1] + self._state = None + + @property + def state(self): + """Return the state of the sensor.""" + return self._state + + def update(self): + """Get the latest data and updates the states.""" + _LOGGER.debug("Updating sensor: %s", self._name) + if self._sensor_type == "rainsensor": + self._state = bool(self._controller.get_rain_sensor_state()) + + @property + def name(self): + """Return the name of this camera.""" + return self._name + + @property + def unit_of_measurement(self): + """Return the units of measurement.""" + return self._unit_of_measurement + + @property + def icon(self): + """Return icon.""" + return self._icon diff --git a/homeassistant/components/rainbird/sensor.py b/homeassistant/components/rainbird/sensor.py index 04844fb798708..c8019279936ea 100644 --- a/homeassistant/components/rainbird/sensor.py +++ b/homeassistant/components/rainbird/sensor.py @@ -56,7 +56,7 @@ def update(self): """Get the latest data and updates the states.""" _LOGGER.debug("Updating sensor: %s", self._name) if self._sensor_type == "rainsensor": - return self._controller.get_rain_sensor_state() + self._state = self._controller.get_rain_sensor_state() @property def name(self): From ea1595d584cc264930a46f6fb124c3bd5470ca0b Mon Sep 17 00:00:00 2001 From: konikvranik Date: Tue, 3 Sep 2019 18:57:52 +0200 Subject: [PATCH 08/60] new version of pyrainbird --- homeassistant/components/rainbird/manifest.json | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/rainbird/manifest.json b/homeassistant/components/rainbird/manifest.json index 0d16123afd3e1..0e9a4f1a46b0a 100644 --- a/homeassistant/components/rainbird/manifest.json +++ b/homeassistant/components/rainbird/manifest.json @@ -3,7 +3,7 @@ "name": "Rainbird", "documentation": "https://www.home-assistant.io/components/rainbird", "requirements": [ - "pyrainbird==0.3.0" + "pyrainbird==0.3.1" ], "dependencies": [], "codeowners": [] diff --git a/requirements_all.txt b/requirements_all.txt index 356225dfd0d91..dff163c92d6e0 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1387,7 +1387,7 @@ pyqwikswitch==0.93 pyrail==0.0.3 # homeassistant.components.rainbird -pyrainbird==0.3.0 +pyrainbird==0.3.1 # homeassistant.components.recswitch pyrecswitch==1.0.2 From d74495be7adab8756c029e2903906f763a01a8f0 Mon Sep 17 00:00:00 2001 From: konikvranik Date: Tue, 3 Sep 2019 20:04:20 +0200 Subject: [PATCH 09/60] binary sensor state --- homeassistant/components/rainbird/binary_sensor.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/rainbird/binary_sensor.py b/homeassistant/components/rainbird/binary_sensor.py index 8ee032cecf46b..9b6f5d1b6946b 100644 --- a/homeassistant/components/rainbird/binary_sensor.py +++ b/homeassistant/components/rainbird/binary_sensor.py @@ -56,7 +56,8 @@ def update(self): """Get the latest data and updates the states.""" _LOGGER.debug("Updating sensor: %s", self._name) if self._sensor_type == "rainsensor": - self._state = bool(self._controller.get_rain_sensor_state()) + state = self._controller.get_rain_sensor_state() + self._state = None if state is None else bool(state) @property def name(self): From 1ebf820e4e4c015eeb0f4b1964ed5479a16a079b Mon Sep 17 00:00:00 2001 From: konikvranik Date: Tue, 3 Sep 2019 20:24:42 +0200 Subject: [PATCH 10/60] quiet in check format --- script/check_format | 1 + 1 file changed, 1 insertion(+) diff --git a/script/check_format b/script/check_format index c92544696453d..bed35ec63e48c 100755 --- a/script/check_format +++ b/script/check_format @@ -6,4 +6,5 @@ cd "$(dirname "$0")/.." black \ --check \ --fast \ + --quiet \ homeassistant tests script *.py From 967c3e9b2ec158a941388281e9cb528097cfe598 Mon Sep 17 00:00:00 2001 From: konikvranik Date: Tue, 3 Sep 2019 20:25:46 +0200 Subject: [PATCH 11/60] is_on instead of state for binary_sensor --- homeassistant/components/rainbird/binary_sensor.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/rainbird/binary_sensor.py b/homeassistant/components/rainbird/binary_sensor.py index 9b6f5d1b6946b..8c60b93d3d58b 100644 --- a/homeassistant/components/rainbird/binary_sensor.py +++ b/homeassistant/components/rainbird/binary_sensor.py @@ -48,16 +48,15 @@ def __init__(self, controller: RainbirdController, sensor_type): self._state = None @property - def state(self): - """Return the state of the sensor.""" - return self._state + def is_on(self): + self._state = self._controller.get_rain_sensor_state() + return None if self._state is None else bool(self._state) def update(self): """Get the latest data and updates the states.""" _LOGGER.debug("Updating sensor: %s", self._name) if self._sensor_type == "rainsensor": - state = self._controller.get_rain_sensor_state() - self._state = None if state is None else bool(state) + self._state = self._controller.get_rain_sensor_state() @property def name(self): From 6f513b235832f93ecc775bf774666be285f1b482 Mon Sep 17 00:00:00 2001 From: konikvranik Date: Tue, 3 Sep 2019 20:26:15 +0200 Subject: [PATCH 12/60] no unit of measurement for binary sensor --- homeassistant/components/rainbird/binary_sensor.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/homeassistant/components/rainbird/binary_sensor.py b/homeassistant/components/rainbird/binary_sensor.py index 8c60b93d3d58b..16143c503684f 100644 --- a/homeassistant/components/rainbird/binary_sensor.py +++ b/homeassistant/components/rainbird/binary_sensor.py @@ -44,7 +44,6 @@ def __init__(self, controller: RainbirdController, sensor_type): self._controller = controller self._name = SENSOR_TYPES[self._sensor_type][0] self._icon = SENSOR_TYPES[self._sensor_type][2] - self._unit_of_measurement = SENSOR_TYPES[self._sensor_type][1] self._state = None @property @@ -63,11 +62,6 @@ def name(self): """Return the name of this camera.""" return self._name - @property - def unit_of_measurement(self): - """Return the units of measurement.""" - return self._unit_of_measurement - @property def icon(self): """Return icon.""" From e8af86aeee675e7f4878b2b2511d098755242803 Mon Sep 17 00:00:00 2001 From: konikvranik Date: Tue, 3 Sep 2019 20:26:35 +0200 Subject: [PATCH 13/60] no monitored conditions config --- .../components/rainbird/binary_sensor.py | 15 +-------------- homeassistant/components/rainbird/sensor.py | 15 +-------------- 2 files changed, 2 insertions(+), 28 deletions(-) diff --git a/homeassistant/components/rainbird/binary_sensor.py b/homeassistant/components/rainbird/binary_sensor.py index 16143c503684f..b13c1059d11f8 100644 --- a/homeassistant/components/rainbird/binary_sensor.py +++ b/homeassistant/components/rainbird/binary_sensor.py @@ -1,11 +1,6 @@ """Support for Rain Bird Irrigation system LNK WiFi Module.""" import logging -import voluptuous as vol - -import homeassistant.helpers.config_validation as cv -from homeassistant.components.sensor import PLATFORM_SCHEMA -from homeassistant.const import CONF_MONITORED_CONDITIONS from homeassistant.helpers.entity import Entity from pyrainbird import RainbirdController from . import DATA_RAINBIRD @@ -15,21 +10,13 @@ # sensor_type [ description, unit, icon ] SENSOR_TYPES = {"rainsensor": ["Rainsensor", None, "mdi:water"]} -PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( - { - vol.Optional(CONF_MONITORED_CONDITIONS, default=list(SENSOR_TYPES)): vol.All( - cv.ensure_list, [vol.In(SENSOR_TYPES)] - ) - } -) - def setup_platform(hass, config, add_entities, discovery_info=None): """Set up a Rain Bird sensor.""" controller = hass.data[DATA_RAINBIRD] sensors = [] - for sensor_type in config.get(CONF_MONITORED_CONDITIONS): + for sensor_type in map(lambda k, v: k, SENSOR_TYPES): sensors.append(RainBirdSensor(controller, sensor_type)) add_entities(sensors, True) diff --git a/homeassistant/components/rainbird/sensor.py b/homeassistant/components/rainbird/sensor.py index c8019279936ea..6f2977c8b617e 100644 --- a/homeassistant/components/rainbird/sensor.py +++ b/homeassistant/components/rainbird/sensor.py @@ -1,11 +1,6 @@ """Support for Rain Bird Irrigation system LNK WiFi Module.""" import logging -import voluptuous as vol - -import homeassistant.helpers.config_validation as cv -from homeassistant.components.sensor import PLATFORM_SCHEMA -from homeassistant.const import CONF_MONITORED_CONDITIONS from homeassistant.helpers.entity import Entity from pyrainbird import RainbirdController from . import DATA_RAINBIRD @@ -15,21 +10,13 @@ # sensor_type [ description, unit, icon ] SENSOR_TYPES = {"rainsensor": ["Rainsensor", None, "mdi:water"]} -PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( - { - vol.Optional(CONF_MONITORED_CONDITIONS, default=list(SENSOR_TYPES)): vol.All( - cv.ensure_list, [vol.In(SENSOR_TYPES)] - ) - } -) - def setup_platform(hass, config, add_entities, discovery_info=None): """Set up a Rain Bird sensor.""" controller = hass.data[DATA_RAINBIRD] sensors = [] - for sensor_type in config.get(CONF_MONITORED_CONDITIONS): + for sensor_type in map(lambda k, v: k, SENSOR_TYPES): sensors.append(RainBirdSensor(controller, sensor_type)) add_entities(sensors, True) From 59db27571b6d9bc32fc6893186f0f40010dcc1bd Mon Sep 17 00:00:00 2001 From: konikvranik Date: Tue, 3 Sep 2019 20:33:30 +0200 Subject: [PATCH 14/60] get keys of dict directly --- homeassistant/components/rainbird/binary_sensor.py | 2 +- homeassistant/components/rainbird/sensor.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/rainbird/binary_sensor.py b/homeassistant/components/rainbird/binary_sensor.py index b13c1059d11f8..02f92d05362ae 100644 --- a/homeassistant/components/rainbird/binary_sensor.py +++ b/homeassistant/components/rainbird/binary_sensor.py @@ -16,7 +16,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None): controller = hass.data[DATA_RAINBIRD] sensors = [] - for sensor_type in map(lambda k, v: k, SENSOR_TYPES): + for sensor_type in SENSOR_TYPES.keys(): sensors.append(RainBirdSensor(controller, sensor_type)) add_entities(sensors, True) diff --git a/homeassistant/components/rainbird/sensor.py b/homeassistant/components/rainbird/sensor.py index 6f2977c8b617e..9fd5b1b9e8df0 100644 --- a/homeassistant/components/rainbird/sensor.py +++ b/homeassistant/components/rainbird/sensor.py @@ -16,7 +16,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None): controller = hass.data[DATA_RAINBIRD] sensors = [] - for sensor_type in map(lambda k, v: k, SENSOR_TYPES): + for sensor_type in SENSOR_TYPES.keys(): sensors.append(RainBirdSensor(controller, sensor_type)) add_entities(sensors, True) From 3cd2b042432e5a1005d3ea594f30ee17971ad9c7 Mon Sep 17 00:00:00 2001 From: konikvranik Date: Tue, 3 Sep 2019 20:35:33 +0200 Subject: [PATCH 15/60] removed redundant update of state --- homeassistant/components/rainbird/binary_sensor.py | 1 - 1 file changed, 1 deletion(-) diff --git a/homeassistant/components/rainbird/binary_sensor.py b/homeassistant/components/rainbird/binary_sensor.py index 02f92d05362ae..d67ffa8773374 100644 --- a/homeassistant/components/rainbird/binary_sensor.py +++ b/homeassistant/components/rainbird/binary_sensor.py @@ -35,7 +35,6 @@ def __init__(self, controller: RainbirdController, sensor_type): @property def is_on(self): - self._state = self._controller.get_rain_sensor_state() return None if self._state is None else bool(self._state) def update(self): From d1758c109b87c2af4543ff56d7b169524185db42 Mon Sep 17 00:00:00 2001 From: konikvranik Date: Tue, 3 Sep 2019 20:49:09 +0200 Subject: [PATCH 16/60] simplified switch --- homeassistant/components/rainbird/switch.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/homeassistant/components/rainbird/switch.py b/homeassistant/components/rainbird/switch.py index 98ac16d3d8fd7..cd70fb03fa5d8 100644 --- a/homeassistant/components/rainbird/switch.py +++ b/homeassistant/components/rainbird/switch.py @@ -81,13 +81,9 @@ def turn_off(self, **kwargs): if response and response["type"] == "AcknowledgeResponse": self._state = False - def get_device_status(self): - """Get the status of the switch from Rain Bird Controller.""" - return self._rainbird.zone_state(self._zone) - def update(self): """Update switch status.""" - self._state = self.get_device_status() + self._state = self._rainbird.zone_state(self._zone) @property def is_on(self): From 54df46437e8321043cce7fd800358aed234507c4 Mon Sep 17 00:00:00 2001 From: konikvranik Date: Tue, 3 Sep 2019 21:01:51 +0200 Subject: [PATCH 17/60] right states for switch --- homeassistant/components/rainbird/switch.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/rainbird/switch.py b/homeassistant/components/rainbird/switch.py index cd70fb03fa5d8..2adba798dc607 100644 --- a/homeassistant/components/rainbird/switch.py +++ b/homeassistant/components/rainbird/switch.py @@ -71,14 +71,12 @@ def name(self): def turn_on(self, **kwargs): """Turn the switch on.""" - response = self._rainbird.irrigate_zone(int(self._zone), int(self._duration)) - if response and response["type"] == "AcknowledgeResponse": + if self._rainbird.irrigate_zone(int(self._zone), int(self._duration)): self._state = True def turn_off(self, **kwargs): """Turn the switch off.""" - response = self._rainbird.stop_irrigation() - if response and response["type"] == "AcknowledgeResponse": + if self._rainbird.stop_irrigation(): self._state = False def update(self): From 7375f4630bf8df06e9ed575e55866bc145c49014 Mon Sep 17 00:00:00 2001 From: konikvranik Date: Tue, 3 Sep 2019 21:07:13 +0200 Subject: [PATCH 18/60] raindelay sensor --- homeassistant/components/rainbird/sensor.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/rainbird/sensor.py b/homeassistant/components/rainbird/sensor.py index 9fd5b1b9e8df0..870c93f67a1b2 100644 --- a/homeassistant/components/rainbird/sensor.py +++ b/homeassistant/components/rainbird/sensor.py @@ -8,7 +8,8 @@ _LOGGER = logging.getLogger(__name__) # sensor_type [ description, unit, icon ] -SENSOR_TYPES = {"rainsensor": ["Rainsensor", None, "mdi:water"]} +SENSOR_TYPES = {"rainsensor": ["Rainsensor", None, "mdi:water"], + "raindelay": ["Raindelay", None, "mdi:water-off"]} def setup_platform(hass, config, add_entities, discovery_info=None): @@ -44,6 +45,8 @@ def update(self): _LOGGER.debug("Updating sensor: %s", self._name) if self._sensor_type == "rainsensor": self._state = self._controller.get_rain_sensor_state() + elif self._sensor_type == "raindelay": + self._state = self._controller.get_rain_delay() @property def name(self): From 9a6821edff2211c5bfb5fb2003297dfa6da62ce3 Mon Sep 17 00:00:00 2001 From: konikvranik Date: Tue, 3 Sep 2019 21:12:47 +0200 Subject: [PATCH 19/60] raindelay sensor --- homeassistant/components/rainbird/__init__.py | 5 +++++ homeassistant/components/rainbird/binary_sensor.py | 10 ++++------ homeassistant/components/rainbird/sensor.py | 8 ++------ 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/homeassistant/components/rainbird/__init__.py b/homeassistant/components/rainbird/__init__.py index 3ba84cee54ba1..aba75af616944 100644 --- a/homeassistant/components/rainbird/__init__.py +++ b/homeassistant/components/rainbird/__init__.py @@ -10,6 +10,9 @@ DATA_RAINBIRD = "rainbird" DOMAIN = "rainbird" +# sensor_type [ description, unit, icon ] +SENSOR_TYPES = {"rainsensor": ["Rainsensor", None, "mdi:water"], + "raindelay": ["Raindelay", None, "mdi:water-off"]} CONFIG_SCHEMA = vol.Schema( { @@ -40,3 +43,5 @@ def setup(hass, config): hass.data[DATA_RAINBIRD] = controller return True + + diff --git a/homeassistant/components/rainbird/binary_sensor.py b/homeassistant/components/rainbird/binary_sensor.py index d67ffa8773374..f41b8b46547c8 100644 --- a/homeassistant/components/rainbird/binary_sensor.py +++ b/homeassistant/components/rainbird/binary_sensor.py @@ -3,20 +3,16 @@ from homeassistant.helpers.entity import Entity from pyrainbird import RainbirdController -from . import DATA_RAINBIRD +from . import DATA_RAINBIRD, SENSOR_TYPES _LOGGER = logging.getLogger(__name__) -# sensor_type [ description, unit, icon ] -SENSOR_TYPES = {"rainsensor": ["Rainsensor", None, "mdi:water"]} - - def setup_platform(hass, config, add_entities, discovery_info=None): """Set up a Rain Bird sensor.""" controller = hass.data[DATA_RAINBIRD] sensors = [] - for sensor_type in SENSOR_TYPES.keys(): + for sensor_type in SENSOR_TYPES: sensors.append(RainBirdSensor(controller, sensor_type)) add_entities(sensors, True) @@ -42,6 +38,8 @@ def update(self): _LOGGER.debug("Updating sensor: %s", self._name) if self._sensor_type == "rainsensor": self._state = self._controller.get_rain_sensor_state() + elif self._sensor_type == "raindelay": + self._state = self._controller.get_rain_delay() @property def name(self): diff --git a/homeassistant/components/rainbird/sensor.py b/homeassistant/components/rainbird/sensor.py index 870c93f67a1b2..3bf044c97036e 100644 --- a/homeassistant/components/rainbird/sensor.py +++ b/homeassistant/components/rainbird/sensor.py @@ -3,21 +3,17 @@ from homeassistant.helpers.entity import Entity from pyrainbird import RainbirdController -from . import DATA_RAINBIRD +from . import DATA_RAINBIRD, SENSOR_TYPES _LOGGER = logging.getLogger(__name__) -# sensor_type [ description, unit, icon ] -SENSOR_TYPES = {"rainsensor": ["Rainsensor", None, "mdi:water"], - "raindelay": ["Raindelay", None, "mdi:water-off"]} - def setup_platform(hass, config, add_entities, discovery_info=None): """Set up a Rain Bird sensor.""" controller = hass.data[DATA_RAINBIRD] sensors = [] - for sensor_type in SENSOR_TYPES.keys(): + for sensor_type in SENSOR_TYPES: sensors.append(RainBirdSensor(controller, sensor_type)) add_entities(sensors, True) From d8e95f64713c2ffd2aaac16d362c198b695abf18 Mon Sep 17 00:00:00 2001 From: konikvranik Date: Tue, 3 Sep 2019 21:24:45 +0200 Subject: [PATCH 20/60] binary sensor state --- homeassistant/components/rainbird/binary_sensor.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/rainbird/binary_sensor.py b/homeassistant/components/rainbird/binary_sensor.py index f41b8b46547c8..3c6a5934aa616 100644 --- a/homeassistant/components/rainbird/binary_sensor.py +++ b/homeassistant/components/rainbird/binary_sensor.py @@ -7,6 +7,7 @@ _LOGGER = logging.getLogger(__name__) + def setup_platform(hass, config, add_entities, discovery_info=None): """Set up a Rain Bird sensor.""" controller = hass.data[DATA_RAINBIRD] @@ -36,10 +37,12 @@ def is_on(self): def update(self): """Get the latest data and updates the states.""" _LOGGER.debug("Updating sensor: %s", self._name) + state = None if self._sensor_type == "rainsensor": - self._state = self._controller.get_rain_sensor_state() + state = self._controller.get_rain_sensor_state() elif self._sensor_type == "raindelay": - self._state = self._controller.get_rain_delay() + state = self._controller.get_rain_delay() + self._state = None if state is None else bool(state) @property def name(self): From de5ba57d25b54c80203fd3a376521358e8b8d338 Mon Sep 17 00:00:00 2001 From: konikvranik Date: Tue, 3 Sep 2019 21:29:04 +0200 Subject: [PATCH 21/60] binary sensor state --- homeassistant/components/rainbird/binary_sensor.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/rainbird/binary_sensor.py b/homeassistant/components/rainbird/binary_sensor.py index 3c6a5934aa616..39350465d68c1 100644 --- a/homeassistant/components/rainbird/binary_sensor.py +++ b/homeassistant/components/rainbird/binary_sensor.py @@ -1,7 +1,7 @@ """Support for Rain Bird Irrigation system LNK WiFi Module.""" import logging -from homeassistant.helpers.entity import Entity +from homeassistant.components.binary_sensor import BinarySensorDevice from pyrainbird import RainbirdController from . import DATA_RAINBIRD, SENSOR_TYPES @@ -19,7 +19,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None): add_entities(sensors, True) -class RainBirdSensor(Entity): +class RainBirdSensor(BinarySensorDevice): """A sensor implementation for Rain Bird device.""" def __init__(self, controller: RainbirdController, sensor_type): From f7b670b8c83340858e0c877f071290ac404f291e Mon Sep 17 00:00:00 2001 From: konikvranik Date: Tue, 3 Sep 2019 21:32:07 +0200 Subject: [PATCH 22/60] reorganized imports --- homeassistant/components/rainbird/__init__.py | 4 +--- homeassistant/components/rainbird/binary_sensor.py | 4 +++- homeassistant/components/rainbird/sensor.py | 4 +++- homeassistant/components/rainbird/switch.py | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/homeassistant/components/rainbird/__init__.py b/homeassistant/components/rainbird/__init__.py index aba75af616944..95d3afd898059 100644 --- a/homeassistant/components/rainbird/__init__.py +++ b/homeassistant/components/rainbird/__init__.py @@ -3,8 +3,8 @@ import voluptuous as vol -import homeassistant.helpers.config_validation as cv from homeassistant.const import CONF_HOST, CONF_PASSWORD +import homeassistant.helpers.config_validation as cv _LOGGER = logging.getLogger(__name__) @@ -43,5 +43,3 @@ def setup(hass, config): hass.data[DATA_RAINBIRD] = controller return True - - diff --git a/homeassistant/components/rainbird/binary_sensor.py b/homeassistant/components/rainbird/binary_sensor.py index 39350465d68c1..89635f12067a5 100644 --- a/homeassistant/components/rainbird/binary_sensor.py +++ b/homeassistant/components/rainbird/binary_sensor.py @@ -1,8 +1,10 @@ """Support for Rain Bird Irrigation system LNK WiFi Module.""" import logging -from homeassistant.components.binary_sensor import BinarySensorDevice from pyrainbird import RainbirdController + +from homeassistant.components.binary_sensor import BinarySensorDevice + from . import DATA_RAINBIRD, SENSOR_TYPES _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/rainbird/sensor.py b/homeassistant/components/rainbird/sensor.py index 3bf044c97036e..5bd549a991d2d 100644 --- a/homeassistant/components/rainbird/sensor.py +++ b/homeassistant/components/rainbird/sensor.py @@ -1,8 +1,10 @@ """Support for Rain Bird Irrigation system LNK WiFi Module.""" import logging -from homeassistant.helpers.entity import Entity from pyrainbird import RainbirdController + +from homeassistant.helpers.entity import Entity + from . import DATA_RAINBIRD, SENSOR_TYPES _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/rainbird/switch.py b/homeassistant/components/rainbird/switch.py index 2adba798dc607..9fb19bc620654 100644 --- a/homeassistant/components/rainbird/switch.py +++ b/homeassistant/components/rainbird/switch.py @@ -2,6 +2,7 @@ import logging +from pyrainbird import RainbirdController import voluptuous as vol from homeassistant.components.switch import PLATFORM_SCHEMA, SwitchDevice @@ -13,7 +14,6 @@ CONF_ZONE, ) from homeassistant.helpers import config_validation as cv -from pyrainbird import RainbirdController from . import DATA_RAINBIRD From 5586685ad7c90666ed7bd3baf27c6d38bf8547d8 Mon Sep 17 00:00:00 2001 From: konikvranik Date: Tue, 3 Sep 2019 21:47:12 +0200 Subject: [PATCH 23/60] doc on public method --- homeassistant/components/rainbird/binary_sensor.py | 1 + 1 file changed, 1 insertion(+) diff --git a/homeassistant/components/rainbird/binary_sensor.py b/homeassistant/components/rainbird/binary_sensor.py index 89635f12067a5..b913cc4883490 100644 --- a/homeassistant/components/rainbird/binary_sensor.py +++ b/homeassistant/components/rainbird/binary_sensor.py @@ -34,6 +34,7 @@ def __init__(self, controller: RainbirdController, sensor_type): @property def is_on(self): + """Return true if the binary sensor is on.""" return None if self._state is None else bool(self._state) def update(self): From cfc61c8c43051803f627b6e57122792eff7931e2 Mon Sep 17 00:00:00 2001 From: konikvranik Date: Tue, 3 Sep 2019 21:54:59 +0200 Subject: [PATCH 24/60] reformatted --- homeassistant/components/rainbird/__init__.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/rainbird/__init__.py b/homeassistant/components/rainbird/__init__.py index 95d3afd898059..724b6f7dd61fd 100644 --- a/homeassistant/components/rainbird/__init__.py +++ b/homeassistant/components/rainbird/__init__.py @@ -11,8 +11,10 @@ DATA_RAINBIRD = "rainbird" DOMAIN = "rainbird" # sensor_type [ description, unit, icon ] -SENSOR_TYPES = {"rainsensor": ["Rainsensor", None, "mdi:water"], - "raindelay": ["Raindelay", None, "mdi:water-off"]} +SENSOR_TYPES = { + "rainsensor": ["Rainsensor", None, "mdi:water"], + "raindelay": ["Raindelay", None, "mdi:water-off"], +} CONFIG_SCHEMA = vol.Schema( { From 80756ef596f5c0e21861772a58e32ed2e7c27a9f Mon Sep 17 00:00:00 2001 From: Peter Nijssen Date: Tue, 3 Sep 2019 22:56:34 +0200 Subject: [PATCH 25/60] add irrigation service to rain bird, which allows you to set the duration --- .../components/rainbird/services.yaml | 9 +++ homeassistant/components/rainbird/switch.py | 60 +++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 homeassistant/components/rainbird/services.yaml diff --git a/homeassistant/components/rainbird/services.yaml b/homeassistant/components/rainbird/services.yaml new file mode 100644 index 0000000000000..160e86cff1232 --- /dev/null +++ b/homeassistant/components/rainbird/services.yaml @@ -0,0 +1,9 @@ +start_irrigation: + description: Start the irrigation + fields: + entity_id: + description: Name(s) of irrigations to turn on + example: 'switch.sprinkler_1' + duration: + description: Duration for this sprinkler to be turned on + example: 1 \ No newline at end of file diff --git a/homeassistant/components/rainbird/switch.py b/homeassistant/components/rainbird/switch.py index 9fb19bc620654..2d4f2a6bdceef 100644 --- a/homeassistant/components/rainbird/switch.py +++ b/homeassistant/components/rainbird/switch.py @@ -7,6 +7,7 @@ from homeassistant.components.switch import PLATFORM_SCHEMA, SwitchDevice from homeassistant.const import ( + ATTR_ENTITY_ID, CONF_FRIENDLY_NAME, CONF_SCAN_INTERVAL, CONF_SWITCHES, @@ -20,6 +21,12 @@ DOMAIN = "rainbird" _LOGGER = logging.getLogger(__name__) +ATTR_DURATION = "duration" + +SERVICE_START_IRRIGATION = "start_irrigation" + +SERVICE_SCHEMA = vol.Schema({vol.Optional(ATTR_ENTITY_ID): cv.entity_ids}) + PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( { vol.Required(CONF_SWITCHES, default={}): vol.Schema( @@ -35,6 +42,17 @@ } ) +SERVICE_SCHEMA_IRRIGATION = SERVICE_SCHEMA.extend( + {vol.Required(ATTR_DURATION): vol.All(vol.Coerce(float), vol.Range(min=0))} +) + +SERVICE_TO_METHOD = { + SERVICE_START_IRRIGATION: { + "method": "start_irrigation", + "schema": SERVICE_SCHEMA_IRRIGATION, + } +} + def setup_platform(hass, config, add_entities, discovery_info=None): """Set up Rain Bird switches over a Rain Bird controller.""" @@ -45,6 +63,31 @@ def setup_platform(hass, config, add_entities, discovery_info=None): devices.append(RainBirdSwitch(controller, switch, dev_id)) add_entities(devices, True) + def start_irrigation(service): + """Set IR code as device state attribute.""" + entity_ids = service.data.get(ATTR_ENTITY_ID) + duration = service.data.get(ATTR_DURATION) + + if entity_ids: + _devices = [ + device + for device in devices + if isinstance(device, RainBirdSwitch) and device.entity_id in entity_ids + ] + else: + _devices = [ + device for device in devices if isinstance(device, RainBirdSwitch) + ] + for device in _devices: + device.start_irrigation(duration) + + hass.services.async_register( + DOMAIN, + SERVICE_START_IRRIGATION, + start_irrigation, + schema=SERVICE_SCHEMA_IRRIGATION, + ) + class RainBirdSwitch(SwitchDevice): """Representation of a Rain Bird switch.""" @@ -79,6 +122,23 @@ def turn_off(self, **kwargs): if self._rainbird.stop_irrigation(): self._state = False +<<<<<<< HEAD +======= + def start_irrigation(self, duration: int): + """Turn the irrigation on.""" + response = self._rainbird.startIrrigation(int(self._zone), int(duration)) + if response and response["type"] == "AcknowledgeResponse": + self._state = True + + def get_device_status(self): + """Get the status of the switch from Rain Bird Controller.""" + response = self._rainbird.currentIrrigation() + if response is None: + return None + if isinstance(response, dict) and "sprinklers" in response: + return response["sprinklers"][self._zone] + +>>>>>>> add irrigation service to rain bird, which allows you to set the duration def update(self): """Update switch status.""" self._state = self._rainbird.zone_state(self._zone) From 38132236c485799686990beb6cb798181a950902 Mon Sep 17 00:00:00 2001 From: Peter Nijssen Date: Thu, 5 Sep 2019 23:36:15 +0200 Subject: [PATCH 26/60] rebased on konikvranik and solved some feedback --- .../components/rainbird/services.yaml | 2 +- homeassistant/components/rainbird/switch.py | 55 +++++-------------- 2 files changed, 14 insertions(+), 43 deletions(-) diff --git a/homeassistant/components/rainbird/services.yaml b/homeassistant/components/rainbird/services.yaml index 160e86cff1232..3ed79b2a9cbf6 100644 --- a/homeassistant/components/rainbird/services.yaml +++ b/homeassistant/components/rainbird/services.yaml @@ -2,7 +2,7 @@ start_irrigation: description: Start the irrigation fields: entity_id: - description: Name(s) of irrigations to turn on + description: Name of a single irrigation to turn on example: 'switch.sprinkler_1' duration: description: Duration for this sprinkler to be turned on diff --git a/homeassistant/components/rainbird/switch.py b/homeassistant/components/rainbird/switch.py index 2d4f2a6bdceef..ca17dd141ebe4 100644 --- a/homeassistant/components/rainbird/switch.py +++ b/homeassistant/components/rainbird/switch.py @@ -16,17 +16,14 @@ ) from homeassistant.helpers import config_validation as cv -from . import DATA_RAINBIRD +from . import DATA_RAINBIRD, DOMAIN -DOMAIN = "rainbird" _LOGGER = logging.getLogger(__name__) ATTR_DURATION = "duration" SERVICE_START_IRRIGATION = "start_irrigation" -SERVICE_SCHEMA = vol.Schema({vol.Optional(ATTR_ENTITY_ID): cv.entity_ids}) - PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( { vol.Required(CONF_SWITCHES, default={}): vol.Schema( @@ -42,16 +39,12 @@ } ) -SERVICE_SCHEMA_IRRIGATION = SERVICE_SCHEMA.extend( - {vol.Required(ATTR_DURATION): vol.All(vol.Coerce(float), vol.Range(min=0))} -) - -SERVICE_TO_METHOD = { - SERVICE_START_IRRIGATION: { - "method": "start_irrigation", - "schema": SERVICE_SCHEMA_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): @@ -64,22 +57,13 @@ def setup_platform(hass, config, add_entities, discovery_info=None): add_entities(devices, True) def start_irrigation(service): - """Set IR code as device state attribute.""" - entity_ids = service.data.get(ATTR_ENTITY_ID) + """Set the duration device state attribute and start the irrigation.""" + entity_id = service.data.get(ATTR_ENTITY_ID) duration = service.data.get(ATTR_DURATION) - if entity_ids: - _devices = [ - device - for device in devices - if isinstance(device, RainBirdSwitch) and device.entity_id in entity_ids - ] - else: - _devices = [ - device for device in devices if isinstance(device, RainBirdSwitch) - ] - for device in _devices: - device.start_irrigation(duration) + for device in devices: + if isinstance(device, RainBirdSwitch) and device.entity_id == entity_id: + device.start_irrigation(duration) hass.services.async_register( DOMAIN, @@ -114,31 +98,18 @@ def name(self): def turn_on(self, **kwargs): """Turn the switch on.""" - if self._rainbird.irrigate_zone(int(self._zone), int(self._duration)): - self._state = True + self.start_irrigation(self._duration) def turn_off(self, **kwargs): """Turn the switch off.""" if self._rainbird.stop_irrigation(): self._state = False -<<<<<<< HEAD -======= def start_irrigation(self, duration: int): """Turn the irrigation on.""" - response = self._rainbird.startIrrigation(int(self._zone), int(duration)) - if response and response["type"] == "AcknowledgeResponse": + if self._rainbird.irrigate_zone(int(self._zone), duration): self._state = True - def get_device_status(self): - """Get the status of the switch from Rain Bird Controller.""" - response = self._rainbird.currentIrrigation() - if response is None: - return None - if isinstance(response, dict) and "sprinklers" in response: - return response["sprinklers"][self._zone] - ->>>>>>> add irrigation service to rain bird, which allows you to set the duration def update(self): """Update switch status.""" self._state = self._rainbird.zone_state(self._zone) From 36fb7003a59a6f75e18ca67ace08449e23345c57 Mon Sep 17 00:00:00 2001 From: konikvranik Date: Sat, 7 Sep 2019 21:31:24 +0200 Subject: [PATCH 27/60] add irrigation service to rain bird --- homeassistant/components/rainbird/switch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/rainbird/switch.py b/homeassistant/components/rainbird/switch.py index ca17dd141ebe4..9d7697a9bec8c 100644 --- a/homeassistant/components/rainbird/switch.py +++ b/homeassistant/components/rainbird/switch.py @@ -107,7 +107,7 @@ def turn_off(self, **kwargs): def start_irrigation(self, duration: int): """Turn the irrigation on.""" - if self._rainbird.irrigate_zone(int(self._zone), duration): + if self._rainbird.irrigate_zone(int(self._zone), duration if duration else self._duration): self._state = True def update(self): From 0c72ebd1a70f7186b5d8612f4279189e4e8452b2 Mon Sep 17 00:00:00 2001 From: konikvranik Date: Mon, 9 Sep 2019 00:51:08 +0200 Subject: [PATCH 28/60] sensor types to constants --- homeassistant/components/rainbird/__init__.py | 7 +++++-- homeassistant/components/rainbird/binary_sensor.py | 6 +++--- homeassistant/components/rainbird/sensor.py | 6 +++--- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/homeassistant/components/rainbird/__init__.py b/homeassistant/components/rainbird/__init__.py index 724b6f7dd61fd..1e71e01f5f185 100644 --- a/homeassistant/components/rainbird/__init__.py +++ b/homeassistant/components/rainbird/__init__.py @@ -10,10 +10,13 @@ DATA_RAINBIRD = "rainbird" DOMAIN = "rainbird" + +SENSOR_TYPE_RAINDELAY = "raindelay" +SENSOR_TYPE_RAINSENSOR = "rainsensor" # sensor_type [ description, unit, icon ] SENSOR_TYPES = { - "rainsensor": ["Rainsensor", None, "mdi:water"], - "raindelay": ["Raindelay", None, "mdi:water-off"], + SENSOR_TYPE_RAINSENSOR: ["Rainsensor", None, "mdi:water"], + SENSOR_TYPE_RAINDELAY: ["Raindelay", None, "mdi:water-off"], } CONFIG_SCHEMA = vol.Schema( diff --git a/homeassistant/components/rainbird/binary_sensor.py b/homeassistant/components/rainbird/binary_sensor.py index b913cc4883490..6cadd7edadb8c 100644 --- a/homeassistant/components/rainbird/binary_sensor.py +++ b/homeassistant/components/rainbird/binary_sensor.py @@ -5,7 +5,7 @@ from homeassistant.components.binary_sensor import BinarySensorDevice -from . import DATA_RAINBIRD, SENSOR_TYPES +from . import DATA_RAINBIRD, SENSOR_TYPES, SENSOR_TYPE_RAINSENSOR, SENSOR_TYPE_RAINDELAY _LOGGER = logging.getLogger(__name__) @@ -41,9 +41,9 @@ def update(self): """Get the latest data and updates the states.""" _LOGGER.debug("Updating sensor: %s", self._name) state = None - if self._sensor_type == "rainsensor": + if self._sensor_type == SENSOR_TYPE_RAINSENSOR: state = self._controller.get_rain_sensor_state() - elif self._sensor_type == "raindelay": + elif self._sensor_type == SENSOR_TYPE_RAINDELAY: state = self._controller.get_rain_delay() self._state = None if state is None else bool(state) diff --git a/homeassistant/components/rainbird/sensor.py b/homeassistant/components/rainbird/sensor.py index 5bd549a991d2d..fb32cfdab5f89 100644 --- a/homeassistant/components/rainbird/sensor.py +++ b/homeassistant/components/rainbird/sensor.py @@ -5,7 +5,7 @@ from homeassistant.helpers.entity import Entity -from . import DATA_RAINBIRD, SENSOR_TYPES +from . import DATA_RAINBIRD, SENSOR_TYPES, SENSOR_TYPE_RAINDELAY, SENSOR_TYPE_RAINSENSOR _LOGGER = logging.getLogger(__name__) @@ -41,9 +41,9 @@ def state(self): def update(self): """Get the latest data and updates the states.""" _LOGGER.debug("Updating sensor: %s", self._name) - if self._sensor_type == "rainsensor": + if self._sensor_type == SENSOR_TYPE_RAINSENSOR: self._state = self._controller.get_rain_sensor_state() - elif self._sensor_type == "raindelay": + elif self._sensor_type == SENSOR_TYPE_RAINDELAY: self._state = self._controller.get_rain_delay() @property From d265f2f31295e6f4bff6a03b8b992f8efbc131bc Mon Sep 17 00:00:00 2001 From: konikvranik Date: Mon, 9 Sep 2019 00:51:26 +0200 Subject: [PATCH 29/60] synchronized register service --- homeassistant/components/rainbird/switch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/rainbird/switch.py b/homeassistant/components/rainbird/switch.py index 9d7697a9bec8c..14ff5f800c644 100644 --- a/homeassistant/components/rainbird/switch.py +++ b/homeassistant/components/rainbird/switch.py @@ -65,7 +65,7 @@ def start_irrigation(service): if isinstance(device, RainBirdSwitch) and device.entity_id == entity_id: device.start_irrigation(duration) - hass.services.async_register( + hass.services.register( DOMAIN, SERVICE_START_IRRIGATION, start_irrigation, From d4cc15addb6b2e1b9a044e611f7b9b0f13fa1c12 Mon Sep 17 00:00:00 2001 From: konikvranik Date: Mon, 9 Sep 2019 02:06:37 +0200 Subject: [PATCH 30/60] patform discovery --- homeassistant/components/rainbird/__init__.py | 31 +++++++++---- .../components/rainbird/binary_sensor.py | 26 ++++++----- homeassistant/components/rainbird/sensor.py | 25 +++++++---- homeassistant/components/rainbird/switch.py | 45 ++++++++++--------- 4 files changed, 78 insertions(+), 49 deletions(-) diff --git a/homeassistant/components/rainbird/__init__.py b/homeassistant/components/rainbird/__init__.py index 1e71e01f5f185..f7533fff9d47f 100644 --- a/homeassistant/components/rainbird/__init__.py +++ b/homeassistant/components/rainbird/__init__.py @@ -3,12 +3,20 @@ import voluptuous as vol -from homeassistant.const import CONF_HOST, CONF_PASSWORD import homeassistant.helpers.config_validation as cv +from homeassistant.components import sensor, binary_sensor +from homeassistant.components.rainbird.switch import ( + SERVICE_START_IRRIGATION, + SERVICE_SCHEMA_IRRIGATION, + ATTR_DURATION, + RainBirdSwitch, +) +from homeassistant.const import CONF_HOST, CONF_PASSWORD +from homeassistant.helpers import discovery _LOGGER = logging.getLogger(__name__) -DATA_RAINBIRD = "rainbird" +RAINBIRD_CONTROLLER = "rainbird_controller" DOMAIN = "rainbird" SENSOR_TYPE_RAINDELAY = "raindelay" @@ -22,7 +30,10 @@ CONFIG_SCHEMA = vol.Schema( { DOMAIN: vol.Schema( - {vol.Required(CONF_HOST): cv.string, vol.Required(CONF_PASSWORD): cv.string} + { + vol.Required(CONF_HOST): cv.string, + vol.Required(CONF_PASSWORD): cv.string, + } ) }, extra=vol.ALLOW_EXTRA, @@ -31,6 +42,7 @@ def setup(hass, config): """Set up the Rain Bird component.""" + conf = config[DOMAIN] server = conf.get(CONF_HOST) password = conf.get(CONF_PASSWORD) @@ -41,10 +53,13 @@ def setup(hass, config): _LOGGER.debug("Rain Bird Controller set to: %s", server) - initial_status = controller.command("ModelAndVersion") - if initial_status and initial_status["type"] != "ModelAndVersionResponse": - _LOGGER.error("Error getting state. Possible configuration issues") - return False + for platform in [switch.DOMAIN, sensor.DOMAIN, binary_sensor.DOMAIN]: + discovery.load_platform( + hass, + platform, + DOMAIN, + discovered={RAINBIRD_CONTROLLER: controller}, + hass_config=config, + ) - hass.data[DATA_RAINBIRD] = controller return True diff --git a/homeassistant/components/rainbird/binary_sensor.py b/homeassistant/components/rainbird/binary_sensor.py index 6cadd7edadb8c..90f2861c80ea0 100644 --- a/homeassistant/components/rainbird/binary_sensor.py +++ b/homeassistant/components/rainbird/binary_sensor.py @@ -1,24 +1,30 @@ """Support for Rain Bird Irrigation system LNK WiFi Module.""" import logging -from pyrainbird import RainbirdController - from homeassistant.components.binary_sensor import BinarySensorDevice - -from . import DATA_RAINBIRD, SENSOR_TYPES, SENSOR_TYPE_RAINSENSOR, SENSOR_TYPE_RAINDELAY +from pyrainbird import RainbirdController +from . import ( + RAINBIRD_CONTROLLER, + SENSOR_TYPES, + SENSOR_TYPE_RAINSENSOR, + SENSOR_TYPE_RAINDELAY, +) _LOGGER = logging.getLogger(__name__) def setup_platform(hass, config, add_entities, discovery_info=None): """Set up a Rain Bird sensor.""" - controller = hass.data[DATA_RAINBIRD] - - sensors = [] - for sensor_type in SENSOR_TYPES: - sensors.append(RainBirdSensor(controller, sensor_type)) + if discovery_info is None or not RAINBIRD_CONTROLLER in discovery_info: + return False - add_entities(sensors, True) + add_entities( + [ + RainBirdSensor(discovery_info[RAINBIRD_CONTROLLER], sensor_type) + for sensor_type in SENSOR_TYPES + ], + True, + ) class RainBirdSensor(BinarySensorDevice): diff --git a/homeassistant/components/rainbird/sensor.py b/homeassistant/components/rainbird/sensor.py index fb32cfdab5f89..367abf85340b3 100644 --- a/homeassistant/components/rainbird/sensor.py +++ b/homeassistant/components/rainbird/sensor.py @@ -1,24 +1,31 @@ """Support for Rain Bird Irrigation system LNK WiFi Module.""" import logging -from pyrainbird import RainbirdController - from homeassistant.helpers.entity import Entity - -from . import DATA_RAINBIRD, SENSOR_TYPES, SENSOR_TYPE_RAINDELAY, SENSOR_TYPE_RAINSENSOR +from pyrainbird import RainbirdController +from . import ( + RAINBIRD_CONTROLLER, + SENSOR_TYPES, + SENSOR_TYPE_RAINDELAY, + SENSOR_TYPE_RAINSENSOR, +) _LOGGER = logging.getLogger(__name__) def setup_platform(hass, config, add_entities, discovery_info=None): """Set up a Rain Bird sensor.""" - controller = hass.data[DATA_RAINBIRD] - sensors = [] - for sensor_type in SENSOR_TYPES: - sensors.append(RainBirdSensor(controller, sensor_type)) + if discovery_info is None or not RAINBIRD_CONTROLLER in discovery_info: + return False - add_entities(sensors, True) + add_entities( + [ + RainBirdSensor(discovery_info[RAINBIRD_CONTROLLER], sensor_type) + for sensor_type in SENSOR_TYPES + ], + True, + ) class RainBirdSensor(Entity): diff --git a/homeassistant/components/rainbird/switch.py b/homeassistant/components/rainbird/switch.py index 14ff5f800c644..ff4ffa9b95cb8 100644 --- a/homeassistant/components/rainbird/switch.py +++ b/homeassistant/components/rainbird/switch.py @@ -2,7 +2,6 @@ import logging -from pyrainbird import RainbirdController import voluptuous as vol from homeassistant.components.switch import PLATFORM_SCHEMA, SwitchDevice @@ -15,8 +14,8 @@ CONF_ZONE, ) from homeassistant.helpers import config_validation as cv - -from . import DATA_RAINBIRD, DOMAIN +from pyrainbird import RainbirdController +from . import RAINBIRD_CONTROLLER, DOMAIN _LOGGER = logging.getLogger(__name__) @@ -42,33 +41,37 @@ 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)), + 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.""" - controller = hass.data[DATA_RAINBIRD] - devices = [] - for dev_id, switch in config.get(CONF_SWITCHES).items(): - devices.append(RainBirdSwitch(controller, switch, dev_id)) + if discovery_info is None or not RAINBIRD_CONTROLLER in discovery_info: + return False + + devices = [ + RainBirdSwitch(discovery_info[RAINBIRD_CONTROLLER], switch) + for switch in config.get(CONF_SWITCHES).values() + ] add_entities(devices, True) - def start_irrigation(service): - """Set the duration device state attribute and start the irrigation.""" + def _start_irrigation(service): entity_id = service.data.get(ATTR_ENTITY_ID) duration = service.data.get(ATTR_DURATION) - for device in devices: - if isinstance(device, RainBirdSwitch) and device.entity_id == entity_id: - device.start_irrigation(duration) + for d in devices: + if d.entity_id == entity_id: + d.turn_on(duration=duration) hass.services.register( DOMAIN, SERVICE_START_IRRIGATION, - start_irrigation, + _start_irrigation, schema=SERVICE_SCHEMA_IRRIGATION, ) @@ -76,10 +79,9 @@ def start_irrigation(service): class RainBirdSwitch(SwitchDevice): """Representation of a Rain Bird switch.""" - def __init__(self, rb: RainbirdController, dev, dev_id): + def __init__(self, rb: RainbirdController, dev): """Initialize a Rain Bird Switch Device.""" self._rainbird = rb - self._devid = dev_id self._zone = int(dev.get(CONF_ZONE)) self._name = dev.get(CONF_FRIENDLY_NAME, f"Sprinkler {self._zone}") self._state = None @@ -98,18 +100,17 @@ def name(self): def turn_on(self, **kwargs): """Turn the switch on.""" - self.start_irrigation(self._duration) + if self._rainbird.irrigate_zone( + int(self._zone), + kwargs["duration"] if "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 start_irrigation(self, duration: int): - """Turn the irrigation on.""" - if self._rainbird.irrigate_zone(int(self._zone), duration if duration else self._duration): - self._state = True - def update(self): """Update switch status.""" self._state = self._rainbird.zone_state(self._zone) From 547d17f2afc523adb200cb5bca3adff1c3a0276e Mon Sep 17 00:00:00 2001 From: konikvranik Date: Mon, 9 Sep 2019 02:23:26 +0200 Subject: [PATCH 31/60] binary sensor as wrapper to sensor --- homeassistant/components/rainbird/__init__.py | 8 ++-- .../components/rainbird/binary_sensor.py | 40 ++++++------------- homeassistant/components/rainbird/sensor.py | 34 +++++++++++----- homeassistant/components/rainbird/switch.py | 5 ++- 4 files changed, 44 insertions(+), 43 deletions(-) diff --git a/homeassistant/components/rainbird/__init__.py b/homeassistant/components/rainbird/__init__.py index f7533fff9d47f..3f5c1c7d8a512 100644 --- a/homeassistant/components/rainbird/__init__.py +++ b/homeassistant/components/rainbird/__init__.py @@ -3,16 +3,16 @@ import voluptuous as vol -import homeassistant.helpers.config_validation as cv -from homeassistant.components import sensor, binary_sensor +from homeassistant.components import binary_sensor, sensor from homeassistant.components.rainbird.switch import ( - SERVICE_START_IRRIGATION, - SERVICE_SCHEMA_IRRIGATION, ATTR_DURATION, + SERVICE_SCHEMA_IRRIGATION, + SERVICE_START_IRRIGATION, RainBirdSwitch, ) from homeassistant.const import CONF_HOST, CONF_PASSWORD from homeassistant.helpers import discovery +import homeassistant.helpers.config_validation as cv _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/rainbird/binary_sensor.py b/homeassistant/components/rainbird/binary_sensor.py index 90f2861c80ea0..54f49fb13190b 100644 --- a/homeassistant/components/rainbird/binary_sensor.py +++ b/homeassistant/components/rainbird/binary_sensor.py @@ -2,56 +2,40 @@ import logging from homeassistant.components.binary_sensor import BinarySensorDevice -from pyrainbird import RainbirdController -from . import ( - RAINBIRD_CONTROLLER, - SENSOR_TYPES, - SENSOR_TYPE_RAINSENSOR, - SENSOR_TYPE_RAINDELAY, -) +from homeassistant.components.rainbird import sensor +from homeassistant.components.rainbird.sensor import PARENT_SENSOR + +from . import SENSOR_TYPES _LOGGER = logging.getLogger(__name__) def setup_platform(hass, config, add_entities, discovery_info=None): """Set up a Rain Bird sensor.""" - if discovery_info is None or not RAINBIRD_CONTROLLER in discovery_info: + if discovery_info is None or not PARENT_SENSOR in discovery_info: return False - add_entities( - [ - RainBirdSensor(discovery_info[RAINBIRD_CONTROLLER], sensor_type) - for sensor_type in SENSOR_TYPES - ], - True, - ) + add_entities([RainBirdSensor(discovery_info[PARENT_SENSOR])], True) class RainBirdSensor(BinarySensorDevice): """A sensor implementation for Rain Bird device.""" - def __init__(self, controller: RainbirdController, sensor_type): + def __init__(self, parent: sensor.RainbirdSensor): """Initialize the Rain Bird sensor.""" - self._sensor_type = sensor_type - self._controller = controller - self._name = SENSOR_TYPES[self._sensor_type][0] - self._icon = SENSOR_TYPES[self._sensor_type][2] + self._parent = parent + self._name = SENSOR_TYPES[parent._sensor_type][0] + self._icon = SENSOR_TYPES[parent._sensor_type][2] self._state = None @property def is_on(self): """Return true if the binary sensor is on.""" - return None if self._state is None else bool(self._state) + return None if self._parent.state is None else bool(self._parent.state) def update(self): """Get the latest data and updates the states.""" - _LOGGER.debug("Updating sensor: %s", self._name) - state = None - if self._sensor_type == SENSOR_TYPE_RAINSENSOR: - state = self._controller.get_rain_sensor_state() - elif self._sensor_type == SENSOR_TYPE_RAINDELAY: - state = self._controller.get_rain_delay() - self._state = None if state is None else bool(state) + self._parent.update() @property def name(self): diff --git a/homeassistant/components/rainbird/sensor.py b/homeassistant/components/rainbird/sensor.py index 367abf85340b3..b9a16e623ee35 100644 --- a/homeassistant/components/rainbird/sensor.py +++ b/homeassistant/components/rainbird/sensor.py @@ -1,15 +1,22 @@ """Support for Rain Bird Irrigation system LNK WiFi Module.""" import logging -from homeassistant.helpers.entity import Entity from pyrainbird import RainbirdController + +from homeassistant.components import binary_sensor +from homeassistant.helpers import discovery +from homeassistant.helpers.entity import Entity + from . import ( + DOMAIN, RAINBIRD_CONTROLLER, - SENSOR_TYPES, SENSOR_TYPE_RAINDELAY, SENSOR_TYPE_RAINSENSOR, + SENSOR_TYPES, ) +PARENT_SENSOR = "parent_sensor" + _LOGGER = logging.getLogger(__name__) @@ -19,13 +26,22 @@ def setup_platform(hass, config, add_entities, discovery_info=None): if discovery_info is None or not RAINBIRD_CONTROLLER in discovery_info: return False - add_entities( - [ - RainBirdSensor(discovery_info[RAINBIRD_CONTROLLER], sensor_type) - for sensor_type in SENSOR_TYPES - ], - True, - ) + devices = [] + for sensor_type in SENSOR_TYPES: + sensor = RainBirdSensor( + discovery_info[RAINBIRD_CONTROLLER], sensor_type + ) + devices += [sensor] + + discovery.load_platform( + hass, + binary_sensor.DOMAIN, + DOMAIN, + discovered={PARENT_SENSOR: sensor}, + hass_config=config, + ) + + add_entities(devices, True) class RainBirdSensor(Entity): diff --git a/homeassistant/components/rainbird/switch.py b/homeassistant/components/rainbird/switch.py index ff4ffa9b95cb8..748874e0cce60 100644 --- a/homeassistant/components/rainbird/switch.py +++ b/homeassistant/components/rainbird/switch.py @@ -2,6 +2,7 @@ import logging +from pyrainbird import RainbirdController import voluptuous as vol from homeassistant.components.switch import PLATFORM_SCHEMA, SwitchDevice @@ -14,8 +15,8 @@ CONF_ZONE, ) from homeassistant.helpers import config_validation as cv -from pyrainbird import RainbirdController -from . import RAINBIRD_CONTROLLER, DOMAIN + +from . import DOMAIN, RAINBIRD_CONTROLLER _LOGGER = logging.getLogger(__name__) From 457c8a5036b678acb3e3e097bc17d13dcfd31c01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Vran=C3=ADk?= Date: Mon, 9 Sep 2019 13:05:02 +0200 Subject: [PATCH 32/60] version 0.4.0 --- homeassistant/components/rainbird/__init__.py | 2 ++ homeassistant/components/rainbird/manifest.json | 2 +- requirements_all.txt | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/rainbird/__init__.py b/homeassistant/components/rainbird/__init__.py index 3f5c1c7d8a512..668a775de96f5 100644 --- a/homeassistant/components/rainbird/__init__.py +++ b/homeassistant/components/rainbird/__init__.py @@ -17,6 +17,7 @@ _LOGGER = logging.getLogger(__name__) RAINBIRD_CONTROLLER = "rainbird_controller" +DATA_RAINBIRD = "rainbird" DOMAIN = "rainbird" SENSOR_TYPE_RAINDELAY = "raindelay" @@ -50,6 +51,7 @@ def setup(hass, config): from pyrainbird import RainbirdController controller = RainbirdController(server, password) + hass.data[DATA_RAINBIRD] = controller _LOGGER.debug("Rain Bird Controller set to: %s", server) diff --git a/homeassistant/components/rainbird/manifest.json b/homeassistant/components/rainbird/manifest.json index 0e9a4f1a46b0a..830c522a1a471 100644 --- a/homeassistant/components/rainbird/manifest.json +++ b/homeassistant/components/rainbird/manifest.json @@ -3,7 +3,7 @@ "name": "Rainbird", "documentation": "https://www.home-assistant.io/components/rainbird", "requirements": [ - "pyrainbird==0.3.1" + "pyrainbird==0.4.0" ], "dependencies": [], "codeowners": [] diff --git a/requirements_all.txt b/requirements_all.txt index dff163c92d6e0..137fb83e46b4e 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1387,7 +1387,7 @@ pyqwikswitch==0.93 pyrail==0.0.3 # homeassistant.components.rainbird -pyrainbird==0.3.1 +pyrainbird==0.4.0 # homeassistant.components.recswitch pyrecswitch==1.0.2 From f6ccdf06421e189623f1a56a71f7ae1553edd09b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Vran=C3=ADk?= Date: Mon, 9 Sep 2019 17:27:23 +0200 Subject: [PATCH 33/60] new config approach --- homeassistant/components/rainbird/__init__.py | 66 +++++++++++-------- .../components/rainbird/binary_sensor.py | 39 +++++++---- homeassistant/components/rainbird/sensor.py | 8 +-- homeassistant/components/rainbird/switch.py | 53 ++++++++------- 4 files changed, 103 insertions(+), 63 deletions(-) diff --git a/homeassistant/components/rainbird/__init__.py b/homeassistant/components/rainbird/__init__.py index 668a775de96f5..8bbc85b458900 100644 --- a/homeassistant/components/rainbird/__init__.py +++ b/homeassistant/components/rainbird/__init__.py @@ -3,20 +3,20 @@ import voluptuous as vol -from homeassistant.components import binary_sensor, sensor -from homeassistant.components.rainbird.switch import ( - ATTR_DURATION, - SERVICE_SCHEMA_IRRIGATION, - SERVICE_START_IRRIGATION, - RainBirdSwitch, +from homeassistant.components import binary_sensor, sensor, switch +from homeassistant.const import ( + CONF_FRIENDLY_NAME, + CONF_HOST, + CONF_PASSWORD, + CONF_SCAN_INTERVAL, + CONF_TRIGGER_TIME, ) -from homeassistant.const import CONF_HOST, CONF_PASSWORD from homeassistant.helpers import discovery import homeassistant.helpers.config_validation as cv _LOGGER = logging.getLogger(__name__) -RAINBIRD_CONTROLLER = "rainbird_controller" +RAINBIRD_CONTROLLER = "controller" DATA_RAINBIRD = "rainbird" DOMAIN = "rainbird" @@ -28,15 +28,24 @@ SENSOR_TYPE_RAINDELAY: ["Raindelay", None, "mdi:water-off"], } -CONFIG_SCHEMA = vol.Schema( +ZONE_SCHEMA = vol.Schema( { - DOMAIN: vol.Schema( - { - vol.Required(CONF_HOST): cv.string, - vol.Required(CONF_PASSWORD): cv.string, - } - ) - }, + vol.Optional(CONF_FRIENDLY_NAME): cv.string, + vol.Optional(CONF_TRIGGER_TIME): cv.positive_int, + vol.Optional(CONF_SCAN_INTERVAL): cv.positive_int, + } +) +CONTROLLER_SCHEMA = vol.Schema( + { + vol.Required(CONF_HOST): cv.string, + vol.Required(CONF_PASSWORD): cv.string, + vol.Optional(CONF_TRIGGER_TIME): cv.string, + vol.Optional(CONF_SCAN_INTERVAL): cv.string, + vol.Optional("zones"): vol.Schema({cv.positive_int: ZONE_SCHEMA}), + } +) +CONFIG_SCHEMA = vol.Schema( + {DOMAIN: vol.Schema(vol.Any({cv.string: CONTROLLER_SCHEMA}, CONTROLLER_SCHEMA))}, extra=vol.ALLOW_EXTRA, ) @@ -44,24 +53,29 @@ def setup(hass, config): """Set up the Rain Bird component.""" - conf = config[DOMAIN] - server = conf.get(CONF_HOST) - password = conf.get(CONF_PASSWORD) + hass.data[DATA_RAINBIRD] = dict() + if CONF_HOST in config[DOMAIN] and CONF_PASSWORD in config[DOMAIN]: + _setup_controller(config[DOMAIN], "rainbird", hass) + else: + for controller_id in config[DOMAIN]: + _setup_controller(config[DOMAIN][controller_id], controller_id, hass) - from pyrainbird import RainbirdController + return True - controller = RainbirdController(server, password) - hass.data[DATA_RAINBIRD] = controller - _LOGGER.debug("Rain Bird Controller set to: %s", server) +def _setup_controller(config, controller_id, hass): + from pyrainbird import RainbirdController + server = config.get(CONF_HOST) + password = config.get(CONF_PASSWORD) + controller = RainbirdController(server, password) + hass.data[DATA_RAINBIRD][controller_id] = controller + _LOGGER.debug("Rain Bird Controller %s set to: %s", controller_id, server) for platform in [switch.DOMAIN, sensor.DOMAIN, binary_sensor.DOMAIN]: discovery.load_platform( hass, platform, DOMAIN, - discovered={RAINBIRD_CONTROLLER: controller}, + discovered={**{RAINBIRD_CONTROLLER: controller_id}, **config}, hass_config=config, ) - - return True diff --git a/homeassistant/components/rainbird/binary_sensor.py b/homeassistant/components/rainbird/binary_sensor.py index 54f49fb13190b..753f16c61e59c 100644 --- a/homeassistant/components/rainbird/binary_sensor.py +++ b/homeassistant/components/rainbird/binary_sensor.py @@ -1,41 +1,58 @@ """Support for Rain Bird Irrigation system LNK WiFi Module.""" import logging +from pyrainbird import RainbirdController + from homeassistant.components.binary_sensor import BinarySensorDevice -from homeassistant.components.rainbird import sensor -from homeassistant.components.rainbird.sensor import PARENT_SENSOR -from . import SENSOR_TYPES +from . import ( + DATA_RAINBIRD, + RAINBIRD_CONTROLLER, + SENSOR_TYPE_RAINDELAY, + SENSOR_TYPE_RAINSENSOR, + SENSOR_TYPES, +) _LOGGER = logging.getLogger(__name__) def setup_platform(hass, config, add_entities, discovery_info=None): """Set up a Rain Bird sensor.""" - if discovery_info is None or not PARENT_SENSOR in discovery_info: + if discovery_info is None: return False - add_entities([RainBirdSensor(discovery_info[PARENT_SENSOR])], True) + controller = hass.data[DATA_RAINBIRD][discovery_info[RAINBIRD_CONTROLLER]] + + add_entities( + [RainBirdSensor(controller, sensor_type) for sensor_type in SENSOR_TYPES], True + ) class RainBirdSensor(BinarySensorDevice): """A sensor implementation for Rain Bird device.""" - def __init__(self, parent: sensor.RainbirdSensor): + def __init__(self, controller: RainbirdController, sensor_type): """Initialize the Rain Bird sensor.""" - self._parent = parent - self._name = SENSOR_TYPES[parent._sensor_type][0] - self._icon = SENSOR_TYPES[parent._sensor_type][2] + self._sensor_type = sensor_type + self._controller = controller + self._name = SENSOR_TYPES[self._sensor_type][0] + self._icon = SENSOR_TYPES[self._sensor_type][2] self._state = None @property def is_on(self): """Return true if the binary sensor is on.""" - return None if self._parent.state is None else bool(self._parent.state) + return None if self._state is None else bool(self._state) def update(self): """Get the latest data and updates the states.""" - self._parent.update() + _LOGGER.debug("Updating sensor: %s", self._name) + state = None + if self._sensor_type == SENSOR_TYPE_RAINSENSOR: + state = self._controller.get_rain_sensor_state() + elif self._sensor_type == SENSOR_TYPE_RAINDELAY: + state = self._controller.get_rain_delay() + self._state = None if state is None else bool(state) @property def name(self): diff --git a/homeassistant/components/rainbird/sensor.py b/homeassistant/components/rainbird/sensor.py index b9a16e623ee35..59f196858339e 100644 --- a/homeassistant/components/rainbird/sensor.py +++ b/homeassistant/components/rainbird/sensor.py @@ -8,6 +8,7 @@ from homeassistant.helpers.entity import Entity from . import ( + DATA_RAINBIRD, DOMAIN, RAINBIRD_CONTROLLER, SENSOR_TYPE_RAINDELAY, @@ -23,14 +24,13 @@ def setup_platform(hass, config, add_entities, discovery_info=None): """Set up a Rain Bird sensor.""" - if discovery_info is None or not RAINBIRD_CONTROLLER in discovery_info: + if discovery_info is None: return False + controller = hass.data[DATA_RAINBIRD][discovery_info[RAINBIRD_CONTROLLER]] devices = [] for sensor_type in SENSOR_TYPES: - sensor = RainBirdSensor( - discovery_info[RAINBIRD_CONTROLLER], sensor_type - ) + sensor = RainBirdSensor(controller, sensor_type) devices += [sensor] discovery.load_platform( diff --git a/homeassistant/components/rainbird/switch.py b/homeassistant/components/rainbird/switch.py index 748874e0cce60..595851f5e87ee 100644 --- a/homeassistant/components/rainbird/switch.py +++ b/homeassistant/components/rainbird/switch.py @@ -2,7 +2,7 @@ import logging -from pyrainbird import RainbirdController +from pyrainbird import AvailableStations, RainbirdController import voluptuous as vol from homeassistant.components.switch import PLATFORM_SCHEMA, SwitchDevice @@ -10,13 +10,12 @@ ATTR_ENTITY_ID, CONF_FRIENDLY_NAME, CONF_SCAN_INTERVAL, - CONF_SWITCHES, CONF_TRIGGER_TIME, CONF_ZONE, ) from homeassistant.helpers import config_validation as cv -from . import DOMAIN, RAINBIRD_CONTROLLER +from . import DATA_RAINBIRD, DOMAIN, RAINBIRD_CONTROLLER _LOGGER = logging.getLogger(__name__) @@ -26,25 +25,18 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( { - vol.Required(CONF_SWITCHES, default={}): vol.Schema( - { - cv.string: { - vol.Optional(CONF_FRIENDLY_NAME): cv.string, - vol.Required(CONF_ZONE): cv.string, - vol.Required(CONF_TRIGGER_TIME): cv.string, - vol.Optional(CONF_SCAN_INTERVAL): cv.string, - } - } - ) + vol.Required(RAINBIRD_CONTROLLER): cv.string, + vol.Required(CONF_ZONE): cv.string, + vol.Optional(CONF_FRIENDLY_NAME): cv.string, + vol.Optional(CONF_TRIGGER_TIME): cv.string, + vol.Optional(CONF_SCAN_INTERVAL): cv.string, } ) 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) - ), + vol.Required(ATTR_DURATION): vol.All(vol.Coerce(float), vol.Range(min=0)), } ) @@ -52,13 +44,30 @@ 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 or not RAINBIRD_CONTROLLER in discovery_info: + if discovery_info is None: return False - devices = [ - RainBirdSwitch(discovery_info[RAINBIRD_CONTROLLER], switch) - for switch in config.get(CONF_SWITCHES).values() + controller: RainbirdController = hass.data[DATA_RAINBIRD][ + discovery_info[RAINBIRD_CONTROLLER] ] + available_stations: AvailableStations = controller.get_available_stations() + devices = [] + for i in range(1, available_stations.stations.count + 1): + if available_stations.stations.active(i): + time = discovery_info.get("zones", {}).get( + CONF_TRIGGER_TIME, discovery_info.get(CONF_TRIGGER_TIME, 0) + ) + name = discovery_info.get("zones", {}).get(CONF_FRIENDLY_NAME) + if time: + devices.append(RainBirdSwitch(controller, i, time, name=name)) + else: + logging.warning( + "No delay configured for zone {0:d}, controller {1:s}. " + "Not adding sprinklers for zone {0:d}.".format( + i, discovery_info[RAINBIRD_CONTROLLER] + ) + ) + add_entities(devices, True) def _start_irrigation(service): @@ -80,13 +89,13 @@ def _start_irrigation(service): class RainBirdSwitch(SwitchDevice): """Representation of a Rain Bird switch.""" - def __init__(self, rb: RainbirdController, dev): + def __init__(self, controller: RainbirdController, zone, time, name=None): """Initialize a Rain Bird Switch Device.""" self._rainbird = rb self._zone = int(dev.get(CONF_ZONE)) self._name = dev.get(CONF_FRIENDLY_NAME, f"Sprinkler {self._zone}") self._state = None - self._duration = dev.get(CONF_TRIGGER_TIME) + self._duration = time self._attributes = {"duration": self._duration, "zone": self._zone} @property From 05127ec11bf623970f015695823665d7d4fabe80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Vran=C3=ADk?= Date: Mon, 9 Sep 2019 17:34:22 +0200 Subject: [PATCH 34/60] sensors cleanup --- .../components/rainbird/binary_sensor.py | 1 - homeassistant/components/rainbird/sensor.py | 20 +++---------------- 2 files changed, 3 insertions(+), 18 deletions(-) diff --git a/homeassistant/components/rainbird/binary_sensor.py b/homeassistant/components/rainbird/binary_sensor.py index 753f16c61e59c..5fad4c81c7782 100644 --- a/homeassistant/components/rainbird/binary_sensor.py +++ b/homeassistant/components/rainbird/binary_sensor.py @@ -22,7 +22,6 @@ def setup_platform(hass, config, add_entities, discovery_info=None): return False controller = hass.data[DATA_RAINBIRD][discovery_info[RAINBIRD_CONTROLLER]] - add_entities( [RainBirdSensor(controller, sensor_type) for sensor_type in SENSOR_TYPES], True ) diff --git a/homeassistant/components/rainbird/sensor.py b/homeassistant/components/rainbird/sensor.py index 59f196858339e..6575343bfa06d 100644 --- a/homeassistant/components/rainbird/sensor.py +++ b/homeassistant/components/rainbird/sensor.py @@ -3,13 +3,10 @@ from pyrainbird import RainbirdController -from homeassistant.components import binary_sensor -from homeassistant.helpers import discovery from homeassistant.helpers.entity import Entity from . import ( DATA_RAINBIRD, - DOMAIN, RAINBIRD_CONTROLLER, SENSOR_TYPE_RAINDELAY, SENSOR_TYPE_RAINSENSOR, @@ -28,20 +25,9 @@ def setup_platform(hass, config, add_entities, discovery_info=None): return False controller = hass.data[DATA_RAINBIRD][discovery_info[RAINBIRD_CONTROLLER]] - devices = [] - for sensor_type in SENSOR_TYPES: - sensor = RainBirdSensor(controller, sensor_type) - devices += [sensor] - - discovery.load_platform( - hass, - binary_sensor.DOMAIN, - DOMAIN, - discovered={PARENT_SENSOR: sensor}, - hass_config=config, - ) - - add_entities(devices, True) + add_entities( + [RainBirdSensor(controller, sensor_type) for sensor_type in SENSOR_TYPES], True + ) class RainBirdSensor(Entity): From 7d0e9e79337abfe161a4df3c777084e4857b7c26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Vran=C3=ADk?= Date: Mon, 9 Sep 2019 17:37:30 +0200 Subject: [PATCH 35/60] bypass if no zones found --- homeassistant/components/rainbird/switch.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/homeassistant/components/rainbird/switch.py b/homeassistant/components/rainbird/switch.py index 595851f5e87ee..fd741f6cfe887 100644 --- a/homeassistant/components/rainbird/switch.py +++ b/homeassistant/components/rainbird/switch.py @@ -51,6 +51,8 @@ def setup_platform(hass, config, add_entities, discovery_info=None): discovery_info[RAINBIRD_CONTROLLER] ] available_stations: AvailableStations = controller.get_available_stations() + if not (available_stations and available_stations.stations): + return False devices = [] for i in range(1, available_stations.stations.count + 1): if available_stations.stations.active(i): From a3e12fbdfde82bd024e06e4976a883f73e591356 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Vran=C3=ADk?= Date: Mon, 9 Sep 2019 17:44:38 +0200 Subject: [PATCH 36/60] platform schema removed --- homeassistant/components/rainbird/switch.py | 23 +++------------------ 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/homeassistant/components/rainbird/switch.py b/homeassistant/components/rainbird/switch.py index fd741f6cfe887..7e87250ec9e43 100644 --- a/homeassistant/components/rainbird/switch.py +++ b/homeassistant/components/rainbird/switch.py @@ -2,19 +2,12 @@ import logging -from pyrainbird import AvailableStations, RainbirdController import voluptuous as vol -from homeassistant.components.switch import PLATFORM_SCHEMA, SwitchDevice -from homeassistant.const import ( - ATTR_ENTITY_ID, - CONF_FRIENDLY_NAME, - CONF_SCAN_INTERVAL, - CONF_TRIGGER_TIME, - CONF_ZONE, -) +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 pyrainbird import AvailableStations, RainbirdController from . import DATA_RAINBIRD, DOMAIN, RAINBIRD_CONTROLLER _LOGGER = logging.getLogger(__name__) @@ -23,16 +16,6 @@ SERVICE_START_IRRIGATION = "start_irrigation" -PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( - { - vol.Required(RAINBIRD_CONTROLLER): cv.string, - vol.Required(CONF_ZONE): cv.string, - vol.Optional(CONF_FRIENDLY_NAME): cv.string, - vol.Optional(CONF_TRIGGER_TIME): cv.string, - vol.Optional(CONF_SCAN_INTERVAL): cv.string, - } -) - SERVICE_SCHEMA_IRRIGATION = vol.Schema( { vol.Required(ATTR_ENTITY_ID): cv.entity_id, From a9b90bc8f7bce27d865b32ba53e8f405a4175c1f Mon Sep 17 00:00:00 2001 From: konikvranik Date: Mon, 9 Sep 2019 19:36:17 +0200 Subject: [PATCH 37/60] 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 --- homeassistant/components/rainbird/__init__.py | 25 ++++++++--------- homeassistant/components/rainbird/switch.py | 27 ++++++++++--------- 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/homeassistant/components/rainbird/__init__.py b/homeassistant/components/rainbird/__init__.py index 8bbc85b458900..5ed84b0b5e379 100644 --- a/homeassistant/components/rainbird/__init__.py +++ b/homeassistant/components/rainbird/__init__.py @@ -45,7 +45,7 @@ } ) CONFIG_SCHEMA = vol.Schema( - {DOMAIN: vol.Schema(vol.Any({cv.string: CONTROLLER_SCHEMA}, CONTROLLER_SCHEMA))}, + {DOMAIN: vol.Schema(vol.Any(cv.ensure_list(CONTROLLER_SCHEMA), CONTROLLER_SCHEMA))}, extra=vol.ALLOW_EXTRA, ) @@ -53,29 +53,30 @@ def setup(hass, config): """Set up the Rain Bird component.""" - hass.data[DATA_RAINBIRD] = dict() - if CONF_HOST in config[DOMAIN] and CONF_PASSWORD in config[DOMAIN]: - _setup_controller(config[DOMAIN], "rainbird", hass) + hass.data[DATA_RAINBIRD] = list() + if isinstance(config[DOMAIN], list): + for controller_config in config[DOMAIN]: + _setup_controller(controller_config, hass) else: - for controller_id in config[DOMAIN]: - _setup_controller(config[DOMAIN][controller_id], controller_id, hass) + _setup_controller(config[DOMAIN], hass) return True -def _setup_controller(config, controller_id, hass): +def _setup_controller(config, hass): from pyrainbird import RainbirdController - server = config.get(CONF_HOST) - password = config.get(CONF_PASSWORD) + server = config[CONF_HOST] + password = config[CONF_PASSWORD] controller = RainbirdController(server, password) - hass.data[DATA_RAINBIRD][controller_id] = controller - _LOGGER.debug("Rain Bird Controller %s set to: %s", controller_id, server) + position = len(hass.data[DATA_RAINBIRD]) + hass.data[DATA_RAINBIRD].append(controller) + _LOGGER.debug("Rain Bird Controller %d set to: %s", position, server) for platform in [switch.DOMAIN, sensor.DOMAIN, binary_sensor.DOMAIN]: discovery.load_platform( hass, platform, DOMAIN, - discovered={**{RAINBIRD_CONTROLLER: controller_id}, **config}, + discovered={**{RAINBIRD_CONTROLLER: position}, **config}, hass_config=config, ) diff --git a/homeassistant/components/rainbird/switch.py b/homeassistant/components/rainbird/switch.py index 7e87250ec9e43..f81cea33c540b 100644 --- a/homeassistant/components/rainbird/switch.py +++ b/homeassistant/components/rainbird/switch.py @@ -2,12 +2,13 @@ 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 pyrainbird import AvailableStations, RainbirdController + from . import DATA_RAINBIRD, DOMAIN, RAINBIRD_CONTROLLER _LOGGER = logging.getLogger(__name__) @@ -28,14 +29,14 @@ 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 False + 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 False + return devices = [] for i in range(1, available_stations.stations.count + 1): if available_stations.stations.active(i): @@ -44,7 +45,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None): ) name = discovery_info.get("zones", {}).get(CONF_FRIENDLY_NAME) if time: - devices.append(RainBirdSwitch(controller, i, time, name=name)) + devices.append(RainBirdSwitch(controller, i, time, name)) else: logging.warning( "No delay configured for zone {0:d}, controller {1:s}. " @@ -56,12 +57,12 @@ def setup_platform(hass, config, add_entities, discovery_info=None): add_entities(devices, True) def _start_irrigation(service): - entity_id = service.data.get(ATTR_ENTITY_ID) - duration = service.data.get(ATTR_DURATION) + entity_id = service.data[ATTR_ENTITY_ID] + duration = service.data[ATTR_DURATION] - for d in devices: - if d.entity_id == entity_id: - d.turn_on(duration=duration) + for device in devices: + if device.entity_id == entity_id: + device.turn_on(duration=duration) hass.services.register( DOMAIN, @@ -74,14 +75,14 @@ def _start_irrigation(service): class RainBirdSwitch(SwitchDevice): """Representation of a Rain Bird switch.""" - def __init__(self, controller: RainbirdController, zone, time, name=None): + def __init__(self, controller: RainbirdController, zone, time, name): """Initialize a Rain Bird Switch Device.""" self._rainbird = rb self._zone = int(dev.get(CONF_ZONE)) self._name = dev.get(CONF_FRIENDLY_NAME, f"Sprinkler {self._zone}") self._state = None self._duration = time - self._attributes = {"duration": self._duration, "zone": self._zone} + self._attributes = {ATTR_DURATION: self._duration, "zone": self._zone} @property def device_state_attributes(self): @@ -97,7 +98,7 @@ def turn_on(self, **kwargs): """Turn the switch on.""" if self._rainbird.irrigate_zone( int(self._zone), - kwargs["duration"] if "duration" in kwargs else self._duration, + int(kwargs[ATTR_DURATION] if ATTR_DURATION in kwargs else self._duration), ): self._state = True @@ -108,7 +109,7 @@ def turn_off(self, **kwargs): def update(self): """Update switch status.""" - self._state = self._rainbird.zone_state(self._zone) + self._state = self._rainbird.get_zone_state(self._zone) @property def is_on(self): From b5bbce5b4fdca72b6f9ccf361ae23fede0363a91 Mon Sep 17 00:00:00 2001 From: konikvranik Date: Mon, 9 Sep 2019 19:46:48 +0200 Subject: [PATCH 38/60] some small code improvements as suggested in CR: - supported platforms in constant - just return instead of return False - removed unused constant --- homeassistant/components/rainbird/__init__.py | 4 +++- homeassistant/components/rainbird/binary_sensor.py | 2 +- homeassistant/components/rainbird/sensor.py | 4 +--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/rainbird/__init__.py b/homeassistant/components/rainbird/__init__.py index 5ed84b0b5e379..931145da6efac 100644 --- a/homeassistant/components/rainbird/__init__.py +++ b/homeassistant/components/rainbird/__init__.py @@ -14,6 +14,8 @@ from homeassistant.helpers import discovery import homeassistant.helpers.config_validation as cv +SUPPORTED_PLATFORMS = [switch.DOMAIN, sensor.DOMAIN, binary_sensor.DOMAIN] + _LOGGER = logging.getLogger(__name__) RAINBIRD_CONTROLLER = "controller" @@ -72,7 +74,7 @@ def _setup_controller(config, hass): position = len(hass.data[DATA_RAINBIRD]) hass.data[DATA_RAINBIRD].append(controller) _LOGGER.debug("Rain Bird Controller %d set to: %s", position, server) - for platform in [switch.DOMAIN, sensor.DOMAIN, binary_sensor.DOMAIN]: + for platform in SUPPORTED_PLATFORMS: discovery.load_platform( hass, platform, diff --git a/homeassistant/components/rainbird/binary_sensor.py b/homeassistant/components/rainbird/binary_sensor.py index 5fad4c81c7782..51c5f7a9dbefe 100644 --- a/homeassistant/components/rainbird/binary_sensor.py +++ b/homeassistant/components/rainbird/binary_sensor.py @@ -19,7 +19,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None): """Set up a Rain Bird sensor.""" if discovery_info is None: - return False + return controller = hass.data[DATA_RAINBIRD][discovery_info[RAINBIRD_CONTROLLER]] add_entities( diff --git a/homeassistant/components/rainbird/sensor.py b/homeassistant/components/rainbird/sensor.py index 6575343bfa06d..501566de6823b 100644 --- a/homeassistant/components/rainbird/sensor.py +++ b/homeassistant/components/rainbird/sensor.py @@ -13,8 +13,6 @@ SENSOR_TYPES, ) -PARENT_SENSOR = "parent_sensor" - _LOGGER = logging.getLogger(__name__) @@ -22,7 +20,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None): """Set up a Rain Bird sensor.""" if discovery_info is None: - return False + return controller = hass.data[DATA_RAINBIRD][discovery_info[RAINBIRD_CONTROLLER]] add_entities( From 49d4bd2c71ae6cf441ee0d55ba43875a3563f304 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Vran=C3=ADk?= Date: Mon, 9 Sep 2019 21:08:00 +0200 Subject: [PATCH 39/60] No single controller configuration Co-Authored-By: Martin Hjelmare --- homeassistant/components/rainbird/__init__.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/rainbird/__init__.py b/homeassistant/components/rainbird/__init__.py index 931145da6efac..2d769de82ed81 100644 --- a/homeassistant/components/rainbird/__init__.py +++ b/homeassistant/components/rainbird/__init__.py @@ -47,7 +47,7 @@ } ) CONFIG_SCHEMA = vol.Schema( - {DOMAIN: vol.Schema(vol.Any(cv.ensure_list(CONTROLLER_SCHEMA), CONTROLLER_SCHEMA))}, + {DOMAIN: vol.Schema(vol.All(cv.ensure_list, [CONTROLLER_SCHEMA]))}, extra=vol.ALLOW_EXTRA, ) @@ -55,12 +55,9 @@ def setup(hass, config): """Set up the Rain Bird component.""" - hass.data[DATA_RAINBIRD] = list() - if isinstance(config[DOMAIN], list): - for controller_config in config[DOMAIN]: - _setup_controller(controller_config, hass) - else: - _setup_controller(config[DOMAIN], hass) + hass.data[DATA_RAINBIRD] = [] + for controller_config in config[DOMAIN]: + _setup_controller(controller_config, hass) return True From 11153f68276bc2517bf7c2ba467d832745bda458 Mon Sep 17 00:00:00 2001 From: konikvranik Date: Tue, 10 Sep 2019 09:05:34 +0200 Subject: [PATCH 40/60] pyrainbird 0.4.1 --- homeassistant/components/rainbird/manifest.json | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/rainbird/manifest.json b/homeassistant/components/rainbird/manifest.json index 830c522a1a471..f2055be2c164d 100644 --- a/homeassistant/components/rainbird/manifest.json +++ b/homeassistant/components/rainbird/manifest.json @@ -3,7 +3,7 @@ "name": "Rainbird", "documentation": "https://www.home-assistant.io/components/rainbird", "requirements": [ - "pyrainbird==0.4.0" + "pyrainbird==0.4.1" ], "dependencies": [], "codeowners": [] diff --git a/requirements_all.txt b/requirements_all.txt index 137fb83e46b4e..88a65528f156b 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1387,7 +1387,7 @@ pyqwikswitch==0.93 pyrail==0.0.3 # homeassistant.components.rainbird -pyrainbird==0.4.0 +pyrainbird==0.4.1 # homeassistant.components.recswitch pyrecswitch==1.0.2 From f1efbd75ad5a67b02819b2b354e019af095f52bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Vran=C3=ADk?= Date: Tue, 10 Sep 2019 10:24:04 +0200 Subject: [PATCH 41/60] individual switch configuration --- homeassistant/components/rainbird/switch.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/rainbird/switch.py b/homeassistant/components/rainbird/switch.py index f81cea33c540b..88db6acb1ba2c 100644 --- a/homeassistant/components/rainbird/switch.py +++ b/homeassistant/components/rainbird/switch.py @@ -2,13 +2,12 @@ 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 pyrainbird import AvailableStations, RainbirdController from . import DATA_RAINBIRD, DOMAIN, RAINBIRD_CONTROLLER _LOGGER = logging.getLogger(__name__) @@ -40,10 +39,11 @@ def setup_platform(hass, config, add_entities, discovery_info=None): devices = [] for i in range(1, available_stations.stations.count + 1): if available_stations.stations.active(i): - time = discovery_info.get("zones", {}).get( + zone_config = discovery_info.get("zones", {}).get(i, {}) + time = zone_config.get( CONF_TRIGGER_TIME, discovery_info.get(CONF_TRIGGER_TIME, 0) ) - name = discovery_info.get("zones", {}).get(CONF_FRIENDLY_NAME) + name = zone_config.get(CONF_FRIENDLY_NAME) if time: devices.append(RainBirdSwitch(controller, i, time, name)) else: From 15a218df44b1141d8e2149579fdcfbe64679dfd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Vran=C3=ADk?= Date: Tue, 10 Sep 2019 11:27:35 +0200 Subject: [PATCH 42/60] imports order --- homeassistant/components/rainbird/switch.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/rainbird/switch.py b/homeassistant/components/rainbird/switch.py index 88db6acb1ba2c..7d7a16b9a39f1 100644 --- a/homeassistant/components/rainbird/switch.py +++ b/homeassistant/components/rainbird/switch.py @@ -2,12 +2,13 @@ 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 pyrainbird import AvailableStations, RainbirdController + from . import DATA_RAINBIRD, DOMAIN, RAINBIRD_CONTROLLER _LOGGER = logging.getLogger(__name__) From 0b4ad97adca17952e65ff6d3a3ef9ebc539de033 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Vran=C3=ADk?= Date: Tue, 10 Sep 2019 15:26:27 +0200 Subject: [PATCH 43/60] generate default name out of entity --- homeassistant/components/rainbird/switch.py | 23 ++++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/homeassistant/components/rainbird/switch.py b/homeassistant/components/rainbird/switch.py index 7d7a16b9a39f1..15194e9489d03 100644 --- a/homeassistant/components/rainbird/switch.py +++ b/homeassistant/components/rainbird/switch.py @@ -38,20 +38,27 @@ def setup_platform(hass, config, add_entities, discovery_info=None): if not (available_stations and available_stations.stations): return devices = [] - for i in range(1, available_stations.stations.count + 1): - if available_stations.stations.active(i): - zone_config = discovery_info.get("zones", {}).get(i, {}) + for zone in range(1, available_stations.stations.count + 1): + if available_stations.stations.active(zone): + zone_config = discovery_info.get("zones", {}).get(zone, {}) time = zone_config.get( CONF_TRIGGER_TIME, discovery_info.get(CONF_TRIGGER_TIME, 0) ) name = zone_config.get(CONF_FRIENDLY_NAME) if time: - devices.append(RainBirdSwitch(controller, i, time, name)) + devices.append( + RainBirdSwitch( + controller, + zone, + time, + name if name else "Sprinkler {}".format(zone), + ) + ) else: logging.warning( "No delay configured for zone {0:d}, controller {1:s}. " "Not adding sprinklers for zone {0:d}.".format( - i, discovery_info[RAINBIRD_CONTROLLER] + zone, discovery_info[RAINBIRD_CONTROLLER] ) ) @@ -78,9 +85,9 @@ class RainBirdSwitch(SwitchDevice): def __init__(self, controller: RainbirdController, zone, time, name): """Initialize a Rain Bird Switch Device.""" - self._rainbird = rb - self._zone = int(dev.get(CONF_ZONE)) - self._name = dev.get(CONF_FRIENDLY_NAME, f"Sprinkler {self._zone}") + self._rainbird = controller + self._zone = zone + self._name = name self._state = None self._duration = time self._attributes = {ATTR_DURATION: self._duration, "zone": self._zone} From 96974c4584e4c56441807495d8cef59fae55f117 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Vran=C3=ADk?= Date: Thu, 12 Sep 2019 11:12:36 +0200 Subject: [PATCH 44/60] trigger time required for controller --- homeassistant/components/rainbird/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/rainbird/__init__.py b/homeassistant/components/rainbird/__init__.py index 2d769de82ed81..e541cd1c66d16 100644 --- a/homeassistant/components/rainbird/__init__.py +++ b/homeassistant/components/rainbird/__init__.py @@ -41,7 +41,7 @@ { vol.Required(CONF_HOST): cv.string, vol.Required(CONF_PASSWORD): cv.string, - vol.Optional(CONF_TRIGGER_TIME): cv.string, + vol.Required(CONF_TRIGGER_TIME): cv.string, vol.Optional(CONF_SCAN_INTERVAL): cv.string, vol.Optional("zones"): vol.Schema({cv.positive_int: ZONE_SCHEMA}), } From 322dba122de2f730d4151366cf6e2be8366ea37d Mon Sep 17 00:00:00 2001 From: konikvranik Date: Wed, 18 Sep 2019 21:50:17 +0200 Subject: [PATCH 45/60] 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 --- homeassistant/components/rainbird/__init__.py | 41 +++++++++++-------- .../components/rainbird/services.yaml | 2 +- homeassistant/components/rainbird/switch.py | 25 +++++------ 3 files changed, 38 insertions(+), 30 deletions(-) diff --git a/homeassistant/components/rainbird/__init__.py b/homeassistant/components/rainbird/__init__.py index e541cd1c66d16..1e80c0d2f7642 100644 --- a/homeassistant/components/rainbird/__init__.py +++ b/homeassistant/components/rainbird/__init__.py @@ -8,12 +8,13 @@ CONF_FRIENDLY_NAME, CONF_HOST, CONF_PASSWORD, - CONF_SCAN_INTERVAL, CONF_TRIGGER_TIME, ) from homeassistant.helpers import discovery import homeassistant.helpers.config_validation as cv +CONF_ZONES = "zones" + SUPPORTED_PLATFORMS = [switch.DOMAIN, sensor.DOMAIN, binary_sensor.DOMAIN] _LOGGER = logging.getLogger(__name__) @@ -34,7 +35,6 @@ { vol.Optional(CONF_FRIENDLY_NAME): cv.string, vol.Optional(CONF_TRIGGER_TIME): cv.positive_int, - vol.Optional(CONF_SCAN_INTERVAL): cv.positive_int, } ) CONTROLLER_SCHEMA = vol.Schema( @@ -42,8 +42,7 @@ vol.Required(CONF_HOST): cv.string, vol.Required(CONF_PASSWORD): cv.string, vol.Required(CONF_TRIGGER_TIME): cv.string, - vol.Optional(CONF_SCAN_INTERVAL): cv.string, - vol.Optional("zones"): vol.Schema({cv.positive_int: ZONE_SCHEMA}), + vol.Optional(CONF_ZONES): vol.Schema({cv.positive_int: ZONE_SCHEMA}), } ) CONFIG_SCHEMA = vol.Schema( @@ -56,26 +55,34 @@ def setup(hass, config): """Set up the Rain Bird component.""" hass.data[DATA_RAINBIRD] = [] + success = False for controller_config in config[DOMAIN]: - _setup_controller(controller_config, hass) + success = success or _setup_controller(hass, controller_config) - return True + return success -def _setup_controller(config, hass): +def _setup_controller(hass, config): from pyrainbird import RainbirdController server = config[CONF_HOST] password = config[CONF_PASSWORD] controller = RainbirdController(server, password) position = len(hass.data[DATA_RAINBIRD]) - hass.data[DATA_RAINBIRD].append(controller) - _LOGGER.debug("Rain Bird Controller %d set to: %s", position, server) - for platform in SUPPORTED_PLATFORMS: - discovery.load_platform( - hass, - platform, - DOMAIN, - discovered={**{RAINBIRD_CONTROLLER: position}, **config}, - hass_config=config, - ) + success = False + try: + controller.get_serial_number() + hass.data[DATA_RAINBIRD].append(controller) + _LOGGER.debug("Rain Bird Controller %d set to: %s", position, server) + for platform in SUPPORTED_PLATFORMS: + discovery.load_platform( + hass, + platform, + DOMAIN, + discovered={**{RAINBIRD_CONTROLLER: position}, **config}, + hass_config=config, + ) + success = True + except Exception as e: + logging.error("Unable to setup controller", e) + return success diff --git a/homeassistant/components/rainbird/services.yaml b/homeassistant/components/rainbird/services.yaml index 3ed79b2a9cbf6..cdac7171a25c8 100644 --- a/homeassistant/components/rainbird/services.yaml +++ b/homeassistant/components/rainbird/services.yaml @@ -6,4 +6,4 @@ start_irrigation: example: 'switch.sprinkler_1' duration: description: Duration for this sprinkler to be turned on - example: 1 \ No newline at end of file + example: 1 diff --git a/homeassistant/components/rainbird/switch.py b/homeassistant/components/rainbird/switch.py index 15194e9489d03..2a39c3c9e66ed 100644 --- a/homeassistant/components/rainbird/switch.py +++ b/homeassistant/components/rainbird/switch.py @@ -45,26 +45,27 @@ def setup_platform(hass, config, add_entities, discovery_info=None): CONF_TRIGGER_TIME, discovery_info.get(CONF_TRIGGER_TIME, 0) ) name = zone_config.get(CONF_FRIENDLY_NAME) - if time: - devices.append( - RainBirdSwitch( - controller, - zone, - time, - name if name else "Sprinkler {}".format(zone), - ) - ) - else: + if not time: logging.warning( "No delay configured for zone {0:d}, controller {1:s}. " "Not adding sprinklers for zone {0:d}.".format( zone, discovery_info[RAINBIRD_CONTROLLER] ) ) + continue + + devices.append( + RainBirdSwitch( + controller, + zone, + time, + name if name else "Sprinkler {}".format(zone), + ) + ) add_entities(devices, True) - def _start_irrigation(service): + def start_irrigation(service): entity_id = service.data[ATTR_ENTITY_ID] duration = service.data[ATTR_DURATION] @@ -75,7 +76,7 @@ def _start_irrigation(service): hass.services.register( DOMAIN, SERVICE_START_IRRIGATION, - _start_irrigation, + start_irrigation, schema=SERVICE_SCHEMA_IRRIGATION, ) From 2343c6cc5e748cd3546fa3e9948f172de149083c Mon Sep 17 00:00:00 2001 From: konikvranik Date: Wed, 18 Sep 2019 21:55:04 +0200 Subject: [PATCH 46/60] import of library on top --- homeassistant/components/rainbird/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/rainbird/__init__.py b/homeassistant/components/rainbird/__init__.py index 1e80c0d2f7642..3be41495609d0 100644 --- a/homeassistant/components/rainbird/__init__.py +++ b/homeassistant/components/rainbird/__init__.py @@ -1,6 +1,7 @@ """Support for Rain Bird Irrigation system LNK WiFi Module.""" import logging +from pyrainbird import RainbirdController import voluptuous as vol from homeassistant.components import binary_sensor, sensor, switch @@ -63,7 +64,6 @@ def setup(hass, config): def _setup_controller(hass, config): - from pyrainbird import RainbirdController server = config[CONF_HOST] password = config[CONF_PASSWORD] From f1c4df4ec1315d9dea2171c698d3718a9d0569cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Vran=C3=ADk?= Date: Thu, 19 Sep 2019 13:46:43 +0200 Subject: [PATCH 47/60] refactored --- homeassistant/components/rainbird/__init__.py | 37 +++++++++---------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/homeassistant/components/rainbird/__init__.py b/homeassistant/components/rainbird/__init__.py index 3be41495609d0..86f9012152477 100644 --- a/homeassistant/components/rainbird/__init__.py +++ b/homeassistant/components/rainbird/__init__.py @@ -63,26 +63,25 @@ def setup(hass, config): return success -def _setup_controller(hass, config): - - server = config[CONF_HOST] - password = config[CONF_PASSWORD] +def _setup_controller(hass, controller_config, config): + """Set up a controller.""" + server = controller_config[CONF_HOST] + password = controller_config[CONF_PASSWORD] controller = RainbirdController(server, password) position = len(hass.data[DATA_RAINBIRD]) - success = False try: controller.get_serial_number() - hass.data[DATA_RAINBIRD].append(controller) - _LOGGER.debug("Rain Bird Controller %d set to: %s", position, server) - for platform in SUPPORTED_PLATFORMS: - discovery.load_platform( - hass, - platform, - DOMAIN, - discovered={**{RAINBIRD_CONTROLLER: position}, **config}, - hass_config=config, - ) - success = True - except Exception as e: - logging.error("Unable to setup controller", e) - return success + except Exception as exc: + _LOGGER.error("Unable to setup controller: %s", exc) + return False + hass.data[DATA_RAINBIRD].append(controller) + _LOGGER.debug("Rain Bird Controller %d set to: %s", position, server) + for platform in SUPPORTED_PLATFORMS: + discovery.load_platform( + hass, + platform, + DOMAIN, + {RAINBIRD_CONTROLLER: position, **controller_config}, + config, + ) + return True From b26f5cd0f15b1c20f10d41e0391b3d291308c513 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Vran=C3=ADk?= Date: Thu, 19 Sep 2019 14:05:01 +0200 Subject: [PATCH 48/60] Update homeassistant/components/rainbird/__init__.py Co-Authored-By: Martin Hjelmare --- homeassistant/components/rainbird/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/rainbird/__init__.py b/homeassistant/components/rainbird/__init__.py index 86f9012152477..90c5768eb84d1 100644 --- a/homeassistant/components/rainbird/__init__.py +++ b/homeassistant/components/rainbird/__init__.py @@ -58,7 +58,7 @@ def setup(hass, config): hass.data[DATA_RAINBIRD] = [] success = False for controller_config in config[DOMAIN]: - success = success or _setup_controller(hass, controller_config) + success = success or _setup_controller(hass, controller_config, config) return success From 4abc751065f8061072a8e1c14d46e5ca73e00291 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Vran=C3=ADk?= Date: Thu, 19 Sep 2019 14:55:07 +0200 Subject: [PATCH 49/60] validate time and set defaults --- homeassistant/components/rainbird/__init__.py | 25 +++++++++++++++---- homeassistant/components/rainbird/switch.py | 13 +--------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/homeassistant/components/rainbird/__init__.py b/homeassistant/components/rainbird/__init__.py index 90c5768eb84d1..e9df9c5758dba 100644 --- a/homeassistant/components/rainbird/__init__.py +++ b/homeassistant/components/rainbird/__init__.py @@ -1,4 +1,5 @@ """Support for Rain Bird Irrigation system LNK WiFi Module.""" +import copy import logging from pyrainbird import RainbirdController @@ -32,17 +33,31 @@ SENSOR_TYPE_RAINDELAY: ["Raindelay", None, "mdi:water-off"], } +TRIGGER_TIME_SCHEMA = vol.All(cv.time_period, cv.positive_timedelta) + + +def _validator(config): + config = copy.deepcopy(config) + for zone, value in config[CONF_ZONES]: + if not value[CONF_TRIGGER_TIME]: + value[CONF_TRIGGER_TIME] = config[CONF_TRIGGER_TIME] + return config + + ZONE_SCHEMA = vol.Schema( - { - vol.Optional(CONF_FRIENDLY_NAME): cv.string, - vol.Optional(CONF_TRIGGER_TIME): cv.positive_int, - } + vol.All( + { + vol.Optional(CONF_FRIENDLY_NAME): cv.string, + vol.Optional(CONF_TRIGGER_TIME): TRIGGER_TIME_SCHEMA, + }, + _validator, + ) ) CONTROLLER_SCHEMA = vol.Schema( { vol.Required(CONF_HOST): cv.string, vol.Required(CONF_PASSWORD): cv.string, - vol.Required(CONF_TRIGGER_TIME): cv.string, + vol.Required(CONF_TRIGGER_TIME): TRIGGER_TIME_SCHEMA, vol.Optional(CONF_ZONES): vol.Schema({cv.positive_int: ZONE_SCHEMA}), } ) diff --git a/homeassistant/components/rainbird/switch.py b/homeassistant/components/rainbird/switch.py index 2a39c3c9e66ed..6080378421af7 100644 --- a/homeassistant/components/rainbird/switch.py +++ b/homeassistant/components/rainbird/switch.py @@ -41,19 +41,8 @@ def setup_platform(hass, config, add_entities, discovery_info=None): for zone in range(1, available_stations.stations.count + 1): if available_stations.stations.active(zone): zone_config = discovery_info.get("zones", {}).get(zone, {}) - time = zone_config.get( - CONF_TRIGGER_TIME, discovery_info.get(CONF_TRIGGER_TIME, 0) - ) + time = zone_config[CONF_TRIGGER_TIME] name = zone_config.get(CONF_FRIENDLY_NAME) - if not time: - logging.warning( - "No delay configured for zone {0:d}, controller {1:s}. " - "Not adding sprinklers for zone {0:d}.".format( - zone, discovery_info[RAINBIRD_CONTROLLER] - ) - ) - continue - devices.append( RainBirdSwitch( controller, From 390298b49ab92211d40bb2bbc74d0a907e53c442 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Vran=C3=ADk?= Date: Thu, 19 Sep 2019 15:13:28 +0200 Subject: [PATCH 50/60] set defaults on right place --- homeassistant/components/rainbird/__init__.py | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/homeassistant/components/rainbird/__init__.py b/homeassistant/components/rainbird/__init__.py index e9df9c5758dba..f4231731c54b0 100644 --- a/homeassistant/components/rainbird/__init__.py +++ b/homeassistant/components/rainbird/__init__.py @@ -36,7 +36,7 @@ TRIGGER_TIME_SCHEMA = vol.All(cv.time_period, cv.positive_timedelta) -def _validator(config): +def _set_defaults(config): config = copy.deepcopy(config) for zone, value in config[CONF_ZONES]: if not value[CONF_TRIGGER_TIME]: @@ -45,22 +45,22 @@ def _validator(config): ZONE_SCHEMA = vol.Schema( + { + vol.Optional(CONF_FRIENDLY_NAME): cv.string, + vol.Optional(CONF_TRIGGER_TIME): TRIGGER_TIME_SCHEMA, + } +) +CONTROLLER_SCHEMA = vol.Schema( vol.All( { - vol.Optional(CONF_FRIENDLY_NAME): cv.string, - vol.Optional(CONF_TRIGGER_TIME): TRIGGER_TIME_SCHEMA, + vol.Required(CONF_HOST): cv.string, + vol.Required(CONF_PASSWORD): cv.string, + vol.Required(CONF_TRIGGER_TIME): TRIGGER_TIME_SCHEMA, + vol.Optional(CONF_ZONES): vol.Schema({cv.positive_int: ZONE_SCHEMA}), }, - _validator, + _set_defaults, ) ) -CONTROLLER_SCHEMA = vol.Schema( - { - vol.Required(CONF_HOST): cv.string, - vol.Required(CONF_PASSWORD): cv.string, - vol.Required(CONF_TRIGGER_TIME): TRIGGER_TIME_SCHEMA, - vol.Optional(CONF_ZONES): vol.Schema({cv.positive_int: ZONE_SCHEMA}), - } -) CONFIG_SCHEMA = vol.Schema( {DOMAIN: vol.Schema(vol.All(cv.ensure_list, [CONTROLLER_SCHEMA]))}, extra=vol.ALLOW_EXTRA, From 9881d3e3d79bb909e1e343fed1369b45d9a0cc9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Vran=C3=ADk?= Date: Thu, 19 Sep 2019 16:19:42 +0200 Subject: [PATCH 51/60] pylint bypass --- homeassistant/components/rainbird/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/rainbird/__init__.py b/homeassistant/components/rainbird/__init__.py index f4231731c54b0..468acbb45533d 100644 --- a/homeassistant/components/rainbird/__init__.py +++ b/homeassistant/components/rainbird/__init__.py @@ -38,7 +38,7 @@ def _set_defaults(config): config = copy.deepcopy(config) - for zone, value in config[CONF_ZONES]: + for zone, value in config[CONF_ZONES]: # pylint: disable=W0612 if not value[CONF_TRIGGER_TIME]: value[CONF_TRIGGER_TIME] = config[CONF_TRIGGER_TIME] return config @@ -86,7 +86,7 @@ def _setup_controller(hass, controller_config, config): position = len(hass.data[DATA_RAINBIRD]) try: controller.get_serial_number() - except Exception as exc: + except Exception as exc: # pylint: disable=W0703 _LOGGER.error("Unable to setup controller: %s", exc) return False hass.data[DATA_RAINBIRD].append(controller) From b1f589cd11e162b41d170c5ca7c8a3b8e35d67e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Vran=C3=ADk?= Date: Thu, 19 Sep 2019 16:22:27 +0200 Subject: [PATCH 52/60] iterate over values --- homeassistant/components/rainbird/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/rainbird/__init__.py b/homeassistant/components/rainbird/__init__.py index 468acbb45533d..28c47d8f68877 100644 --- a/homeassistant/components/rainbird/__init__.py +++ b/homeassistant/components/rainbird/__init__.py @@ -38,7 +38,7 @@ def _set_defaults(config): config = copy.deepcopy(config) - for zone, value in config[CONF_ZONES]: # pylint: disable=W0612 + for value in config[CONF_ZONES].values(): if not value[CONF_TRIGGER_TIME]: value[CONF_TRIGGER_TIME] = config[CONF_TRIGGER_TIME] return config From 1053aba817db46bddfa6d2609a83c486d9cd6ad9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Vran=C3=ADk?= Date: Thu, 19 Sep 2019 17:51:47 +0200 Subject: [PATCH 53/60] codeowner --- homeassistant/components/rainbird/manifest.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/rainbird/manifest.json b/homeassistant/components/rainbird/manifest.json index f2055be2c164d..b911aaa57e19b 100644 --- a/homeassistant/components/rainbird/manifest.json +++ b/homeassistant/components/rainbird/manifest.json @@ -6,5 +6,7 @@ "pyrainbird==0.4.1" ], "dependencies": [], - "codeowners": [] + "codeowners": [ + "@konikvranik" + ] } From 60ae83aecc4e871b11a46b66d43efb8ba8b59473 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Vran=C3=ADk?= Date: Thu, 19 Sep 2019 19:10:58 +0200 Subject: [PATCH 54/60] 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. --- homeassistant/components/rainbird/__init__.py | 27 +++++-------------- homeassistant/components/rainbird/switch.py | 6 ++--- 2 files changed, 10 insertions(+), 23 deletions(-) diff --git a/homeassistant/components/rainbird/__init__.py b/homeassistant/components/rainbird/__init__.py index 28c47d8f68877..8a70c240f0653 100644 --- a/homeassistant/components/rainbird/__init__.py +++ b/homeassistant/components/rainbird/__init__.py @@ -1,5 +1,4 @@ """Support for Rain Bird Irrigation system LNK WiFi Module.""" -import copy import logging from pyrainbird import RainbirdController @@ -33,16 +32,7 @@ SENSOR_TYPE_RAINDELAY: ["Raindelay", None, "mdi:water-off"], } -TRIGGER_TIME_SCHEMA = vol.All(cv.time_period, cv.positive_timedelta) - - -def _set_defaults(config): - config = copy.deepcopy(config) - for value in config[CONF_ZONES].values(): - if not value[CONF_TRIGGER_TIME]: - value[CONF_TRIGGER_TIME] = config[CONF_TRIGGER_TIME] - return config - +TRIGGER_TIME_SCHEMA = cv.positive_int ZONE_SCHEMA = vol.Schema( { @@ -51,15 +41,12 @@ def _set_defaults(config): } ) CONTROLLER_SCHEMA = vol.Schema( - vol.All( - { - vol.Required(CONF_HOST): cv.string, - vol.Required(CONF_PASSWORD): cv.string, - vol.Required(CONF_TRIGGER_TIME): TRIGGER_TIME_SCHEMA, - vol.Optional(CONF_ZONES): vol.Schema({cv.positive_int: ZONE_SCHEMA}), - }, - _set_defaults, - ) + { + vol.Required(CONF_HOST): cv.string, + vol.Required(CONF_PASSWORD): cv.string, + vol.Required(CONF_TRIGGER_TIME): TRIGGER_TIME_SCHEMA, + vol.Optional(CONF_ZONES): vol.Schema({cv.positive_int: ZONE_SCHEMA}), + } ) CONFIG_SCHEMA = vol.Schema( {DOMAIN: vol.Schema(vol.All(cv.ensure_list, [CONTROLLER_SCHEMA]))}, diff --git a/homeassistant/components/rainbird/switch.py b/homeassistant/components/rainbird/switch.py index 6080378421af7..cb4ac83090f12 100644 --- a/homeassistant/components/rainbird/switch.py +++ b/homeassistant/components/rainbird/switch.py @@ -9,7 +9,7 @@ from homeassistant.const import ATTR_ENTITY_ID, CONF_FRIENDLY_NAME, CONF_TRIGGER_TIME from homeassistant.helpers import config_validation as cv -from . import DATA_RAINBIRD, DOMAIN, RAINBIRD_CONTROLLER +from . import CONF_ZONES, DATA_RAINBIRD, DOMAIN, RAINBIRD_CONTROLLER _LOGGER = logging.getLogger(__name__) @@ -40,8 +40,8 @@ def setup_platform(hass, config, add_entities, discovery_info=None): devices = [] for zone in range(1, available_stations.stations.count + 1): if available_stations.stations.active(zone): - zone_config = discovery_info.get("zones", {}).get(zone, {}) - time = zone_config[CONF_TRIGGER_TIME] + 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( From e0dc5e93c979d4fcbce1b932de8295ca90233201 Mon Sep 17 00:00:00 2001 From: konikvranik Date: Thu, 19 Sep 2019 19:36:51 +0200 Subject: [PATCH 55/60] codeowners updated --- CODEOWNERS | 1 + 1 file changed, 1 insertion(+) diff --git a/CODEOWNERS b/CODEOWNERS index f82523d8c8d8e..c4a8e143f350b 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -221,6 +221,7 @@ homeassistant/components/qld_bushfire/* @exxamalte homeassistant/components/qnap/* @colinodell homeassistant/components/quantum_gateway/* @cisasteelersfan homeassistant/components/qwikswitch/* @kellerza +homeassistant/components/rainbird/* @konikvranik homeassistant/components/raincloud/* @vanstinator homeassistant/components/rainforest_eagle/* @gtdiehl homeassistant/components/rainmachine/* @bachya From 7745ac995adb469e044f8103065f188f36b00adc Mon Sep 17 00:00:00 2001 From: konikvranik Date: Sat, 21 Sep 2019 08:22:52 +0200 Subject: [PATCH 56/60] accept timedelta in irrigation time --- homeassistant/components/rainbird/__init__.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/rainbird/__init__.py b/homeassistant/components/rainbird/__init__.py index 8a70c240f0653..8d02999382217 100644 --- a/homeassistant/components/rainbird/__init__.py +++ b/homeassistant/components/rainbird/__init__.py @@ -32,7 +32,14 @@ SENSOR_TYPE_RAINDELAY: ["Raindelay", None, "mdi:water-off"], } -TRIGGER_TIME_SCHEMA = cv.positive_int +TRIGGER_TIME_SCHEMA = vol.Any( + cv.positive_int, + vol.All( + cv.time_period, + cv.positive_timedelta, + lambda td: (td.days * 24 * 60) + td.seconds // 60, + ), +) ZONE_SCHEMA = vol.Schema( { From 8d5c117d7b55a905a0740ae09b4994e5b6b25860 Mon Sep 17 00:00:00 2001 From: konikvranik Date: Sat, 21 Sep 2019 16:16:46 +0200 Subject: [PATCH 57/60] simplified time calculation --- homeassistant/components/rainbird/__init__.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/homeassistant/components/rainbird/__init__.py b/homeassistant/components/rainbird/__init__.py index 8d02999382217..87195b78af65a 100644 --- a/homeassistant/components/rainbird/__init__.py +++ b/homeassistant/components/rainbird/__init__.py @@ -34,11 +34,7 @@ TRIGGER_TIME_SCHEMA = vol.Any( cv.positive_int, - vol.All( - cv.time_period, - cv.positive_timedelta, - lambda td: (td.days * 24 * 60) + td.seconds // 60, - ), + vol.All(cv.time_period, cv.positive_timedelta, lambda td: td.total_seconds // 60), ) ZONE_SCHEMA = vol.Schema( From 24895667f0b11f2f55534a309d048fae9c0a9349 Mon Sep 17 00:00:00 2001 From: konikvranik Date: Sat, 21 Sep 2019 23:26:20 +0200 Subject: [PATCH 58/60] call total_seconds --- homeassistant/components/rainbird/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/rainbird/__init__.py b/homeassistant/components/rainbird/__init__.py index 87195b78af65a..99eda5c0b72fc 100644 --- a/homeassistant/components/rainbird/__init__.py +++ b/homeassistant/components/rainbird/__init__.py @@ -34,7 +34,9 @@ TRIGGER_TIME_SCHEMA = vol.Any( cv.positive_int, - vol.All(cv.time_period, cv.positive_timedelta, lambda td: td.total_seconds // 60), + vol.All( + cv.time_period, cv.positive_timedelta, lambda td: (td.total_seconds() // 60) + ), ) ZONE_SCHEMA = vol.Schema( From da40302332df09a4e451392f7d3fb4a2ff59a87c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Vran=C3=ADk?= Date: Mon, 23 Sep 2019 10:04:48 +0200 Subject: [PATCH 59/60] irrigation time as seconds. --- homeassistant/components/rainbird/__init__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/homeassistant/components/rainbird/__init__.py b/homeassistant/components/rainbird/__init__.py index 99eda5c0b72fc..917d6831e3bbb 100644 --- a/homeassistant/components/rainbird/__init__.py +++ b/homeassistant/components/rainbird/__init__.py @@ -33,10 +33,9 @@ } TRIGGER_TIME_SCHEMA = vol.Any( - cv.positive_int, vol.All( cv.time_period, cv.positive_timedelta, lambda td: (td.total_seconds() // 60) - ), + ) ) ZONE_SCHEMA = vol.Schema( From 292a238e4c41b67efdb9e200c9686148cbeda501 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Vran=C3=ADk?= Date: Wed, 25 Sep 2019 10:09:24 +0200 Subject: [PATCH 60/60] simplified schema --- homeassistant/components/rainbird/__init__.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/rainbird/__init__.py b/homeassistant/components/rainbird/__init__.py index 917d6831e3bbb..0b51be1f25801 100644 --- a/homeassistant/components/rainbird/__init__.py +++ b/homeassistant/components/rainbird/__init__.py @@ -32,10 +32,8 @@ SENSOR_TYPE_RAINDELAY: ["Raindelay", None, "mdi:water-off"], } -TRIGGER_TIME_SCHEMA = vol.Any( - vol.All( - cv.time_period, cv.positive_timedelta, lambda td: (td.total_seconds() // 60) - ) +TRIGGER_TIME_SCHEMA = vol.All( + cv.time_period, cv.positive_timedelta, lambda td: (td.total_seconds() // 60) ) ZONE_SCHEMA = vol.Schema(