Remove global variable from zigbee (#33750)
* Remove global variable from zigbee * Pass device instead of hass into the constructorpull/33789/head
parent
894aac1b45
commit
325e5416ef
|
@ -33,20 +33,8 @@ DEFAULT_DEVICE = "/dev/ttyUSB0"
|
|||
DEFAULT_BAUD = 9600
|
||||
DEFAULT_ADC_MAX_VOLTS = 1.2
|
||||
|
||||
# Copied from xbee_helper during setup()
|
||||
GPIO_DIGITAL_OUTPUT_LOW = None
|
||||
GPIO_DIGITAL_OUTPUT_HIGH = None
|
||||
ADC_PERCENTAGE = None
|
||||
DIGITAL_PINS = None
|
||||
ANALOG_PINS = None
|
||||
CONVERT_ADC = None
|
||||
ZIGBEE_EXCEPTION = None
|
||||
ZIGBEE_TX_FAILURE = None
|
||||
|
||||
ATTR_FRAME = "frame"
|
||||
|
||||
DEVICE = None
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema(
|
||||
{
|
||||
DOMAIN: vol.Schema(
|
||||
|
@ -71,24 +59,6 @@ PLATFORM_SCHEMA = vol.Schema(
|
|||
|
||||
def setup(hass, config):
|
||||
"""Set up the connection to the Zigbee device."""
|
||||
global DEVICE # pylint: disable=global-statement
|
||||
global GPIO_DIGITAL_OUTPUT_LOW # pylint: disable=global-statement
|
||||
global GPIO_DIGITAL_OUTPUT_HIGH # pylint: disable=global-statement
|
||||
global ADC_PERCENTAGE # pylint: disable=global-statement
|
||||
global DIGITAL_PINS # pylint: disable=global-statement
|
||||
global ANALOG_PINS # pylint: disable=global-statement
|
||||
global CONVERT_ADC # pylint: disable=global-statement
|
||||
global ZIGBEE_EXCEPTION # pylint: disable=global-statement
|
||||
global ZIGBEE_TX_FAILURE # pylint: disable=global-statement
|
||||
|
||||
GPIO_DIGITAL_OUTPUT_LOW = xb_const.GPIO_DIGITAL_OUTPUT_LOW
|
||||
GPIO_DIGITAL_OUTPUT_HIGH = xb_const.GPIO_DIGITAL_OUTPUT_HIGH
|
||||
ADC_PERCENTAGE = xb_const.ADC_PERCENTAGE
|
||||
DIGITAL_PINS = xb_const.DIGITAL_PINS
|
||||
ANALOG_PINS = xb_const.ANALOG_PINS
|
||||
CONVERT_ADC = convert_adc
|
||||
ZIGBEE_EXCEPTION = ZigBeeException
|
||||
ZIGBEE_TX_FAILURE = ZigBeeTxFailure
|
||||
|
||||
usb_device = config[DOMAIN].get(CONF_DEVICE, DEFAULT_DEVICE)
|
||||
baud = int(config[DOMAIN].get(CONF_BAUD, DEFAULT_BAUD))
|
||||
|
@ -97,8 +67,11 @@ def setup(hass, config):
|
|||
except SerialException as exc:
|
||||
_LOGGER.exception("Unable to open serial port for Zigbee: %s", exc)
|
||||
return False
|
||||
DEVICE = ZigBee(ser)
|
||||
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, close_serial_port)
|
||||
zigbee_device = ZigBee(ser)
|
||||
|
||||
def close_serial_port(*args):
|
||||
"""Close the serial port we're using to communicate with the Zigbee."""
|
||||
zigbee_device.zb.serial.close()
|
||||
|
||||
def _frame_received(frame):
|
||||
"""Run when a Zigbee frame is received.
|
||||
|
@ -108,16 +81,13 @@ def setup(hass, config):
|
|||
"""
|
||||
dispatcher_send(hass, SIGNAL_ZIGBEE_FRAME_RECEIVED, frame)
|
||||
|
||||
DEVICE.add_frame_rx_handler(_frame_received)
|
||||
hass.data[DOMAIN] = zigbee_device
|
||||
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, close_serial_port)
|
||||
zigbee_device.add_frame_rx_handler(_frame_received)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def close_serial_port(*args):
|
||||
"""Close the serial port we're using to communicate with the Zigbee."""
|
||||
DEVICE.zb.serial.close()
|
||||
|
||||
|
||||
def frame_is_relevant(entity, frame):
|
||||
"""Test whether the frame is relevant to the entity."""
|
||||
if frame.get("source_addr_long") != entity.config.address:
|
||||
|
@ -229,13 +199,13 @@ class ZigBeeDigitalOutConfig(ZigBeePinConfig):
|
|||
"""
|
||||
if self._config.get("on_state", "").lower() == "low":
|
||||
bool2state = {
|
||||
True: GPIO_DIGITAL_OUTPUT_LOW,
|
||||
False: GPIO_DIGITAL_OUTPUT_HIGH,
|
||||
True: xb_const.GPIO_DIGITAL_OUTPUT_LOW,
|
||||
False: xb_const.GPIO_DIGITAL_OUTPUT_HIGH,
|
||||
}
|
||||
else:
|
||||
bool2state = {
|
||||
True: GPIO_DIGITAL_OUTPUT_HIGH,
|
||||
False: GPIO_DIGITAL_OUTPUT_LOW,
|
||||
True: xb_const.GPIO_DIGITAL_OUTPUT_HIGH,
|
||||
False: xb_const.GPIO_DIGITAL_OUTPUT_LOW,
|
||||
}
|
||||
state2bool = {v: k for k, v in bool2state.items()}
|
||||
return bool2state, state2bool
|
||||
|
@ -269,9 +239,10 @@ class ZigBeeAnalogInConfig(ZigBeePinConfig):
|
|||
class ZigBeeDigitalIn(Entity):
|
||||
"""Representation of a GPIO pin configured as a digital input."""
|
||||
|
||||
def __init__(self, hass, config):
|
||||
def __init__(self, config, device):
|
||||
"""Initialize the device."""
|
||||
self._config = config
|
||||
self._device = device
|
||||
self._state = False
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
|
@ -286,7 +257,7 @@ class ZigBeeDigitalIn(Entity):
|
|||
if not frame_is_relevant(self, frame):
|
||||
return
|
||||
sample = next(iter(frame["samples"]))
|
||||
pin_name = DIGITAL_PINS[self._config.pin]
|
||||
pin_name = xb_const.DIGITAL_PINS[self._config.pin]
|
||||
if pin_name not in sample:
|
||||
# Doesn't contain information about our pin
|
||||
return
|
||||
|
@ -322,18 +293,18 @@ class ZigBeeDigitalIn(Entity):
|
|||
def update(self):
|
||||
"""Ask the Zigbee device what state its input pin is in."""
|
||||
try:
|
||||
sample = DEVICE.get_sample(self._config.address)
|
||||
except ZIGBEE_TX_FAILURE:
|
||||
sample = self._device.get_sample(self._config.address)
|
||||
except ZigBeeTxFailure:
|
||||
_LOGGER.warning(
|
||||
"Transmission failure when attempting to get sample from "
|
||||
"Zigbee device at address: %s",
|
||||
hexlify(self._config.address),
|
||||
)
|
||||
return
|
||||
except ZIGBEE_EXCEPTION as exc:
|
||||
except ZigBeeException as exc:
|
||||
_LOGGER.exception("Unable to get sample from Zigbee device: %s", exc)
|
||||
return
|
||||
pin_name = DIGITAL_PINS[self._config.pin]
|
||||
pin_name = xb_const.DIGITAL_PINS[self._config.pin]
|
||||
if pin_name not in sample:
|
||||
_LOGGER.warning(
|
||||
"Pin %s (%s) was not in the sample provided by Zigbee device %s.",
|
||||
|
@ -351,17 +322,17 @@ class ZigBeeDigitalOut(ZigBeeDigitalIn):
|
|||
def _set_state(self, state):
|
||||
"""Initialize the Zigbee digital out device."""
|
||||
try:
|
||||
DEVICE.set_gpio_pin(
|
||||
self._device.set_gpio_pin(
|
||||
self._config.pin, self._config.bool2state[state], self._config.address
|
||||
)
|
||||
except ZIGBEE_TX_FAILURE:
|
||||
except ZigBeeTxFailure:
|
||||
_LOGGER.warning(
|
||||
"Transmission failure when attempting to set output pin on "
|
||||
"Zigbee device at address: %s",
|
||||
hexlify(self._config.address),
|
||||
)
|
||||
return
|
||||
except ZIGBEE_EXCEPTION as exc:
|
||||
except ZigBeeException as exc:
|
||||
_LOGGER.exception("Unable to set digital pin on Zigbee device: %s", exc)
|
||||
return
|
||||
self._state = state
|
||||
|
@ -379,15 +350,17 @@ class ZigBeeDigitalOut(ZigBeeDigitalIn):
|
|||
def update(self):
|
||||
"""Ask the Zigbee device what its output is set to."""
|
||||
try:
|
||||
pin_state = DEVICE.get_gpio_pin(self._config.pin, self._config.address)
|
||||
except ZIGBEE_TX_FAILURE:
|
||||
pin_state = self._device.get_gpio_pin(
|
||||
self._config.pin, self._config.address
|
||||
)
|
||||
except ZigBeeTxFailure:
|
||||
_LOGGER.warning(
|
||||
"Transmission failure when attempting to get output pin status"
|
||||
" from Zigbee device at address: %s",
|
||||
hexlify(self._config.address),
|
||||
)
|
||||
return
|
||||
except ZIGBEE_EXCEPTION as exc:
|
||||
except ZigBeeException as exc:
|
||||
_LOGGER.exception(
|
||||
"Unable to get output pin status from Zigbee device: %s", exc
|
||||
)
|
||||
|
@ -398,9 +371,10 @@ class ZigBeeDigitalOut(ZigBeeDigitalIn):
|
|||
class ZigBeeAnalogIn(Entity):
|
||||
"""Representation of a GPIO pin configured as an analog input."""
|
||||
|
||||
def __init__(self, hass, config):
|
||||
def __init__(self, config, device):
|
||||
"""Initialize the ZigBee analog in device."""
|
||||
self._config = config
|
||||
self._device = device
|
||||
self._value = None
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
|
@ -415,12 +389,12 @@ class ZigBeeAnalogIn(Entity):
|
|||
if not frame_is_relevant(self, frame):
|
||||
return
|
||||
sample = frame["samples"].pop()
|
||||
pin_name = ANALOG_PINS[self._config.pin]
|
||||
pin_name = xb_const.ANALOG_PINS[self._config.pin]
|
||||
if pin_name not in sample:
|
||||
# Doesn't contain information about our pin
|
||||
return
|
||||
self._value = CONVERT_ADC(
|
||||
sample[pin_name], ADC_PERCENTAGE, self._config.max_voltage
|
||||
self._value = convert_adc(
|
||||
sample[pin_name], xb_const.ADC_PERCENTAGE, self._config.max_voltage
|
||||
)
|
||||
self.schedule_update_ha_state()
|
||||
|
||||
|
@ -454,17 +428,17 @@ class ZigBeeAnalogIn(Entity):
|
|||
def update(self):
|
||||
"""Get the latest reading from the ADC."""
|
||||
try:
|
||||
self._value = DEVICE.read_analog_pin(
|
||||
self._value = self._device.read_analog_pin(
|
||||
self._config.pin,
|
||||
self._config.max_voltage,
|
||||
self._config.address,
|
||||
ADC_PERCENTAGE,
|
||||
xb_const.ADC_PERCENTAGE,
|
||||
)
|
||||
except ZIGBEE_TX_FAILURE:
|
||||
except ZigBeeTxFailure:
|
||||
_LOGGER.warning(
|
||||
"Transmission failure when attempting to get sample from "
|
||||
"Zigbee device at address: %s",
|
||||
hexlify(self._config.address),
|
||||
)
|
||||
except ZIGBEE_EXCEPTION as exc:
|
||||
except ZigBeeException as exc:
|
||||
_LOGGER.exception("Unable to get sample from Zigbee device: %s", exc)
|
||||
|
|
|
@ -3,7 +3,7 @@ import voluptuous as vol
|
|||
|
||||
from homeassistant.components.binary_sensor import BinarySensorDevice
|
||||
|
||||
from . import PLATFORM_SCHEMA, ZigBeeDigitalIn, ZigBeeDigitalInConfig
|
||||
from . import DOMAIN, PLATFORM_SCHEMA, ZigBeeDigitalIn, ZigBeeDigitalInConfig
|
||||
|
||||
CONF_ON_STATE = "on_state"
|
||||
|
||||
|
@ -15,7 +15,10 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({vol.Optional(CONF_ON_STATE): vol.In(ST
|
|||
|
||||
def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||
"""Set up the Zigbee binary sensor platform."""
|
||||
add_entities([ZigBeeBinarySensor(hass, ZigBeeDigitalInConfig(config))], True)
|
||||
zigbee_device = hass.data[DOMAIN]
|
||||
add_entities(
|
||||
[ZigBeeBinarySensor(ZigBeeDigitalInConfig(config), zigbee_device)], True
|
||||
)
|
||||
|
||||
|
||||
class ZigBeeBinarySensor(ZigBeeDigitalIn, BinarySensorDevice):
|
||||
|
|
|
@ -3,7 +3,7 @@ import voluptuous as vol
|
|||
|
||||
from homeassistant.components.light import Light
|
||||
|
||||
from . import PLATFORM_SCHEMA, ZigBeeDigitalOut, ZigBeeDigitalOutConfig
|
||||
from . import DOMAIN, PLATFORM_SCHEMA, ZigBeeDigitalOut, ZigBeeDigitalOutConfig
|
||||
|
||||
CONF_ON_STATE = "on_state"
|
||||
|
||||
|
@ -17,7 +17,8 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
|||
|
||||
def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||
"""Create and add an entity based on the configuration."""
|
||||
add_entities([ZigBeeLight(hass, ZigBeeDigitalOutConfig(config))])
|
||||
zigbee_device = hass.data[DOMAIN]
|
||||
add_entities([ZigBeeLight(ZigBeeDigitalOutConfig(config), zigbee_device)])
|
||||
|
||||
|
||||
class ZigBeeLight(ZigBeeDigitalOut, Light):
|
||||
|
|
|
@ -3,12 +3,18 @@ from binascii import hexlify
|
|||
import logging
|
||||
|
||||
import voluptuous as vol
|
||||
from xbee_helper.exceptions import ZigBeeException, ZigBeeTxFailure
|
||||
|
||||
from homeassistant.components import zigbee
|
||||
from homeassistant.const import TEMP_CELSIUS
|
||||
from homeassistant.helpers.entity import Entity
|
||||
|
||||
from . import PLATFORM_SCHEMA
|
||||
from . import (
|
||||
DOMAIN,
|
||||
PLATFORM_SCHEMA,
|
||||
ZigBeeAnalogIn,
|
||||
ZigBeeAnalogInConfig,
|
||||
ZigBeeConfig,
|
||||
)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@ -32,6 +38,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
|||
Uses the 'type' config value to work out which type of Zigbee sensor we're
|
||||
dealing with and instantiates the relevant classes to handle it.
|
||||
"""
|
||||
zigbee_device = hass.data[DOMAIN]
|
||||
typ = config.get(CONF_TYPE)
|
||||
|
||||
try:
|
||||
|
@ -40,15 +47,16 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
|||
_LOGGER.exception("Unknown Zigbee sensor type: %s", typ)
|
||||
return
|
||||
|
||||
add_entities([sensor_class(hass, config_class(config))], True)
|
||||
add_entities([sensor_class(config_class(config), zigbee_device)], True)
|
||||
|
||||
|
||||
class ZigBeeTemperatureSensor(Entity):
|
||||
"""Representation of XBee Pro temperature sensor."""
|
||||
|
||||
def __init__(self, hass, config):
|
||||
def __init__(self, config, device):
|
||||
"""Initialize the sensor."""
|
||||
self._config = config
|
||||
self._device = device
|
||||
self._temp = None
|
||||
|
||||
@property
|
||||
|
@ -69,19 +77,19 @@ class ZigBeeTemperatureSensor(Entity):
|
|||
def update(self):
|
||||
"""Get the latest data."""
|
||||
try:
|
||||
self._temp = zigbee.DEVICE.get_temperature(self._config.address)
|
||||
except zigbee.ZIGBEE_TX_FAILURE:
|
||||
self._temp = self._device.get_temperature(self._config.address)
|
||||
except ZigBeeTxFailure:
|
||||
_LOGGER.warning(
|
||||
"Transmission failure when attempting to get sample from "
|
||||
"Zigbee device at address: %s",
|
||||
hexlify(self._config.address),
|
||||
)
|
||||
except zigbee.ZIGBEE_EXCEPTION as exc:
|
||||
except ZigBeeException as exc:
|
||||
_LOGGER.exception("Unable to get sample from Zigbee device: %s", exc)
|
||||
|
||||
|
||||
# This must be below the classes to which it refers.
|
||||
TYPE_CLASSES = {
|
||||
"temperature": (ZigBeeTemperatureSensor, zigbee.ZigBeeConfig),
|
||||
"analog": (zigbee.ZigBeeAnalogIn, zigbee.ZigBeeAnalogInConfig),
|
||||
"temperature": (ZigBeeTemperatureSensor, ZigBeeConfig),
|
||||
"analog": (ZigBeeAnalogIn, ZigBeeAnalogInConfig),
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ import voluptuous as vol
|
|||
|
||||
from homeassistant.components.switch import SwitchDevice
|
||||
|
||||
from . import PLATFORM_SCHEMA, ZigBeeDigitalOut, ZigBeeDigitalOutConfig
|
||||
from . import DOMAIN, PLATFORM_SCHEMA, ZigBeeDigitalOut, ZigBeeDigitalOutConfig
|
||||
|
||||
CONF_ON_STATE = "on_state"
|
||||
|
||||
|
@ -16,7 +16,8 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({vol.Optional(CONF_ON_STATE): vol.In(ST
|
|||
|
||||
def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||
"""Set up the Zigbee switch platform."""
|
||||
add_entities([ZigBeeSwitch(hass, ZigBeeDigitalOutConfig(config))])
|
||||
zigbee_device = hass.data[DOMAIN]
|
||||
add_entities([ZigBeeSwitch(ZigBeeDigitalOutConfig(config), zigbee_device)])
|
||||
|
||||
|
||||
class ZigBeeSwitch(ZigBeeDigitalOut, SwitchDevice):
|
||||
|
|
Loading…
Reference in New Issue