Merge pull request #6177 from molobrakos/volvooncall

volvooncall: support for naming vehicle and selecting what attributes to display
This commit is contained in:
Erik Eriksson 2017-02-23 13:00:11 +01:00 committed by GitHub
commit c88527ce79
7 changed files with 69 additions and 93 deletions

View File

@ -12,43 +12,24 @@ from homeassistant.components.binary_sensor import BinarySensorDevice
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
SENSORS = [('washer_fluid_level', 'Washer fluid'),
('brake_fluid', 'Brake Fluid'),
('service_warning_status', 'Service'),
('bulb_failures', 'Bulbs'),
('doors', 'Doors'),
('windows', 'Windows')]
def setup_platform(hass, config, add_devices, discovery_info=None): def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup Volvo sensors.""" """Setup Volvo sensors."""
if discovery_info is None: if discovery_info is None:
return return
add_devices(VolvoSensor(hass, discovery_info, sensor) add_devices([VolvoSensor(hass, *discovery_info)])
for sensor in SENSORS)
class VolvoSensor(VolvoEntity, BinarySensorDevice): class VolvoSensor(VolvoEntity, BinarySensorDevice):
"""Representation of a Volvo sensor.""" """Representation of a Volvo sensor."""
def __init__(self, hass, vehicle, sensor):
"""Initialize the sensor."""
super().__init__(hass, vehicle)
self._sensor = sensor
@property
def _name(self):
"""Name of sensor."""
return self._sensor[1]
@property @property
def is_on(self): def is_on(self):
"""Return True if the binary sensor is on.""" """Return True if the binary sensor is on."""
attr = self._sensor[0] val = getattr(self.vehicle, self._attribute)
val = getattr(self.vehicle, attr) if self._attribute == 'bulb_failures':
if attr == 'bulb_failures':
return len(val) > 0 return len(val) > 0
elif attr in ['doors', 'windows']: elif self._attribute in ['doors', 'windows']:
return any([val[key] for key in val if 'Open' in key]) return any([val[key] for key in val if 'Open' in key])
else: else:
return val != 'Normal' return val != 'Normal'

View File

@ -17,7 +17,7 @@ def setup_scanner(hass, config, see, discovery_info=None):
if discovery_info is None: if discovery_info is None:
return return
vin = discovery_info vin, _ = discovery_info
vehicle = hass.data[DOMAIN].vehicles[vin] vehicle = hass.data[DOMAIN].vehicles[vin]
host_name = vehicle.registration_number host_name = vehicle.registration_number

View File

@ -17,7 +17,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the lock.""" """Setup the lock."""
if discovery_info is None: if discovery_info is None:
return return
add_devices([VolvoLock(hass, discovery_info)]) add_devices([VolvoLock(hass, *discovery_info)])
class VolvoLock(VolvoEntity, LockDevice): class VolvoLock(VolvoEntity, LockDevice):
@ -35,8 +35,3 @@ class VolvoLock(VolvoEntity, LockDevice):
def unlock(self, **kwargs): def unlock(self, **kwargs):
"""Unlock the car.""" """Unlock the car."""
self.vehicle.unlock() self.vehicle.unlock()
@property
def _name(self):
"""Return name."""
return 'Lock'

View File

@ -7,53 +7,36 @@ https://home-assistant.io/components/sensor.volvooncall/
""" """
import logging import logging
from homeassistant.components.volvooncall import VolvoEntity from homeassistant.components.volvooncall import VolvoEntity, RESOURCES
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
SENSORS = [('odometer', 'Odometer', 'km', 'mdi:speedometer'),
('fuel_amount', 'Fuel', 'L', 'mdi:gas-station'),
('fuel_amount_level', 'Fuel', '%', 'mdi:water-percent'),
('distance_to_empty', 'Range', 'km', 'mdi:ruler')]
def setup_platform(hass, config, add_devices, discovery_info=None): def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup Volvo sensors.""" """Setup Volvo sensors."""
if discovery_info is None: if discovery_info is None:
return return
add_devices(VolvoSensor(hass, discovery_info, sensor) add_devices([VolvoSensor(hass, *discovery_info)])
for sensor in SENSORS)
class VolvoSensor(VolvoEntity): class VolvoSensor(VolvoEntity):
"""Representation of a Volvo sensor.""" """Representation of a Volvo sensor."""
def __init__(self, hass, vehicle, sensor):
"""Initialize sensor."""
super().__init__(hass, vehicle)
self._sensor = sensor
@property @property
def state(self): def state(self):
"""Return the state of the sensor.""" """Return the state of the sensor."""
attr = self._sensor[0] val = getattr(self.vehicle, self._attribute)
val = getattr(self.vehicle, attr) if self._attribute == 'odometer':
if attr == 'odometer':
return round(val / 1000) # km return round(val / 1000) # km
else: else:
return val return val
@property
def _name(self):
"""Name of quantity."""
return self._sensor[1]
@property @property
def unit_of_measurement(self): def unit_of_measurement(self):
"""Return the unit of measurement.""" """Return the unit of measurement."""
return self._sensor[2] return RESOURCES[self._attribute][2]
@property @property
def icon(self): def icon(self):
"""Return the icon.""" """Return the icon."""
return self._sensor[3] return RESOURCES[self._attribute][3]

View File

@ -8,7 +8,7 @@ https://home-assistant.io/components/switch.volvooncall/
""" """
import logging import logging
from homeassistant.components.volvooncall import VolvoEntity from homeassistant.components.volvooncall import VolvoEntity, RESOURCES
from homeassistant.helpers.entity import ToggleEntity from homeassistant.helpers.entity import ToggleEntity
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -18,7 +18,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup Tellstick switches.""" """Setup Tellstick switches."""
if discovery_info is None: if discovery_info is None:
return return
add_devices([VolvoSwitch(hass, discovery_info)]) add_devices([VolvoSwitch(hass, *discovery_info)])
class VolvoSwitch(VolvoEntity, ToggleEntity): class VolvoSwitch(VolvoEntity, ToggleEntity):
@ -37,12 +37,7 @@ class VolvoSwitch(VolvoEntity, ToggleEntity):
"""Turn the switch off.""" """Turn the switch off."""
self.vehicle.stop_heater() self.vehicle.stop_heater()
@property
def _name(self):
"""Return the name of the switch."""
return 'Heater'
@property @property
def icon(self): def icon(self):
"""Return the icon.""" """Return the icon."""
return 'mdi:radiator' return RESOURCES[self._attribute][2]

View File

@ -8,7 +8,8 @@ https://home-assistant.io/components/volvooncall/
from datetime import timedelta from datetime import timedelta
import logging import logging
from homeassistant.const import (CONF_USERNAME, CONF_PASSWORD) from homeassistant.const import (CONF_USERNAME, CONF_PASSWORD,
CONF_NAME, CONF_RESOURCES)
from homeassistant.helpers import discovery from homeassistant.helpers import discovery
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
@ -18,7 +19,7 @@ import voluptuous as vol
DOMAIN = 'volvooncall' DOMAIN = 'volvooncall'
REQUIREMENTS = ['volvooncall==0.3.0'] REQUIREMENTS = ['volvooncall==0.3.2']
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -26,12 +27,30 @@ CONF_UPDATE_INTERVAL = 'update_interval'
MIN_UPDATE_INTERVAL = timedelta(minutes=1) MIN_UPDATE_INTERVAL = timedelta(minutes=1)
DEFAULT_UPDATE_INTERVAL = timedelta(minutes=1) DEFAULT_UPDATE_INTERVAL = timedelta(minutes=1)
RESOURCES = {'position': ('device_tracker',),
'lock': ('lock', 'Lock'),
'heater': ('switch', 'Heater', 'mdi:radiator'),
'odometer': ('sensor', 'Odometer', 'mdi:speedometer', 'km'),
'fuel_amount': ('sensor', 'Fuel', 'mdi:gas-station', 'L'),
'fuel_amount_level': ('sensor', 'Fuel', 'mdi:water-percent', '%'),
'distance_to_empty': ('sensor', 'Range', 'mdi:ruler', 'km'),
'washer_fluid_level': ('binary_sensor', 'Washer fluid'),
'brake_fluid': ('binary_sensor', 'Brake Fluid'),
'service_warning_status': ('binary_sensor', 'Service'),
'bulb_failures': ('binary_sensor', 'Bulbs'),
'doors': ('binary_sensor', 'Doors'),
'windows': ('binary_sensor', 'Windows')}
CONFIG_SCHEMA = vol.Schema({ CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({ DOMAIN: vol.Schema({
vol.Required(CONF_USERNAME): cv.string, vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_PASSWORD): cv.string, vol.Required(CONF_PASSWORD): cv.string,
vol.Optional(CONF_UPDATE_INTERVAL, default=DEFAULT_UPDATE_INTERVAL): ( vol.Optional(CONF_UPDATE_INTERVAL, default=DEFAULT_UPDATE_INTERVAL): (
vol.All(cv.time_period, vol.Clamp(min=MIN_UPDATE_INTERVAL))) vol.All(cv.time_period, vol.Clamp(min=MIN_UPDATE_INTERVAL))),
vol.Optional(CONF_NAME, default={}): vol.Schema(
{cv.slug: cv.string}),
vol.Optional(CONF_RESOURCES): vol.All(
cv.ensure_list, [vol.In(RESOURCES)]),
}), }),
}, extra=vol.ALLOW_EXTRA) }, extra=vol.ALLOW_EXTRA)
@ -50,29 +69,21 @@ def setup(hass, config):
entities = {} entities = {}
vehicles = {} vehicles = {}
names = config[DOMAIN].get(CONF_NAME)
hass.data[DOMAIN] = state hass.data[DOMAIN] = state
def discover_vehicle(vehicle): def discover_vehicle(vehicle):
"""Load relevant platforms.""" """Load relevant platforms."""
state.entities[vehicle.vin] = [] state.entities[vehicle.vin] = []
components = ['sensor', 'binary_sensor'] for attr, (component, *_) in RESOURCES.items():
if (getattr(vehicle, attr + '_supported', True) and
if getattr(vehicle, 'position'): attr in config[DOMAIN].get(CONF_RESOURCES, [attr])):
components.append('device_tracker') discovery.load_platform(hass,
component,
if vehicle.heater_supported: DOMAIN,
components.append('switch') (vehicle.vin, attr),
config)
if vehicle.lock_supported:
components.append('lock')
for component in components:
discovery.load_platform(hass,
component,
DOMAIN,
vehicle.vin,
config)
def update_vehicle(vehicle): def update_vehicle(vehicle):
"""Updated information on vehicle received.""" """Updated information on vehicle received."""
@ -107,28 +118,39 @@ def setup(hass, config):
class VolvoEntity(Entity): class VolvoEntity(Entity):
"""Base class for all VOC entities.""" """Base class for all VOC entities."""
def __init__(self, hass, vin): def __init__(self, hass, vin, attribute):
"""Initialize the entity.""" """Initialize the entity."""
self._hass = hass self._hass = hass
self._vin = vin self._vin = vin
self._hass.data[DOMAIN].entities[self._vin].append(self) self._attribute = attribute
self._state.entities[self._vin].append(self)
@property
def _state(self):
return self._hass.data[DOMAIN]
@property @property
def vehicle(self): def vehicle(self):
"""Return vehicle.""" """Return vehicle."""
return self._hass.data[DOMAIN].vehicles[self._vin] return self._state.vehicles[self._vin]
@property
def _vehicle_name(self):
return (self._state.names.get(self._vin.lower()) or
self._state.names.get(
self.vehicle.registration_number.lower()) or
self.vehicle.registration_number)
@property
def _entity_name(self):
return RESOURCES[self._attribute][1]
@property @property
def name(self): def name(self):
"""Return the name of the sensor.""" """Return full name of the entity."""
return '%s %s' % ( return '%s %s' % (
self.vehicle.registration_number, self._vehicle_name,
self._name) self._entity_name)
@property
def _name(self):
"""Overridden by subclasses."""
return None
@property @property
def should_poll(self): def should_poll(self):

View File

@ -720,7 +720,7 @@ urllib3
uvcclient==0.10.0 uvcclient==0.10.0
# homeassistant.components.volvooncall # homeassistant.components.volvooncall
volvooncall==0.3.0 volvooncall==0.3.2
# homeassistant.components.verisure # homeassistant.components.verisure
vsure==0.11.1 vsure==0.11.1