Make RainMachine async (#14879)

* Make RainMachine async

* Updated requirements

* Dispatcher adjustments

* Small verbiage change

* Member-requested changes

* Style consistency

* Updated requirements
This commit is contained in:
Aaron Bach 2018-06-10 02:23:07 -06:00 committed by Martin Hjelmare
parent f3e55ce330
commit 8aca2e84dc
5 changed files with 156 additions and 134 deletions

View File

@ -8,7 +8,7 @@ import logging
from homeassistant.components.binary_sensor import BinarySensorDevice from homeassistant.components.binary_sensor import BinarySensorDevice
from homeassistant.components.rainmachine import ( from homeassistant.components.rainmachine import (
BINARY_SENSORS, DATA_RAINMACHINE, DATA_UPDATE_TOPIC, TYPE_FREEZE, BINARY_SENSORS, DATA_RAINMACHINE, SENSOR_UPDATE_TOPIC, TYPE_FREEZE,
TYPE_FREEZE_PROTECTION, TYPE_HOT_DAYS, TYPE_HOURLY, TYPE_MONTH, TYPE_FREEZE_PROTECTION, TYPE_HOT_DAYS, TYPE_HOURLY, TYPE_MONTH,
TYPE_RAINDELAY, TYPE_RAINSENSOR, TYPE_WEEKDAY, RainMachineEntity) TYPE_RAINDELAY, TYPE_RAINSENSOR, TYPE_WEEKDAY, RainMachineEntity)
from homeassistant.const import CONF_MONITORED_CONDITIONS from homeassistant.const import CONF_MONITORED_CONDITIONS
@ -20,7 +20,8 @@ DEPENDENCIES = ['rainmachine']
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
def setup_platform(hass, config, add_devices, discovery_info=None): async def async_setup_platform(
hass, config, async_add_devices, discovery_info=None):
"""Set up the RainMachine Switch platform.""" """Set up the RainMachine Switch platform."""
if discovery_info is None: if discovery_info is None:
return return
@ -33,7 +34,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
binary_sensors.append( binary_sensors.append(
RainMachineBinarySensor(rainmachine, sensor_type, name, icon)) RainMachineBinarySensor(rainmachine, sensor_type, name, icon))
add_devices(binary_sensors, True) async_add_devices(binary_sensors, True)
class RainMachineBinarySensor(RainMachineEntity, BinarySensorDevice): class RainMachineBinarySensor(RainMachineEntity, BinarySensorDevice):
@ -70,16 +71,16 @@ class RainMachineBinarySensor(RainMachineEntity, BinarySensorDevice):
self.rainmachine.device_mac.replace(':', ''), self._sensor_type) self.rainmachine.device_mac.replace(':', ''), self._sensor_type)
@callback @callback
def update_data(self): def _update_data(self):
"""Update the state.""" """Update the state."""
self.async_schedule_update_ha_state(True) self.async_schedule_update_ha_state(True)
async def async_added_to_hass(self): async def async_added_to_hass(self):
"""Register callbacks.""" """Register callbacks."""
async_dispatcher_connect(self.hass, DATA_UPDATE_TOPIC, async_dispatcher_connect(
self.update_data) self.hass, SENSOR_UPDATE_TOPIC, self._update_data)
def update(self): async def async_update(self):
"""Update the state.""" """Update the state."""
if self._sensor_type == TYPE_FREEZE: if self._sensor_type == TYPE_FREEZE:
self._state = self.rainmachine.restrictions['current']['freeze'] self._state = self.rainmachine.restrictions['current']['freeze']

View File

@ -13,12 +13,13 @@ from homeassistant.const import (
ATTR_ATTRIBUTION, CONF_BINARY_SENSORS, CONF_IP_ADDRESS, CONF_PASSWORD, ATTR_ATTRIBUTION, CONF_BINARY_SENSORS, CONF_IP_ADDRESS, CONF_PASSWORD,
CONF_PORT, CONF_SENSORS, CONF_SSL, CONF_MONITORED_CONDITIONS, CONF_PORT, CONF_SENSORS, CONF_SSL, CONF_MONITORED_CONDITIONS,
CONF_SWITCHES) CONF_SWITCHES)
from homeassistant.helpers import config_validation as cv, discovery from homeassistant.helpers import (
from homeassistant.helpers.dispatcher import dispatcher_send aiohttp_client, config_validation as cv, discovery)
from homeassistant.helpers.dispatcher import async_dispatcher_send
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
from homeassistant.helpers.event import track_time_interval from homeassistant.helpers.event import async_track_time_interval
REQUIREMENTS = ['regenmaschine==0.4.2'] REQUIREMENTS = ['regenmaschine==1.0.2']
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -28,8 +29,9 @@ DOMAIN = 'rainmachine'
NOTIFICATION_ID = 'rainmachine_notification' NOTIFICATION_ID = 'rainmachine_notification'
NOTIFICATION_TITLE = 'RainMachine Component Setup' NOTIFICATION_TITLE = 'RainMachine Component Setup'
DATA_UPDATE_TOPIC = '{0}_data_update'.format(DOMAIN)
PROGRAM_UPDATE_TOPIC = '{0}_program_update'.format(DOMAIN) PROGRAM_UPDATE_TOPIC = '{0}_program_update'.format(DOMAIN)
SENSOR_UPDATE_TOPIC = '{0}_data_update'.format(DOMAIN)
ZONE_UPDATE_TOPIC = '{0}_zone_update'.format(DOMAIN)
CONF_PROGRAM_ID = 'program_id' CONF_PROGRAM_ID = 'program_id'
CONF_ZONE_ID = 'zone_id' CONF_ZONE_ID = 'zone_id'
@ -114,10 +116,10 @@ CONFIG_SCHEMA = vol.Schema(
extra=vol.ALLOW_EXTRA) extra=vol.ALLOW_EXTRA)
def setup(hass, config): async def async_setup(hass, config):
"""Set up the RainMachine component.""" """Set up the RainMachine component."""
from regenmaschine import Authenticator, Client from regenmaschine import Client
from regenmaschine.exceptions import RainMachineError from regenmaschine.errors import RequestError
conf = config[DOMAIN] conf = config[DOMAIN]
ip_address = conf[CONF_IP_ADDRESS] ip_address = conf[CONF_IP_ADDRESS]
@ -126,17 +128,18 @@ def setup(hass, config):
ssl = conf[CONF_SSL] ssl = conf[CONF_SSL]
try: try:
auth = Authenticator.create_local( websession = aiohttp_client.async_get_clientsession(hass)
ip_address, password, port=port, https=ssl) client = Client(ip_address, websession, port=port, ssl=ssl)
rainmachine = RainMachine(hass, Client(auth)) await client.authenticate(password)
rainmachine.update() rainmachine = RainMachine(client)
await rainmachine.async_update()
hass.data[DATA_RAINMACHINE] = rainmachine hass.data[DATA_RAINMACHINE] = rainmachine
except RainMachineError as exc: except RequestError as err:
_LOGGER.error('An error occurred: %s', str(exc)) _LOGGER.error('An error occurred: %s', str(err))
hass.components.persistent_notification.create( hass.components.persistent_notification.create(
'Error: {0}<br />' 'Error: {0}<br />'
'You will need to restart hass after fixing.' 'You will need to restart hass after fixing.'
''.format(exc), ''.format(err),
title=NOTIFICATION_TITLE, title=NOTIFICATION_TITLE,
notification_id=NOTIFICATION_ID) notification_id=NOTIFICATION_ID)
return False return False
@ -146,36 +149,43 @@ def setup(hass, config):
('sensor', conf[CONF_SENSORS]), ('sensor', conf[CONF_SENSORS]),
('switch', conf[CONF_SWITCHES]), ('switch', conf[CONF_SWITCHES]),
]: ]:
discovery.load_platform(hass, component, DOMAIN, schema, config) hass.async_add_job(
discovery.async_load_platform(hass, component, DOMAIN, schema,
config))
def refresh(event_time): async def refresh_sensors(event_time):
"""Refresh RainMachine data.""" """Refresh RainMachine sensor data."""
_LOGGER.debug('Updating RainMachine data') _LOGGER.debug('Updating RainMachine sensor data')
hass.data[DATA_RAINMACHINE].update() await rainmachine.async_update()
dispatcher_send(hass, DATA_UPDATE_TOPIC) async_dispatcher_send(hass, SENSOR_UPDATE_TOPIC)
track_time_interval(hass, refresh, DEFAULT_SCAN_INTERVAL) async_track_time_interval(hass, refresh_sensors, DEFAULT_SCAN_INTERVAL)
def start_program(service): async def start_program(service):
"""Start a particular program.""" """Start a particular program."""
rainmachine.client.programs.start(service.data[CONF_PROGRAM_ID]) await rainmachine.client.programs.start(service.data[CONF_PROGRAM_ID])
async_dispatcher_send(hass, PROGRAM_UPDATE_TOPIC)
def start_zone(service): async def start_zone(service):
"""Start a particular zone for a certain amount of time.""" """Start a particular zone for a certain amount of time."""
rainmachine.client.zones.start(service.data[CONF_ZONE_ID], await rainmachine.client.zones.start(service.data[CONF_ZONE_ID],
service.data[CONF_ZONE_RUN_TIME]) service.data[CONF_ZONE_RUN_TIME])
async_dispatcher_send(hass, ZONE_UPDATE_TOPIC)
def stop_all(service): async def stop_all(service):
"""Stop all watering.""" """Stop all watering."""
rainmachine.client.watering.stop_all() await rainmachine.client.watering.stop_all()
async_dispatcher_send(hass, PROGRAM_UPDATE_TOPIC)
def stop_program(service): async def stop_program(service):
"""Stop a program.""" """Stop a program."""
rainmachine.client.programs.stop(service.data[CONF_PROGRAM_ID]) await rainmachine.client.programs.stop(service.data[CONF_PROGRAM_ID])
async_dispatcher_send(hass, PROGRAM_UPDATE_TOPIC)
def stop_zone(service): async def stop_zone(service):
"""Stop a zone.""" """Stop a zone."""
rainmachine.client.zones.stop(service.data[CONF_ZONE_ID]) await rainmachine.client.zones.stop(service.data[CONF_ZONE_ID])
async_dispatcher_send(hass, ZONE_UPDATE_TOPIC)
for service, method, schema in [ for service, method, schema in [
('start_program', start_program, SERVICE_START_PROGRAM_SCHEMA), ('start_program', start_program, SERVICE_START_PROGRAM_SCHEMA),
@ -184,7 +194,7 @@ def setup(hass, config):
('stop_program', stop_program, SERVICE_STOP_PROGRAM_SCHEMA), ('stop_program', stop_program, SERVICE_STOP_PROGRAM_SCHEMA),
('stop_zone', stop_zone, SERVICE_STOP_ZONE_SCHEMA) ('stop_zone', stop_zone, SERVICE_STOP_ZONE_SCHEMA)
]: ]:
hass.services.register(DOMAIN, service, method, schema=schema) hass.services.async_register(DOMAIN, service, method, schema=schema)
return True return True
@ -192,17 +202,17 @@ def setup(hass, config):
class RainMachine(object): class RainMachine(object):
"""Define a generic RainMachine object.""" """Define a generic RainMachine object."""
def __init__(self, hass, client): def __init__(self, client):
"""Initialize.""" """Initialize."""
self.client = client self.client = client
self.device_mac = self.client.provision.wifi()['macAddress'] self.device_mac = self.client.mac
self.restrictions = {} self.restrictions = {}
def update(self): async def async_update(self):
"""Update sensor/binary sensor data.""" """Update sensor/binary sensor data."""
self.restrictions.update({ self.restrictions.update({
'current': self.client.restrictions.current(), 'current': await self.client.restrictions.current(),
'global': self.client.restrictions.universal() 'global': await self.client.restrictions.universal()
}) })

View File

@ -7,7 +7,7 @@ https://home-assistant.io/components/sensor.rainmachine/
import logging import logging
from homeassistant.components.rainmachine import ( from homeassistant.components.rainmachine import (
DATA_RAINMACHINE, DATA_UPDATE_TOPIC, SENSORS, RainMachineEntity) DATA_RAINMACHINE, SENSOR_UPDATE_TOPIC, SENSORS, RainMachineEntity)
from homeassistant.const import CONF_MONITORED_CONDITIONS from homeassistant.const import CONF_MONITORED_CONDITIONS
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.dispatcher import async_dispatcher_connect
@ -17,7 +17,8 @@ DEPENDENCIES = ['rainmachine']
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
def setup_platform(hass, config, add_devices, discovery_info=None): async def async_setup_platform(
hass, config, async_add_devices, discovery_info=None):
"""Set up the RainMachine Switch platform.""" """Set up the RainMachine Switch platform."""
if discovery_info is None: if discovery_info is None:
return return
@ -30,7 +31,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
sensors.append( sensors.append(
RainMachineSensor(rainmachine, sensor_type, name, icon, unit)) RainMachineSensor(rainmachine, sensor_type, name, icon, unit))
add_devices(sensors, True) async_add_devices(sensors, True)
class RainMachineSensor(RainMachineEntity): class RainMachineSensor(RainMachineEntity):
@ -73,16 +74,16 @@ class RainMachineSensor(RainMachineEntity):
return self._unit return self._unit
@callback @callback
def update_data(self): def _update_data(self):
"""Update the state.""" """Update the state."""
self.async_schedule_update_ha_state(True) self.async_schedule_update_ha_state(True)
async def async_added_to_hass(self): async def async_added_to_hass(self):
"""Register callbacks.""" """Register callbacks."""
async_dispatcher_connect(self.hass, DATA_UPDATE_TOPIC, async_dispatcher_connect(
self.update_data) self.hass, SENSOR_UPDATE_TOPIC, self._update_data)
def update(self): async def async_update(self):
"""Update the sensor's state.""" """Update the sensor's state."""
self._state = self.rainmachine.restrictions['global'][ self._state = self.rainmachine.restrictions['global'][
'freezeProtectTemp'] 'freezeProtectTemp']

View File

@ -8,12 +8,12 @@ import logging
from homeassistant.components.rainmachine import ( from homeassistant.components.rainmachine import (
CONF_ZONE_RUN_TIME, DATA_RAINMACHINE, DEFAULT_ZONE_RUN, CONF_ZONE_RUN_TIME, DATA_RAINMACHINE, DEFAULT_ZONE_RUN,
PROGRAM_UPDATE_TOPIC, RainMachineEntity) PROGRAM_UPDATE_TOPIC, ZONE_UPDATE_TOPIC, RainMachineEntity)
from homeassistant.const import ATTR_ID from homeassistant.const import ATTR_ID
from homeassistant.components.switch import SwitchDevice from homeassistant.components.switch import SwitchDevice
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.helpers.dispatcher import ( from homeassistant.helpers.dispatcher import (
async_dispatcher_connect, dispatcher_send) async_dispatcher_connect, async_dispatcher_send)
DEPENDENCIES = ['rainmachine'] DEPENDENCIES = ['rainmachine']
@ -39,20 +39,11 @@ ATTR_VEGETATION_TYPE = 'vegetation_type'
ATTR_ZONES = 'zones' ATTR_ZONES = 'zones'
DAYS = [ DAYS = [
'Monday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday',
'Sunday' 'Sunday'
] ]
PROGRAM_STATUS_MAP = { PROGRAM_STATUS_MAP = {0: 'Not Running', 1: 'Running', 2: 'Queued'}
0: 'Not Running',
1: 'Running',
2: 'Queued'
}
SOIL_TYPE_MAP = { SOIL_TYPE_MAP = {
0: 'Not Set', 0: 'Not Set',
@ -108,7 +99,8 @@ VEGETATION_MAP = {
} }
def setup_platform(hass, config, add_devices, discovery_info=None): async def async_setup_platform(
hass, config, async_add_devices, discovery_info=None):
"""Set up the RainMachine Switch platform.""" """Set up the RainMachine Switch platform."""
if discovery_info is None: if discovery_info is None:
return return
@ -120,21 +112,24 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
rainmachine = hass.data[DATA_RAINMACHINE] rainmachine = hass.data[DATA_RAINMACHINE]
entities = [] entities = []
for program in rainmachine.client.programs.all().get('programs', {}):
programs = await rainmachine.client.programs.all()
for program in programs:
if not program.get('active'): if not program.get('active'):
continue continue
_LOGGER.debug('Adding program: %s', program) _LOGGER.debug('Adding program: %s', program)
entities.append(RainMachineProgram(rainmachine, program)) entities.append(RainMachineProgram(rainmachine, program))
for zone in rainmachine.client.zones.all().get('zones', {}): zones = await rainmachine.client.zones.all()
for zone in zones:
if not zone.get('active'): if not zone.get('active'):
continue continue
_LOGGER.debug('Adding zone: %s', zone) _LOGGER.debug('Adding zone: %s', zone)
entities.append(RainMachineZone(rainmachine, zone, zone_run_time)) entities.append(RainMachineZone(rainmachine, zone, zone_run_time))
add_devices(entities, True) async_add_devices(entities, True)
class RainMachineSwitch(RainMachineEntity, SwitchDevice): class RainMachineSwitch(RainMachineEntity, SwitchDevice):
@ -163,10 +158,14 @@ class RainMachineSwitch(RainMachineEntity, SwitchDevice):
def unique_id(self) -> str: def unique_id(self) -> str:
"""Return a unique, HASS-friendly identifier for this entity.""" """Return a unique, HASS-friendly identifier for this entity."""
return '{0}_{1}_{2}'.format( return '{0}_{1}_{2}'.format(
self.rainmachine.device_mac.replace(':', ''), self.rainmachine.device_mac.replace(':', ''), self._switch_type,
self._switch_type,
self._rainmachine_entity_id) self._rainmachine_entity_id)
@callback
def _program_updated(self):
"""Update state, trigger updates."""
self.async_schedule_update_ha_state(True)
class RainMachineProgram(RainMachineSwitch): class RainMachineProgram(RainMachineSwitch):
"""A RainMachine program.""" """A RainMachine program."""
@ -185,34 +184,42 @@ class RainMachineProgram(RainMachineSwitch):
"""Return a list of active zones associated with this program.""" """Return a list of active zones associated with this program."""
return [z for z in self._obj['wateringTimes'] if z['active']] return [z for z in self._obj['wateringTimes'] if z['active']]
def turn_off(self, **kwargs) -> None: async def async_added_to_hass(self):
"""Register callbacks."""
async_dispatcher_connect(
self.hass, PROGRAM_UPDATE_TOPIC, self._program_updated)
async def async_turn_off(self, **kwargs) -> None:
"""Turn the program off.""" """Turn the program off."""
from regenmaschine.exceptions import RainMachineError from regenmaschine.errors import RequestError
try: try:
self.rainmachine.client.programs.stop(self._rainmachine_entity_id) await self.rainmachine.client.programs.stop(
dispatcher_send(self.hass, PROGRAM_UPDATE_TOPIC) self._rainmachine_entity_id)
except RainMachineError as exc_info: async_dispatcher_send(self.hass, PROGRAM_UPDATE_TOPIC)
_LOGGER.error('Unable to turn off program "%s"', self.unique_id) except RequestError as err:
_LOGGER.debug(exc_info) _LOGGER.error(
'Unable to turn off program "%s": %s', self.unique_id,
str(err))
def turn_on(self, **kwargs) -> None: async def async_turn_on(self, **kwargs) -> None:
"""Turn the program on.""" """Turn the program on."""
from regenmaschine.exceptions import RainMachineError from regenmaschine.errors import RequestError
try: try:
self.rainmachine.client.programs.start(self._rainmachine_entity_id) await self.rainmachine.client.programs.start(
dispatcher_send(self.hass, PROGRAM_UPDATE_TOPIC) self._rainmachine_entity_id)
except RainMachineError as exc_info: async_dispatcher_send(self.hass, PROGRAM_UPDATE_TOPIC)
_LOGGER.error('Unable to turn on program "%s"', self.unique_id) except RequestError as err:
_LOGGER.debug(exc_info) _LOGGER.error(
'Unable to turn on program "%s": %s', self.unique_id, str(err))
def update(self) -> None: async def async_update(self) -> None:
"""Update info for the program.""" """Update info for the program."""
from regenmaschine.exceptions import RainMachineError from regenmaschine.errors import RequestError
try: try:
self._obj = self.rainmachine.client.programs.get( self._obj = await self.rainmachine.client.programs.get(
self._rainmachine_entity_id) self._rainmachine_entity_id)
self._attrs.update({ self._attrs.update({
@ -221,10 +228,10 @@ class RainMachineProgram(RainMachineSwitch):
ATTR_STATUS: PROGRAM_STATUS_MAP[self._obj.get('status')], ATTR_STATUS: PROGRAM_STATUS_MAP[self._obj.get('status')],
ATTR_ZONES: ', '.join(z['name'] for z in self.zones) ATTR_ZONES: ', '.join(z['name'] for z in self.zones)
}) })
except RainMachineError as exc_info: except RequestError as err:
_LOGGER.error('Unable to update info for program "%s"', _LOGGER.error(
self.unique_id) 'Unable to update info for program "%s": %s', self.unique_id,
_LOGGER.debug(exc_info) str(err))
class RainMachineZone(RainMachineSwitch): class RainMachineZone(RainMachineSwitch):
@ -242,62 +249,65 @@ class RainMachineZone(RainMachineSwitch):
"""Return whether the zone is running.""" """Return whether the zone is running."""
return bool(self._obj.get('state')) return bool(self._obj.get('state'))
@callback
def _program_updated(self):
"""Update state, trigger updates."""
self.async_schedule_update_ha_state(True)
async def async_added_to_hass(self): async def async_added_to_hass(self):
"""Register callbacks.""" """Register callbacks."""
async_dispatcher_connect(self.hass, PROGRAM_UPDATE_TOPIC, async_dispatcher_connect(
self._program_updated) self.hass, PROGRAM_UPDATE_TOPIC, self._program_updated)
async_dispatcher_connect(
self.hass, ZONE_UPDATE_TOPIC, self._program_updated)
def turn_off(self, **kwargs) -> None: async def async_turn_off(self, **kwargs) -> None:
"""Turn the zone off.""" """Turn the zone off."""
from regenmaschine.exceptions import RainMachineError from regenmaschine.errors import RequestError
try: try:
self.rainmachine.client.zones.stop(self._rainmachine_entity_id) await self.rainmachine.client.zones.stop(
except RainMachineError as exc_info: self._rainmachine_entity_id)
_LOGGER.error('Unable to turn off zone "%s"', self.unique_id) except RequestError as err:
_LOGGER.debug(exc_info) _LOGGER.error(
'Unable to turn off zone "%s": %s', self.unique_id, str(err))
def turn_on(self, **kwargs) -> None: async def async_turn_on(self, **kwargs) -> None:
"""Turn the zone on.""" """Turn the zone on."""
from regenmaschine.exceptions import RainMachineError from regenmaschine.errors import RequestError
try: try:
self.rainmachine.client.zones.start(self._rainmachine_entity_id, await self.rainmachine.client.zones.start(
self._run_time) self._rainmachine_entity_id, self._run_time)
except RainMachineError as exc_info: except RequestError as err:
_LOGGER.error('Unable to turn on zone "%s"', self.unique_id) _LOGGER.error(
_LOGGER.debug(exc_info) 'Unable to turn on zone "%s": %s', self.unique_id, str(err))
def update(self) -> None: async def async_update(self) -> None:
"""Update info for the zone.""" """Update info for the zone."""
from regenmaschine.exceptions import RainMachineError from regenmaschine.errors import RequestError
try: try:
self._obj = self.rainmachine.client.zones.get( self._obj = await self.rainmachine.client.zones.get(
self._rainmachine_entity_id) self._rainmachine_entity_id)
self._properties_json = self.rainmachine.client.zones.get( self._properties_json = await self.rainmachine.client.zones.get(
self._rainmachine_entity_id, properties=True) self._rainmachine_entity_id, details=True)
self._attrs.update({ self._attrs.update({
ATTR_ID: self._obj['uid'], ATTR_ID:
ATTR_AREA: self._properties_json.get('waterSense').get('area'), self._obj['uid'],
ATTR_CURRENT_CYCLE: self._obj.get('cycle'), ATTR_AREA:
self._properties_json.get('waterSense').get('area'),
ATTR_CURRENT_CYCLE:
self._obj.get('cycle'),
ATTR_FIELD_CAPACITY: ATTR_FIELD_CAPACITY:
self._properties_json.get( self._properties_json.get('waterSense')
'waterSense').get('fieldCapacity'), .get('fieldCapacity'),
ATTR_NO_CYCLES: self._obj.get('noOfCycles'), ATTR_NO_CYCLES:
self._obj.get('noOfCycles'),
ATTR_PRECIP_RATE: ATTR_PRECIP_RATE:
self._properties_json.get( self._properties_json.get('waterSense')
'waterSense').get('precipitationRate'), .get('precipitationRate'),
ATTR_RESTRICTIONS: self._obj.get('restriction'), ATTR_RESTRICTIONS:
ATTR_SLOPE: SLOPE_TYPE_MAP.get( self._obj.get('restriction'),
self._properties_json.get('slope')), ATTR_SLOPE:
SLOPE_TYPE_MAP.get(self._properties_json.get('slope')),
ATTR_SOIL_TYPE: ATTR_SOIL_TYPE:
SOIL_TYPE_MAP.get(self._properties_json.get('sun')), SOIL_TYPE_MAP.get(self._properties_json.get('sun')),
ATTR_SPRINKLER_TYPE: ATTR_SPRINKLER_TYPE:
@ -308,7 +318,7 @@ class RainMachineZone(RainMachineSwitch):
ATTR_VEGETATION_TYPE: ATTR_VEGETATION_TYPE:
VEGETATION_MAP.get(self._obj.get('type')), VEGETATION_MAP.get(self._obj.get('type')),
}) })
except RainMachineError as exc_info: except RequestError as err:
_LOGGER.error('Unable to update info for zone "%s"', _LOGGER.error(
self.unique_id) 'Unable to update info for zone "%s": %s', self.unique_id,
_LOGGER.debug(exc_info) str(err))

View File

@ -1162,7 +1162,7 @@ raincloudy==0.0.4
# raspihats==2.2.3 # raspihats==2.2.3
# homeassistant.components.rainmachine # homeassistant.components.rainmachine
regenmaschine==0.4.2 regenmaschine==1.0.2
# homeassistant.components.python_script # homeassistant.components.python_script
restrictedpython==4.0b4 restrictedpython==4.0b4