8000 Use voluptuous for mysensors by MartinHjelmare · Pull Request #2992 · home-assistant/core · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Use voluptuous for mysensors #2992

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 27, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions homeassistant/components/binary_sensor/mysensors.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
pres.S_MOTION: [set_req.V_TRIPPED],
pres.S_SMOKE: [set_req.V_TRIPPED],
}
if float(gateway.version) >= 1.5:
if float(gateway.protocol_version) >= 1.5:
map_sv_types.update({
pres.S_SPRINKLER: [set_req.V_TRIPPED],
pres.S_WATER_LEAK: [set_req.V_TRIPPED],
Expand Down Expand Up @@ -66,7 +66,7 @@ def sensor_class(self):
pres.S_MOTION: 'motion',
pres.S_SMOKE: 'smoke',
}
if float(self.gateway.version) >= 1.5:
if float(self.gateway.protocol_version) >= 1.5:
class_map.update({
pres.S_SPRINKLER: 'sprinkler',
pres.S_WATER_LEAK: 'leak',
Expand Down
5 changes: 2 additions & 3 deletions homeassistant/components/light/mysensors.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
device_class_map = {
pres.S_DIMMER: MySensorsLightDimmer,
}
if float(gateway.version) >= 1.5:
if float(gateway.protocol_version) >= 1.5:
# Add V_RGBW when rgb_white is implemented in the frontend
map_sv_types.update({
pres.S_RGB_LIGHT: [set_req.V_RGB],
Expand Down Expand Up @@ -169,7 +169,7 @@ def _turn_off_dimmer(self, value_type=None, value=None):

def _turn_off_rgb_or_w(self, value_type=None, value=None):
"""Turn off RGB or RGBW child device."""
if float(self.gateway.version) >= 1.5:
if float(self.gateway.protocol_version) >= 1.5:
set_req = self.gateway.const.SetReq
if self.value_type == set_req.V_RGB:
value = '000000'
Expand Down Expand Up @@ -227,7 +227,6 @@ def _update_main(self):
"""Update the controller with the latest value from a sensor."""
node = self.gateway.sensors[self.node_id]
child = node.children[self.child_id]
self.battery_level = node.battery_level
for value_type, value in child.values.items():
_LOGGER.debug(
'%s: value_type %s, value = %s', self._name, value_type, value)
Expand Down
108 changes: 60 additions & 48 deletions homeassistant/components/mysensors.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,59 +7,74 @@
import logging
import socket

import voluptuous as vol

from homeassistant.bootstrap import setup_component
import homeassistant.helpers.config_validation as cv
from homeassistant.const import (ATTR_BATTERY_LEVEL, CONF_OPTIMISTIC,
EVENT_HOMEASSISTANT_START,
EVENT_HOMEASSISTANT_STOP, STATE_OFF, STATE_ON)
from homeassistant.helpers import discovery, validate_config
from homeassistant.helpers import discovery
from homeassistant.loader import get_component

CONF_GATEWAYS = 'gateways'
_LOGGER = logging.getLogger(__name__)

ATTR_NODE_ID = 'node_id'
ATTR_CHILD_ID = 'child_id'
ATTR_DESCRIPTION = 'description'
ATTR_DEVICE = 'device'
CONF_BAUD_RATE = 'baud_rate'
CONF_DEVICE = 'device'
CONF_DEBUG = 'debug'
CONF_GATEWAYS = 'gateways'
CONF_PERSISTENCE = 'persistence'
CONF_PERSISTENCE_FILE = 'persistence_file'
CONF_VERSION = 'version'
CONF_BAUD_RATE = 'baud_rate'
CONF_TCP_PORT = 'tcp_port'
CONF_TOPIC_IN_PREFIX = 'topic_in_prefix'
CONF_TOPIC_OUT_PREFIX = 'topic_out_prefix'
CONF_RETAIN = 'retain'
DEFAULT_VERSION = '1.4'
CONF_VERSION = 'version'
DEFAULT_VERSION = 1.4
DEFAULT_BAUD_RATE = 115200
DEFAULT_TCP_PORT = 5003

DOMAIN = 'mysensors'
DEPENDENCIES = []
GATEWAYS = None
MQTT_COMPONENT = 'mqtt'
REQUIREMENTS = [
'https://github.com/theolind/pymysensors/archive/'
'8ce98b7fb56f7921a808eb66845ce8b2c455c81e.zip#pymysensors==0.7.1']
_LOGGER = logging.getLogger(__name__)
ATTR_NODE_ID = 'node_id'
ATTR_CHILD_ID = 'child_id'
ATTR_DEVICE = 'device'

GATEWAYS = None
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
vol.Required(CONF_GATEWAYS): vol.All(cv.ensure_list, [
{
vol.Required(CONF_DEVICE): cv.string,
vol.Optional(CONF_PERSISTENCE_FILE): cv.string,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Persistence_FIle is optionsal, but CONF_PERSISTENCE defaults to true. How does the SerialGateway behave if told to persist without a file?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That behavior is still left later in the code. I'm using the index of the gateways to set different default filenames, to not overwrite. Any suggestion how I could solve that in voluptuous?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hrm... well we could move persist to the same level as the persistence file - that would allow you to persist some devices, and not others - more granularity

vol.Optional(
CONF_BAUD_RATE,
default=DEFAULT_BAUD_RATE): cv.positive_int,
vol.Optional(
CONF_TCP_PORT,
default=DEFAULT_TCP_PORT): cv.port,
vol.Optional(CONF_TOPIC_IN_PREFIX, default=''): cv.string,
vol.Optional(CONF_TOPIC_OUT_PREFIX, default=''): cv.string,
},
]),
vol.Optional(CONF_DEBUG, default=False): cv.boolean,
vol.Optional(CONF_OPTIMISTIC, default=False): cv.boolean,
vol.Optional(CONF_PERSISTENCE, default=True): cv.boolean,
vol.Optional(CONF_RETAIN, default=True): cv.boolean,
vol.Optional(CONF_VERSION, default=DEFAULT_VERSION): vol.Coerce(float),
})
}, extra=vol.ALLOW_EXTRA)


def setup(hass, config): # pylint: disable=too-many-locals
"""Setup the MySensors component."""
if not validate_config(config,
{DOMAIN: [CONF_GATEWAYS]},
_LOGGER):
return False
if not all(CONF_DEVICE in gateway
for gateway in config[DOMAIN][CONF_GATEWAYS]):
_LOGGER.error('Missing required configuration items '
'in %s: %s', DOMAIN, CONF_DEVICE)
return False

import mysensors.mysensors as mysensors

version = str(config[DOMAIN].get(CONF_VERSION, DEFAULT_VERSION))
is_metric = hass.config.units.is_metric
persistence = config[DOMAIN].get(CONF_PERSISTENCE, True)
version = config[DOMAIN].get(CONF_VERSION)
persistence = config[DOMAIN].get(CONF_PERSISTENCE)

def setup_gateway(device, persistence_file, baud_rate, tcp_port, in_prefix,
out_prefix):
Expand All @@ -69,7 +84,7 @@ def setup_gateway(device, persistence_file, baud_rate, tcp_port, in_prefix,
if not setup_component(hass, MQTT_COMPONENT, config):
return
mqtt = get_component(MQTT_COMPONENT)
retain = config[DOMAIN].get(CONF_RETAIN, True)
retain = config[DOMAIN].get(CONF_RETAIN)

def pub_callback(topic, payload, qos, retain):
"""Call mqtt publish function."""
Expand Down Expand Up @@ -98,10 +113,10 @@ def sub_callback(topic, callback, qos):
device, event_callback=None, persistence=persistence,
persistence_file=persistence_file,
protocol_version=version, baud=baud_rate)
gateway.metric = is_metric
gateway.debug = config[DOMAIN].get(CONF_DEBUG, False)
optimistic = config[DOMAIN].get(CONF_OPTIMISTIC, False)
gateway = GatewayWrapper(gateway, version, optimistic, device)
gateway.metric = hass.config.units.is_metric
gateway.debug = config[DOMAIN].get(CONF_DEBUG)
optimistic = config[DOMAIN].get(CONF_OPTIMISTIC)
gateway = GatewayWrapper(gateway, optimistic, device)
# pylint: disable=attribute-defined-outside-init
gateway.event_callback = gateway.callback_factory()

Expand All @@ -122,18 +137,16 @@ def gw_start(event):
global GATEWAYS
GATEWAYS = {}
conf_gateways = config[DOMAIN][CONF_GATEWAYS]
if isinstance(conf_gateways, dict):
conf_gateways = [conf_gateways]

for index, gway in enumerate(conf_gateways):
device = gway[CONF_DEVICE]
persistence_file = gway.get(
CONF_PERSISTENCE_FILE,
hass.config.path('mysensors{}.pickle'.format(index + 1)))
baud_rate = gway.get(CONF_BAUD_RATE, DEFAULT_BAUD_RATE)
tcp_port = gway.get(CONF_TCP_PORT, DEFAULT_TCP_PORT)
in_prefix = gway.get(CONF_TOPIC_IN_PREFIX, '')
out_prefix = gway.get(CONF_TOPIC_OUT_PREFIX, '')
baud_rate = gway.get(CONF_BAUD_RATE)
tcp_port = gway.get(CONF_TCP_PORT)
in_prefix = gway.get(CONF_TOPIC_IN_PREFIX)
out_prefix = gway.get(CONF_TOPIC_OUT_PREFIX)
GATEWAYS[device] = setup_gateway(
device, persistence_file, baud_rate, tcp_port, in_prefix,
out_prefix)
Expand Down Expand Up @@ -189,24 +202,22 @@ class GatewayWrapper(object):

# pylint: disable=too-few-public-methods

def __init__(self, gateway, version, optimistic, device):
def __init__(self, gateway, optimistic, device):
"""Setup class attributes on instantiation.

Args:
gateway (mysensors.Gateway): Gateway to wrap.
version (str): Version of mysensors API.
gateway (mysensors.SerialGateway): Gateway to wrap.
optimistic (bool): Send values to actuators without feedback state.
device (str): Path to serial port, ip adress or mqtt.

Attributes:
_wrapped_gateway (mysensors.Gateway): Wrapped gateway.
version (str): Version of mysensors API.
_wrapped_gateway (mysensors.SerialGateway): Wrapped gateway.
platform_callbacks (list): Callback functions, one per platform.
optimistic (bool): Send values to actuators without feedback state.
device (str): Device configured as gateway.
__initialised (bool): True if GatewayWrapper is initialised.
"""
self._wrapped_gateway = gateway
self.version = version
self.platform_callbacks = []
self.optimistic = optimistic
self.device = device
Expand Down Expand Up @@ -244,7 +255,7 @@ def node_update(update_type, node_id):
class MySensorsDeviceEntity(object):
"""Represent a MySensors entity."""

# pylint: disable=too-many-arguments,too-many-instance-attributes
# pylint: disable=too-many-arguments

def __init__(
self, gateway, node_id, child_id, name, value_type, child_type):
Expand Down Expand Up @@ -276,7 +287,6 @@ def __init__(
self._name = name
self.value_type = value_type
self.child_type = child_type
self.battery_level = 0
self._values = {}

@property
Expand All @@ -292,11 +302,14 @@ def name(self):
@property
def device_state_attributes(self):
"""Return device specific state attributes."""
node = self.gateway.sensors[self.node_id]
child = node.children[self.child_id]
attr = {
ATTR_BATTERY_LEVEL: node.battery_level,
ATTR_CHILD_ID: self.child_id,
ATTR_DESCRIPTION: child.description,
ATTR_DEVICE: self.gateway.device,
ATTR_NODE_ID: self.node_id,
ATTR_CHILD_ID: self.child_id,
ATTR_BATTERY_LEVEL: self.battery_level,
}

set_req = self.gateway.const.SetReq
Expand All @@ -307,7 +320,7 @@ def device_state_attributes(self):
except ValueError:
_LOGGER.error('Value_type %s is not valid for mysensors '
'version %s', value_type,
self.gateway.version)
self.gateway.protocol_version)
return attr

@property
Expand All @@ -319,7 +332,6 @@ def update(self):
"""Update the controller with the latest value from a sensor."""
node = self.gateway.sensors[self.node_id]
child = node.children[self.child_id]
self.battery_level = node.battery_level
set_req = self.gateway.const.SetReq
for value_type, value in child.values.items():
_LOGGER.debug(
Expand Down
6 changes: 3 additions & 3 deletions homeassistant/components/sensor/mysensors.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,12 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
pres.S_SCENE_CONTROLLER: [set_req.V_SCENE_ON,
set_req.V_SCENE_OFF],
}
if float(gateway.version) < 1.5:
if float(gateway.protocol_version) < 1.5:
map_sv_types.update({
pres.S_AIR_QUALITY: [set_req.V_DUST_LEVEL],
pres.S_DUST: [set_req.V_DUST_LEVEL],
})
if float(gateway.version) >= 1.5:
if float(gateway.protocol_version) >= 1.5:
map_sv_types.update({
pres.S_COLOR_SENSOR: [set_req.V_RGB],
pres.S_MULTIMETER: [set_req.V_VOLTAGE,
Expand Down Expand Up @@ -99,7 +99,7 @@ def unit_of_measurement(self):
set_req.V_VOLTAGE: 'V',
set_req.V_CURRENT: 'A',
}
if float(self.gateway.version) >= 1.5:
if float(self.gateway.protocol_version) >= 1.5:
if set_req.V_UNIT_PREFIX in self._values:
return self._values[
set_req.V_UNIT_PREFIX]
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/switch/mysensors.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
pres.S_LOCK: MySensorsSwitch,
pres.S_IR: MySensorsIRSwitch,
}
if float(gateway.version) >= 1.5:
if float(gateway.protocol_version) >= 1.5:
map_sv_types.update({
pres.S_BINARY: [set_req.V_STATUS, set_req.V_LIGHT],
pres.S_SPRINKLER: [set_req.V_STATUS],
Expand Down
0