Add mysensors tcp ethernet gateway (#1861)
* Bump version of pymysensors to 0.6, which includes the tcp gateway. * Update requirements_all.txt. * Replace CONF_PORT with CONF_DEVICE and ATTR_PORT with ATTR_DEVICE. * Add tcp_port in config. * Try to guess if tcp or serial gateway is configured, by validating device name as an ip address. If successful setup tcp gateway, if it fails, setup serial gateway. * Update device_state_attributes to show correct device, ethernet or serial.pull/1862/head
parent
2e79e9d5bb
commit
9d391becc1
|
@ -6,10 +6,9 @@ https://home-assistant.io/components/binary_sensor.mysensors/
|
|||
"""
|
||||
import logging
|
||||
|
||||
from homeassistant.const import (
|
||||
ATTR_BATTERY_LEVEL, STATE_OFF, STATE_ON)
|
||||
from homeassistant.components.binary_sensor import (
|
||||
BinarySensorDevice, SENSOR_CLASSES)
|
||||
from homeassistant.components.binary_sensor import (SENSOR_CLASSES,
|
||||
BinarySensorDevice)
|
||||
from homeassistant.const import ATTR_BATTERY_LEVEL, STATE_OFF, STATE_ON
|
||||
from homeassistant.loader import get_component
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
@ -101,8 +100,13 @@ class MySensorsBinarySensor(BinarySensorDevice):
|
|||
@property
|
||||
def device_state_attributes(self):
|
||||
"""Return device specific state attributes."""
|
||||
address = getattr(self.gateway, 'server_address', None)
|
||||
if address:
|
||||
device = '{}:{}'.format(address[0], address[1])
|
||||
else:
|
||||
device = self.gateway.port
|
||||
attr = {
|
||||
self.mysensors.ATTR_PORT: self.gateway.port,
|
||||
self.mysensors.ATTR_DEVICE: device,
|
||||
self.mysensors.ATTR_NODE_ID: self.node_id,
|
||||
self.mysensors.ATTR_CHILD_ID: self.child_id,
|
||||
ATTR_BATTERY_LEVEL: self.battery_level,
|
||||
|
|
|
@ -6,8 +6,8 @@ https://home-assistant.io/components/light.mysensors/
|
|||
"""
|
||||
import logging
|
||||
|
||||
from homeassistant.components.light import (
|
||||
ATTR_BRIGHTNESS, ATTR_RGB_COLOR, Light)
|
||||
from homeassistant.components.light import (ATTR_BRIGHTNESS, ATTR_RGB_COLOR,
|
||||
Light)
|
||||
from homeassistant.const import ATTR_BATTERY_LEVEL, STATE_OFF, STATE_ON
|
||||
from homeassistant.loader import get_component
|
||||
from homeassistant.util.color import rgb_hex_to_rgb_list
|
||||
|
@ -100,15 +100,20 @@ class MySensorsLight(Light):
|
|||
@property
|
||||
def device_state_attributes(self):
|
||||
"""Return device specific state attributes."""
|
||||
device_attr = {
|
||||
self.mysensors.ATTR_PORT: self.gateway.port,
|
||||
address = getattr(self.gateway, 'server_address', None)
|
||||
if address:
|
||||
device = '{}:{}'.format(address[0], address[1])
|
||||
else:
|
||||
device = self.gateway.port
|
||||
attr = {
|
||||
self.mysensors.ATTR_DEVICE: device,
|
||||
self.mysensors.ATTR_NODE_ID: self.node_id,
|
||||
self.mysensors.ATTR_CHILD_ID: self.child_id,
|
||||
ATTR_BATTERY_LEVEL: self.battery_level,
|
||||
}
|
||||
for value_type, value in self._values.items():
|
||||
device_attr[self.gateway.const.SetReq(value_type).name] = value
|
||||
return device_attr
|
||||
attr[self.gateway.const.SetReq(value_type).name] = value
|
||||
return attr
|
||||
|
||||
@property
|
||||
def available(self):
|
||||
|
|
|
@ -5,33 +5,36 @@ For more details about this platform, please refer to the documentation at
|
|||
https://home-assistant.io/components/sensor.mysensors/
|
||||
"""
|
||||
import logging
|
||||
import socket
|
||||
|
||||
import homeassistant.bootstrap as bootstrap
|
||||
from homeassistant.const import (
|
||||
ATTR_DISCOVERED, ATTR_SERVICE, EVENT_HOMEASSISTANT_START,
|
||||
EVENT_HOMEASSISTANT_STOP, EVENT_PLATFORM_DISCOVERED, TEMP_CELSIUS,
|
||||
CONF_OPTIMISTIC)
|
||||
from homeassistant.const import (ATTR_DISCOVERED, ATTR_SERVICE,
|
||||
CONF_OPTIMISTIC, EVENT_HOMEASSISTANT_START,
|
||||
EVENT_HOMEASSISTANT_STOP,
|
||||
EVENT_PLATFORM_DISCOVERED, TEMP_CELSIUS)
|
||||
from homeassistant.helpers import validate_config
|
||||
|
||||
CONF_GATEWAYS = 'gateways'
|
||||
CONF_PORT = 'port'
|
||||
CONF_DEVICE = 'device'
|
||||
CONF_DEBUG = 'debug'
|
||||
CONF_PERSISTENCE = 'persistence'
|
||||
CONF_PERSISTENCE_FILE = 'persistence_file'
|
||||
CONF_VERSION = 'version'
|
||||
CONF_BAUD_RATE = 'baud_rate'
|
||||
CONF_TCP_PORT = 'tcp_port'
|
||||
DEFAULT_VERSION = '1.4'
|
||||
DEFAULT_BAUD_RATE = 115200
|
||||
DEFAULT_TCP_PORT = 5003
|
||||
|
||||
DOMAIN = 'mysensors'
|
||||
DEPENDENCIES = []
|
||||
REQUIREMENTS = [
|
||||
'https://github.com/theolind/pymysensors/archive/'
|
||||
'f0c928532167fb24823efa793ec21ca646fd37a6.zip#pymysensors==0.5']
|
||||
'cc5d0b325e13c2b623fa934f69eea7cd4555f110.zip#pymysensors==0.6']
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
ATTR_NODE_ID = 'node_id'
|
||||
ATTR_CHILD_ID = 'child_id'
|
||||
ATTR_PORT = 'port'
|
||||
ATTR_DEVICE = 'device'
|
||||
|
||||
GATEWAYS = None
|
||||
|
||||
|
@ -49,30 +52,39 @@ DISCOVERY_COMPONENTS = [
|
|||
]
|
||||
|
||||
|
||||
def setup(hass, config):
|
||||
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_PORT in gateway
|
||||
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_PORT)
|
||||
'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.temperature_unit == TEMP_CELSIUS)
|
||||
persistence = config[DOMAIN].get(CONF_PERSISTENCE, True)
|
||||
|
||||
def setup_gateway(port, persistence, persistence_file, version, baud_rate):
|
||||
def setup_gateway(device, persistence_file, baud_rate, tcp_port):
|
||||
"""Return gateway after setup of the gateway."""
|
||||
gateway = mysensors.SerialGateway(port, event_callback=None,
|
||||
persistence=persistence,
|
||||
persistence_file=persistence_file,
|
||||
protocol_version=version,
|
||||
baud=baud_rate)
|
||||
try:
|
||||
socket.inet_aton(device)
|
||||
# valid ip address
|
||||
gateway = mysensors.TCPGateway(
|
||||
device, event_callback=None, persistence=persistence,
|
||||
persistence_file=persistence_file, protocol_version=version,
|
||||
port=tcp_port)
|
||||
except OSError:
|
||||
# invalid ip address
|
||||
gateway = mysensors.SerialGateway(
|
||||
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)
|
||||
|
@ -93,22 +105,22 @@ def setup(hass, config):
|
|||
|
||||
return gateway
|
||||
|
||||
# Setup all ports from config
|
||||
# Setup all devices from config
|
||||
global GATEWAYS
|
||||
GATEWAYS = {}
|
||||
conf_gateways = config[DOMAIN][CONF_GATEWAYS]
|
||||
if isinstance(conf_gateways, dict):
|
||||
conf_gateways = [conf_gateways]
|
||||
persistence = config[DOMAIN].get(CONF_PERSISTENCE, True)
|
||||
|
||||
for index, gway in enumerate(conf_gateways):
|
||||
port = gway[CONF_PORT]
|
||||
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)
|
||||
GATEWAYS[port] = setup_gateway(
|
||||
port, persistence, persistence_file, version, baud_rate)
|
||||
tcp_port = gway.get(CONF_TCP_PORT, DEFAULT_TCP_PORT)
|
||||
GATEWAYS[device] = setup_gateway(
|
||||
device, persistence_file, baud_rate, tcp_port)
|
||||
|
||||
for (component, discovery_service) in DISCOVERY_COMPONENTS:
|
||||
# Ensure component is loaded
|
||||
|
|
|
@ -6,8 +6,8 @@ https://home-assistant.io/components/sensor.mysensors/
|
|||
"""
|
||||
import logging
|
||||
|
||||
from homeassistant.const import (
|
||||
ATTR_BATTERY_LEVEL, STATE_OFF, STATE_ON, TEMP_CELSIUS, TEMP_FAHRENHEIT)
|
||||
from homeassistant.const import (ATTR_BATTERY_LEVEL, STATE_OFF, STATE_ON,
|
||||
TEMP_CELSIUS, TEMP_FAHRENHEIT)
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.loader import get_component
|
||||
|
||||
|
@ -157,8 +157,13 @@ class MySensorsSensor(Entity):
|
|||
@property
|
||||
def device_state_attributes(self):
|
||||
"""Return device specific state attributes."""
|
||||
address = getattr(self.gateway, 'server_address', None)
|
||||
if address:
|
||||
device = '{}:{}'.format(address[0], address[1])
|
||||
else:
|
||||
device = self.gateway.port
|
||||
attr = {
|
||||
self.mysensors.ATTR_PORT: self.gateway.port,
|
||||
self.mysensors.ATTR_DEVICE: device,
|
||||
self.mysensors.ATTR_NODE_ID: self.node_id,
|
||||
self.mysensors.ATTR_CHILD_ID: self.child_id,
|
||||
ATTR_BATTERY_LEVEL: self.battery_level,
|
||||
|
|
|
@ -99,8 +99,13 @@ class MySensorsSwitch(SwitchDevice):
|
|||
@property
|
||||
def device_state_attributes(self):
|
||||
"""Return device specific state attributes."""
|
||||
address = getattr(self.gateway, 'server_address', None)
|
||||
if address:
|
||||
device = '{}:{}'.format(address[0], address[1])
|
||||
else:
|
||||
device = self.gateway.port
|
||||
attr = {
|
||||
self.mysensors.ATTR_PORT: self.gateway.port,
|
||||
self.mysensors.ATTR_DEVICE: device,
|
||||
self.mysensors.ATTR_NODE_ID: self.node_id,
|
||||
self.mysensors.ATTR_CHILD_ID: self.child_id,
|
||||
ATTR_BATTERY_LEVEL: self.battery_level,
|
||||
|
|
|
@ -31,7 +31,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||
return True
|
||||
|
||||
|
||||
# pylint: disable=too-many-instance-attributes
|
||||
# pylint: disable=too-many-instance-attributes, import-error
|
||||
class EQ3BTSmartThermostat(ThermostatDevice):
|
||||
"""Representation of a EQ3 Bluetooth Smart thermostat."""
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ blinkstick==1.1.7
|
|||
blockchain==1.3.1
|
||||
|
||||
# homeassistant.components.thermostat.eq3btsmart
|
||||
bluepy_devices>=0.2.0
|
||||
# bluepy_devices>=0.2.0
|
||||
|
||||
# homeassistant.components.notify.xmpp
|
||||
dnspython3==1.12.0
|
||||
|
@ -117,7 +117,7 @@ https://github.com/robbiet480/pygtfs/archive/432414b720c580fb2667a0a48f539118a2d
|
|||
https://github.com/sander76/powerviewApi/archive/master.zip#powerviewApi==0.2
|
||||
|
||||
# homeassistant.components.mysensors
|
||||
https://github.com/theolind/pymysensors/archive/f0c928532167fb24823efa793ec21ca646fd37a6.zip#pymysensors==0.5
|
||||
https://github.com/theolind/pymysensors/archive/cc5d0b325e13c2b623fa934f69eea7cd4555f110.zip#pymysensors==0.6
|
||||
|
||||
# homeassistant.components.notify.googlevoice
|
||||
https://github.com/w1ll1am23/pygooglevoice-sms/archive/7c5ee9969b97a7992fc86a753fe9f20e3ffa3f7c.zip#pygooglevoice-sms==0.0.1
|
||||
|
|
|
@ -11,6 +11,7 @@ COMMENT_REQUIREMENTS = [
|
|||
'Adafruit_Python_DHT',
|
||||
'fritzconnection',
|
||||
'pybluez',
|
||||
'bluepy',
|
||||
]
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue