Skip to content

Commit 325e541

Browse files
authored
Remove global variable from zigbee (home-assistant#33750)
* Remove global variable from zigbee * Pass device instead of hass into the constructor
1 parent 894aac1 commit 325e541

File tree

5 files changed

+64
-77
lines changed

5 files changed

+64
-77
lines changed

homeassistant/components/zigbee/__init__.py

+36-62
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,8 @@
3333
DEFAULT_BAUD = 9600
3434
DEFAULT_ADC_MAX_VOLTS = 1.2
3535

36-
# Copied from xbee_helper during setup()
37-
GPIO_DIGITAL_OUTPUT_LOW = None
38-
GPIO_DIGITAL_OUTPUT_HIGH = None
39-
ADC_PERCENTAGE = None
40-
DIGITAL_PINS = None
41-
ANALOG_PINS = None
42-
CONVERT_ADC = None
43-
ZIGBEE_EXCEPTION = None
44-
ZIGBEE_TX_FAILURE = None
45-
4636
ATTR_FRAME = "frame"
4737

48-
DEVICE = None
49-
5038
CONFIG_SCHEMA = vol.Schema(
5139
{
5240
DOMAIN: vol.Schema(
@@ -71,24 +59,6 @@
7159

7260
def setup(hass, config):
7361
"""Set up the connection to the Zigbee device."""
74-
global DEVICE # pylint: disable=global-statement
75-
global GPIO_DIGITAL_OUTPUT_LOW # pylint: disable=global-statement
76-
global GPIO_DIGITAL_OUTPUT_HIGH # pylint: disable=global-statement
77-
global ADC_PERCENTAGE # pylint: disable=global-statement
78-
global DIGITAL_PINS # pylint: disable=global-statement
79-
global ANALOG_PINS # pylint: disable=global-statement
80-
global CONVERT_ADC # pylint: disable=global-statement
81-
global ZIGBEE_EXCEPTION # pylint: disable=global-statement
82-
global ZIGBEE_TX_FAILURE # pylint: disable=global-statement
83-
84-
GPIO_DIGITAL_OUTPUT_LOW = xb_const.GPIO_DIGITAL_OUTPUT_LOW
85-
GPIO_DIGITAL_OUTPUT_HIGH = xb_const.GPIO_DIGITAL_OUTPUT_HIGH
86-
ADC_PERCENTAGE = xb_const.ADC_PERCENTAGE
87-
DIGITAL_PINS = xb_const.DIGITAL_PINS
88-
ANALOG_PINS = xb_const.ANALOG_PINS
89-
CONVERT_ADC = convert_adc
90-
ZIGBEE_EXCEPTION = ZigBeeException
91-
ZIGBEE_TX_FAILURE = ZigBeeTxFailure
9262

9363
usb_device = config[DOMAIN].get(CONF_DEVICE, DEFAULT_DEVICE)
9464
baud = int(config[DOMAIN].get(CONF_BAUD, DEFAULT_BAUD))
@@ -97,8 +67,11 @@ def setup(hass, config):
9767
except SerialException as exc:
9868
_LOGGER.exception("Unable to open serial port for Zigbee: %s", exc)
9969
return False
100-
DEVICE = ZigBee(ser)
101-
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, close_serial_port)
70+
zigbee_device = ZigBee(ser)
71+
72+
def close_serial_port(*args):
73+
"""Close the serial port we're using to communicate with the Zigbee."""
74+
zigbee_device.zb.serial.close()
10275

10376
def _frame_received(frame):
10477
"""Run when a Zigbee frame is received.
@@ -108,16 +81,13 @@ def _frame_received(frame):
10881
"""
10982
dispatcher_send(hass, SIGNAL_ZIGBEE_FRAME_RECEIVED, frame)
11083

111-
DEVICE.add_frame_rx_handler(_frame_received)
84+
hass.data[DOMAIN] = zigbee_device
85+
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, close_serial_port)
86+
zigbee_device.add_frame_rx_handler(_frame_received)
11287

11388
return True
11489

11590

116-
def close_serial_port(*args):
117-
"""Close the serial port we're using to communicate with the Zigbee."""
118-
DEVICE.zb.serial.close()
119-
120-
12191
def frame_is_relevant(entity, frame):
12292
"""Test whether the frame is relevant to the entity."""
12393
if frame.get("source_addr_long") != entity.config.address:
@@ -229,13 +199,13 @@ def boolean_maps(self):
229199
"""
230200
if self._config.get("on_state", "").lower() == "low":
231201
bool2state = {
232-
True: GPIO_DIGITAL_OUTPUT_LOW,
233-
False: GPIO_DIGITAL_OUTPUT_HIGH,
202+
True: xb_const.GPIO_DIGITAL_OUTPUT_LOW,
203+
False: xb_const.GPIO_DIGITAL_OUTPUT_HIGH,
234204
}
235205
else:
236206
bool2state = {
237-
True: GPIO_DIGITAL_OUTPUT_HIGH,
238-
False: GPIO_DIGITAL_OUTPUT_LOW,
207+
True: xb_const.GPIO_DIGITAL_OUTPUT_HIGH,
208+
False: xb_const.GPIO_DIGITAL_OUTPUT_LOW,
239209
}
240210
state2bool = {v: k for k, v in bool2state.items()}
241211
return bool2state, state2bool
@@ -269,9 +239,10 @@ def max_voltage(self):
269239
class ZigBeeDigitalIn(Entity):
270240
"""Representation of a GPIO pin configured as a digital input."""
271241

272-
def __init__(self, hass, config):
242+
def __init__(self, config, device):
273243
"""Initialize the device."""
274244
self._config = config
245+
self._device = device
275246
self._state = False
276247

277248
async def async_added_to_hass(self):
@@ -286,7 +257,7 @@ def handle_frame(frame):
286257
if not frame_is_relevant(self, frame):
287258
return
288259
sample = next(iter(frame["samples"]))
289-
pin_name = DIGITAL_PINS[self._config.pin]
260+
pin_name = xb_const.DIGITAL_PINS[self._config.pin]
290261
if pin_name not in sample:
291262
# Doesn't contain information about our pin
292263
return
@@ -322,18 +293,18 @@ def is_on(self):
322293
def update(self):
323294
"""Ask the Zigbee device what state its input pin is in."""
324295
try:
325-
sample = DEVICE.get_sample(self._config.address)
326-
except ZIGBEE_TX_FAILURE:
296+
sample = self._device.get_sample(self._config.address)
297+
except ZigBeeTxFailure:
327298
_LOGGER.warning(
328299
"Transmission failure when attempting to get sample from "
329300
"Zigbee device at address: %s",
330301
hexlify(self._config.address),
331302
)
332303
return
333-
except ZIGBEE_EXCEPTION as exc:
304+
except ZigBeeException as exc:
334305
_LOGGER.exception("Unable to get sample from Zigbee device: %s", exc)
335306
return
336-
pin_name = DIGITAL_PINS[self._config.pin]
307+
pin_name = xb_const.DIGITAL_PINS[self._config.pin]
337308
if pin_name not in sample:
338309
_LOGGER.warning(
339310
"Pin %s (%s) was not in the sample provided by Zigbee device %s.",
@@ -351,17 +322,17 @@ class ZigBeeDigitalOut(ZigBeeDigitalIn):
351322
def _set_state(self, state):
352323
"""Initialize the Zigbee digital out device."""
353324
try:
354-
DEVICE.set_gpio_pin(
325+
self._device.set_gpio_pin(
355326
self._config.pin, self._config.bool2state[state], self._config.address
356327
)
357-
except ZIGBEE_TX_FAILURE:
328+
except ZigBeeTxFailure:
358329
_LOGGER.warning(
359330
"Transmission failure when attempting to set output pin on "
360331
"Zigbee device at address: %s",
361332
hexlify(self._config.address),
362333
)
363334
return
364-
except ZIGBEE_EXCEPTION as exc:
335+
except ZigBeeException as exc:
365336
_LOGGER.exception("Unable to set digital pin on Zigbee device: %s", exc)
366337
return
367338
self._state = state
@@ -379,15 +350,17 @@ def turn_off(self, **kwargs):
379350
def update(self):
380351
"""Ask the Zigbee device what its output is set to."""
381352
try:
382-
pin_state = DEVICE.get_gpio_pin(self._config.pin, self._config.address)
383-
except ZIGBEE_TX_FAILURE:
353+
pin_state = self._device.get_gpio_pin(
354+
self._config.pin, self._config.address
355+
)
356+
except ZigBeeTxFailure:
384357
_LOGGER.warning(
385358
"Transmission failure when attempting to get output pin status"
386359
" from Zigbee device at address: %s",
387360
hexlify(self._config.address),
388361
)
389362
return
390-
except ZIGBEE_EXCEPTION as exc:
363+
except ZigBeeException as exc:
391364
_LOGGER.exception(
392365
"Unable to get output pin status from Zigbee device: %s", exc
393366
)
@@ -398,9 +371,10 @@ def update(self):
398371
class ZigBeeAnalogIn(Entity):
399372
"""Representation of a GPIO pin configured as an analog input."""
400373

401-
def __init__(self, hass, config):
374+
def __init__(self, config, device):
402375
"""Initialize the ZigBee analog in device."""
403376
self._config = config
377+
self._device = device
404378
self._value = None
405379

406380
async def async_added_to_hass(self):
@@ -415,12 +389,12 @@ def handle_frame(frame):
415389
if not frame_is_relevant(self, frame):
416390
return
417391
sample = frame["samples"].pop()
418-
pin_name = ANALOG_PINS[self._config.pin]
392+
pin_name = xb_const.ANALOG_PINS[self._config.pin]
419393
if pin_name not in sample:
420394
# Doesn't contain information about our pin
421395
return
422-
self._value = CONVERT_ADC(
423-
sample[pin_name], ADC_PERCENTAGE, self._config.max_voltage
396+
self._value = convert_adc(
397+
sample[pin_name], xb_const.ADC_PERCENTAGE, self._config.max_voltage
424398
)
425399
self.schedule_update_ha_state()
426400

@@ -454,17 +428,17 @@ def unit_of_measurement(self):
454428
def update(self):
455429
"""Get the latest reading from the ADC."""
456430
try:
457-
self._value = DEVICE.read_analog_pin(
431+
self._value = self._device.read_analog_pin(
458432
self._config.pin,
459433
self._config.max_voltage,
460434
self._config.address,
461-
ADC_PERCENTAGE,
435+
xb_const.ADC_PERCENTAGE,
462436
)
463-
except ZIGBEE_TX_FAILURE:
437+
except ZigBeeTxFailure:
464438
_LOGGER.warning(
465439
"Transmission failure when attempting to get sample from "
466440
"Zigbee device at address: %s",
467441
hexlify(self._config.address),
468442
)
469-
except ZIGBEE_EXCEPTION as exc:
443+
except ZigBeeException as exc:
470444
_LOGGER.exception("Unable to get sample from Zigbee device: %s", exc)

homeassistant/components/zigbee/binary_sensor.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from homeassistant.components.binary_sensor import BinarySensorDevice
55

6-
from . import PLATFORM_SCHEMA, ZigBeeDigitalIn, ZigBeeDigitalInConfig
6+
from . import DOMAIN, PLATFORM_SCHEMA, ZigBeeDigitalIn, ZigBeeDigitalInConfig
77

88
CONF_ON_STATE = "on_state"
99

@@ -15,7 +15,10 @@
1515

1616
def setup_platform(hass, config, add_entities, discovery_info=None):
1717
"""Set up the Zigbee binary sensor platform."""
18-
add_entities([ZigBeeBinarySensor(hass, ZigBeeDigitalInConfig(config))], True)
18+
zigbee_device = hass.data[DOMAIN]
19+
add_entities(
20+
[ZigBeeBinarySensor(ZigBeeDigitalInConfig(config), zigbee_device)], True
21+
)
1922

2023

2124
class ZigBeeBinarySensor(ZigBeeDigitalIn, BinarySensorDevice):

homeassistant/components/zigbee/light.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from homeassistant.components.light import Light
55

6-
from . import PLATFORM_SCHEMA, ZigBeeDigitalOut, ZigBeeDigitalOutConfig
6+
from . import DOMAIN, PLATFORM_SCHEMA, ZigBeeDigitalOut, ZigBeeDigitalOutConfig
77

88
CONF_ON_STATE = "on_state"
99

@@ -17,7 +17,8 @@
1717

1818
def setup_platform(hass, config, add_entities, discovery_info=None):
1919
"""Create and add an entity based on the configuration."""
20-
add_entities([ZigBeeLight(hass, ZigBeeDigitalOutConfig(config))])
20+
zigbee_device = hass.data[DOMAIN]
21+
add_entities([ZigBeeLight(ZigBeeDigitalOutConfig(config), zigbee_device)])
2122

2223

2324
class ZigBeeLight(ZigBeeDigitalOut, Light):

homeassistant/components/zigbee/sensor.py

+17-9
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,18 @@
33
import logging
44

55
import voluptuous as vol
6+
from xbee_helper.exceptions import ZigBeeException, ZigBeeTxFailure
67

7-
from homeassistant.components import zigbee
88
from homeassistant.const import TEMP_CELSIUS
99
from homeassistant.helpers.entity import Entity
1010

11-
from . import PLATFORM_SCHEMA
11+
from . import (
12+
DOMAIN,
13+
PLATFORM_SCHEMA,
14+
ZigBeeAnalogIn,
15+
ZigBeeAnalogInConfig,
16+
ZigBeeConfig,
17+
)
1218

1319
_LOGGER = logging.getLogger(__name__)
1420

@@ -32,6 +38,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
3238
Uses the 'type' config value to work out which type of Zigbee sensor we're
3339
dealing with and instantiates the relevant classes to handle it.
3440
"""
41+
zigbee_device = hass.data[DOMAIN]
3542
typ = config.get(CONF_TYPE)
3643

3744
try:
@@ -40,15 +47,16 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
4047
_LOGGER.exception("Unknown Zigbee sensor type: %s", typ)
4148
return
4249

43-
add_entities([sensor_class(hass, config_class(config))], True)
50+
add_entities([sensor_class(config_class(config), zigbee_device)], True)
4451

4552

4653
class ZigBeeTemperatureSensor(Entity):
4754
"""Representation of XBee Pro temperature sensor."""
4855

49-
def __init__(self, hass, config):
56+
def __init__(self, config, device):
5057
"""Initialize the sensor."""
5158
self._config = config
59+
self._device = device
5260
self._temp = None
5361

5462
@property
@@ -69,19 +77,19 @@ def unit_of_measurement(self):
6977
def update(self):
7078
"""Get the latest data."""
7179
try:
72-
self._temp = zigbee.DEVICE.get_temperature(self._config.address)
73-
except zigbee.ZIGBEE_TX_FAILURE:
80+
self._temp = self._device.get_temperature(self._config.address)
81+
except ZigBeeTxFailure:
7482
_LOGGER.warning(
7583
"Transmission failure when attempting to get sample from "
7684
"Zigbee device at address: %s",
7785
hexlify(self._config.address),
7886
)
79-
except zigbee.ZIGBEE_EXCEPTION as exc:
87+
except ZigBeeException as exc:
8088
_LOGGER.exception("Unable to get sample from Zigbee device: %s", exc)
8189

8290

8391
# This must be below the classes to which it refers.
8492
TYPE_CLASSES = {
85-
"temperature": (ZigBeeTemperatureSensor, zigbee.ZigBeeConfig),
86-
"analog": (zigbee.ZigBeeAnalogIn, zigbee.ZigBeeAnalogInConfig),
93+
"temperature": (ZigBeeTemperatureSensor, ZigBeeConfig),
94+
"analog": (ZigBeeAnalogIn, ZigBeeAnalogInConfig),
8795
}

homeassistant/components/zigbee/switch.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from homeassistant.components.switch import SwitchDevice
55

6-
from . import PLATFORM_SCHEMA, ZigBeeDigitalOut, ZigBeeDigitalOutConfig
6+
from . import DOMAIN, PLATFORM_SCHEMA, ZigBeeDigitalOut, ZigBeeDigitalOutConfig
77

88
CONF_ON_STATE = "on_state"
99

@@ -16,7 +16,8 @@
1616

1717
def setup_platform(hass, config, add_entities, discovery_info=None):
1818
"""Set up the Zigbee switch platform."""
19-
add_entities([ZigBeeSwitch(hass, ZigBeeDigitalOutConfig(config))])
19+
zigbee_device = hass.data[DOMAIN]
20+
add_entities([ZigBeeSwitch(ZigBeeDigitalOutConfig(config), zigbee_device)])
2021

2122

2223
class ZigBeeSwitch(ZigBeeDigitalOut, SwitchDevice):

0 commit comments

Comments
 (0)