Async version of melissa (#17721)

* rebase upstream

* Fixed tests

* Fixing lint
This commit is contained in:
kennedyshead 2018-10-30 21:29:11 +01:00 committed by Martin Hjelmare
parent 9565c0bd1d
commit 4073f63256
7 changed files with 481 additions and 317 deletions

View File

@ -34,10 +34,11 @@ FAN_MODES = [
] ]
def setup_platform(hass, config, add_entities, discovery_info=None): async def async_setup_platform(
hass, config, async_add_entities, discovery_info=None):
"""Iterate through and add all Melissa devices.""" """Iterate through and add all Melissa devices."""
api = hass.data[DATA_MELISSA] api = hass.data[DATA_MELISSA]
devices = api.fetch_devices().values() devices = (await api.async_fetch_devices()).values()
all_devices = [] all_devices = []
@ -46,7 +47,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
all_devices.append(MelissaClimate( all_devices.append(MelissaClimate(
api, device['serial_number'], device)) api, device['serial_number'], device))
add_entities(all_devices) async_add_entities(all_devices)
class MelissaClimate(ClimateDevice): class MelissaClimate(ClimateDevice):
@ -142,48 +143,48 @@ class MelissaClimate(ClimateDevice):
"""Return the list of supported features.""" """Return the list of supported features."""
return SUPPORT_FLAGS return SUPPORT_FLAGS
def set_temperature(self, **kwargs): async def async_set_temperature(self, **kwargs):
"""Set new target temperature.""" """Set new target temperature."""
temp = kwargs.get(ATTR_TEMPERATURE) temp = kwargs.get(ATTR_TEMPERATURE)
self.send({self._api.TEMP: temp}) await self.async_send({self._api.TEMP: temp})
def set_fan_mode(self, fan_mode): async def async_set_fan_mode(self, fan_mode):
"""Set fan mode.""" """Set fan mode."""
melissa_fan_mode = self.hass_fan_to_melissa(fan_mode) melissa_fan_mode = self.hass_fan_to_melissa(fan_mode)
self.send({self._api.FAN: melissa_fan_mode}) await self.async_send({self._api.FAN: melissa_fan_mode})
def set_operation_mode(self, operation_mode): async def async_set_operation_mode(self, operation_mode):
"""Set operation mode.""" """Set operation mode."""
mode = self.hass_mode_to_melissa(operation_mode) mode = self.hass_mode_to_melissa(operation_mode)
self.send({self._api.MODE: mode}) await self.async_send({self._api.MODE: mode})
def turn_on(self): async def async_turn_on(self):
"""Turn on device.""" """Turn on device."""
self.send({self._api.STATE: self._api.STATE_ON}) await self.async_send({self._api.STATE: self._api.STATE_ON})
def turn_off(self): async def async_turn_off(self):
"""Turn off device.""" """Turn off device."""
self.send({self._api.STATE: self._api.STATE_OFF}) await self.async_send({self._api.STATE: self._api.STATE_OFF})
def send(self, value): async def async_send(self, value):
"""Send action to service.""" """Send action to service."""
try: try:
old_value = self._cur_settings.copy() old_value = self._cur_settings.copy()
self._cur_settings.update(value) self._cur_settings.update(value)
except AttributeError: except AttributeError:
old_value = None old_value = None
if not self._api.send(self._serial_number, self._cur_settings): if not await self._api.async_send(
self._serial_number, self._cur_settings):
self._cur_settings = old_value self._cur_settings = old_value
return False
return True
def update(self): async def async_update(self):
"""Get latest data from Melissa.""" """Get latest data from Melissa."""
try: try:
self._data = self._api.status(cached=True)[self._serial_number] self._data = (await self._api.async_status(cached=True))[
self._cur_settings = self._api.cur_settings( self._serial_number]
self._cur_settings = (await self._api.async_cur_settings(
self._serial_number self._serial_number
)['controller']['_relation']['command_log'] ))['controller']['_relation']['command_log']
except KeyError: except KeyError:
_LOGGER.warning( _LOGGER.warning(
'Unable to update entity %s', self.entity_id) 'Unable to update entity %s', self.entity_id)

View File

@ -10,9 +10,9 @@ import voluptuous as vol
from homeassistant.const import CONF_USERNAME, CONF_PASSWORD from homeassistant.const import CONF_USERNAME, CONF_PASSWORD
from homeassistant.helpers import config_validation as cv from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.discovery import load_platform from homeassistant.helpers.discovery import async_load_platform
REQUIREMENTS = ["py-melissa-climate==1.0.6"] REQUIREMENTS = ["py-melissa-climate==2.0.0"]
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -28,17 +28,19 @@ CONFIG_SCHEMA = vol.Schema({
}, extra=vol.ALLOW_EXTRA) }, extra=vol.ALLOW_EXTRA)
def setup(hass, config): async def async_setup(hass, config):
"""Set up the Melissa Climate component.""" """Set up the Melissa Climate component."""
import melissa import melissa
conf = config[DOMAIN] conf = config[DOMAIN]
username = conf.get(CONF_USERNAME) username = conf.get(CONF_USERNAME)
password = conf.get(CONF_PASSWORD) password = conf.get(CONF_PASSWORD)
api = melissa.AsyncMelissa(username=username, password=password)
api = melissa.Melissa(username=username, password=password) await api.async_connect()
hass.data[DATA_MELISSA] = api hass.data[DATA_MELISSA] = api
load_platform(hass, 'sensor', DOMAIN, {}, config) hass.async_create_task(
load_platform(hass, 'climate', DOMAIN, {}, config) async_load_platform(hass, 'sensor', DOMAIN, {}, config))
hass.async_create_task(
async_load_platform(hass, 'climate', DOMAIN, {}, config))
return True return True

View File

@ -15,17 +15,19 @@ DEPENDENCIES = ['melissa']
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
def setup_platform(hass, config, add_entities, discovery_info=None): async def async_setup_platform(
hass, config, async_add_entities, discovery_info=None):
"""Set up the melissa sensor platform.""" """Set up the melissa sensor platform."""
sensors = [] sensors = []
api = hass.data[DATA_MELISSA] api = hass.data[DATA_MELISSA]
devices = api.fetch_devices().values()
devices = (await api.async_fetch_devices()).values()
for device in devices: for device in devices:
if device['type'] == 'melissa': if device['type'] == 'melissa':
sensors.append(MelissaTemperatureSensor(device, api)) sensors.append(MelissaTemperatureSensor(device, api))
sensors.append(MelissaHumiditySensor(device, api)) sensors.append(MelissaHumiditySensor(device, api))
add_entities(sensors) async_add_entities(sensors)
class MelissaSensor(Entity): class MelissaSensor(Entity):
@ -54,9 +56,9 @@ class MelissaSensor(Entity):
"""Return the state of the sensor.""" """Return the state of the sensor."""
return self._state return self._state
def update(self): async def async_update(self):
"""Fetch status from melissa.""" """Fetch status from melissa."""
self._data = self._api.status(cached=True) self._data = await self._api.async_status(cached=True)
class MelissaTemperatureSensor(MelissaSensor): class MelissaTemperatureSensor(MelissaSensor):
@ -70,9 +72,9 @@ class MelissaTemperatureSensor(MelissaSensor):
"""Return the unit of measurement.""" """Return the unit of measurement."""
return self._unit return self._unit
def update(self): async def async_update(self):
"""Fetch new state data for the sensor.""" """Fetch new state data for the sensor."""
super().update() await super().async_update()
try: try:
self._state = self._data[self._serial]['temp'] self._state = self._data[self._serial]['temp']
except KeyError: except KeyError:
@ -90,9 +92,9 @@ class MelissaHumiditySensor(MelissaSensor):
"""Return the unit of measurement.""" """Return the unit of measurement."""
return self._unit return self._unit
def update(self): async def async_update(self):
"""Fetch new state data for the sensor.""" """Fetch new state data for the sensor."""
super().update() await super().async_update()
try: try:
self._state = self._data[self._serial]['humidity'] self._state = self._data[self._serial]['humidity']
except KeyError: except KeyError:

View File

@ -768,7 +768,7 @@ py-canary==0.5.0
py-cpuinfo==4.0.0 py-cpuinfo==4.0.0
# homeassistant.components.melissa # homeassistant.components.melissa
py-melissa-climate==1.0.6 py-melissa-climate==2.0.0
# homeassistant.components.camera.synology # homeassistant.components.camera.synology
py-synology==0.2.0 py-synology==0.2.0

View File

@ -1,9 +1,8 @@
"""Test for Melissa climate component.""" """Test for Melissa climate component."""
import unittest
from unittest.mock import Mock, patch from unittest.mock import Mock, patch
import json import json
from asynctest import mock from homeassistant.components.climate.melissa import MelissaClimate
from homeassistant.components.climate import ( from homeassistant.components.climate import (
melissa, SUPPORT_TARGET_TEMPERATURE, SUPPORT_OPERATION_MODE, melissa, SUPPORT_TARGET_TEMPERATURE, SUPPORT_OPERATION_MODE,
@ -15,244 +14,392 @@ from homeassistant.components.melissa import DATA_MELISSA
from homeassistant.const import ( from homeassistant.const import (
TEMP_CELSIUS, STATE_ON, ATTR_TEMPERATURE, STATE_OFF, STATE_IDLE TEMP_CELSIUS, STATE_ON, ATTR_TEMPERATURE, STATE_OFF, STATE_IDLE
) )
from tests.common import get_test_home_assistant, load_fixture from tests.common import load_fixture, mock_coro_func
_SERIAL = "12345678"
class TestMelissa(unittest.TestCase): def melissa_mock():
"""Tests for Melissa climate.""" """Use this to mock the melissa api."""
api = Mock()
api.async_fetch_devices = mock_coro_func(
return_value=json.loads(load_fixture('melissa_fetch_devices.json')))
api.async_status = mock_coro_func(return_value=json.loads(load_fixture(
'melissa_status.json')))
api.async_cur_settings = mock_coro_func(
return_value=json.loads(load_fixture('melissa_cur_settings.json')))
def setUp(self): # pylint: disable=invalid-name api.async_send = mock_coro_func(return_value=True)
"""Set up test variables."""
self.hass = get_test_home_assistant()
self._serial = '12345678'
self.api = Mock() api.STATE_OFF = 0
self.api.fetch_devices.return_value = json.loads(load_fixture( api.STATE_ON = 1
'melissa_fetch_devices.json' api.STATE_IDLE = 2
))
self.api.cur_settings.return_value = json.loads(load_fixture(
'melissa_cur_settings.json'
))
self.api.status.return_value = json.loads(load_fixture(
'melissa_status.json'
))
self.api.STATE_OFF = 0
self.api.STATE_ON = 1
self.api.STATE_IDLE = 2
self.api.MODE_AUTO = 0 api.MODE_AUTO = 0
self.api.MODE_FAN = 1 api.MODE_FAN = 1
self.api.MODE_HEAT = 2 api.MODE_HEAT = 2
self.api.MODE_COOL = 3 api.MODE_COOL = 3
self.api.MODE_DRY = 4 api.MODE_DRY = 4
self.api.FAN_AUTO = 0 api.FAN_AUTO = 0
self.api.FAN_LOW = 1 api.FAN_LOW = 1
self.api.FAN_MEDIUM = 2 api.FAN_MEDIUM = 2
self.api.FAN_HIGH = 3 api.FAN_HIGH = 3
self.api.STATE = 'state' api.STATE = 'state'
self.api.MODE = 'mode' api.MODE = 'mode'
self.api.FAN = 'fan' api.FAN = 'fan'
self.api.TEMP = 'temp' api.TEMP = 'temp'
return api
device = self.api.fetch_devices()[self._serial]
self.thermostat = melissa.MelissaClimate(
self.api, device['serial_number'], device)
self.thermostat.update()
def tearDown(self): # pylint: disable=invalid-name async def test_setup_platform(hass):
"""Teardown this test class. Stop hass."""
self.hass.stop()
@patch("homeassistant.components.climate.melissa.MelissaClimate")
def test_setup_platform(self, mocked_thermostat):
"""Test setup_platform.""" """Test setup_platform."""
device = self.api.fetch_devices()[self._serial] with patch("homeassistant.components.climate.melissa.MelissaClimate"
thermostat = mocked_thermostat(self.api, device['serial_number'], ) as mocked_thermostat:
api = melissa_mock()
device = (await api.async_fetch_devices())[_SERIAL]
thermostat = mocked_thermostat(api, device['serial_number'],
device) device)
thermostats = [thermostat] thermostats = [thermostat]
self.hass.data[DATA_MELISSA] = self.api hass.data[DATA_MELISSA] = api
config = {} config = {}
add_entities = Mock() add_entities = Mock()
discovery_info = {} discovery_info = {}
melissa.setup_platform(self.hass, config, add_entities, discovery_info) await melissa.async_setup_platform(
hass, config, add_entities, discovery_info)
add_entities.assert_called_once_with(thermostats) add_entities.assert_called_once_with(thermostats)
def test_get_name(self):
"""Test name property."""
assert "Melissa 12345678" == self.thermostat.name
def test_is_on(self): async def test_get_name(hass):
"""Test name property.""" """Test name property."""
assert self.thermostat.is_on with patch('homeassistant.components.melissa'):
self.thermostat._cur_settings = None api = melissa_mock()
assert not self.thermostat.is_on device = (await api.async_fetch_devices())[_SERIAL]
thermostat = MelissaClimate(api, _SERIAL, device)
assert "Melissa 12345678" == thermostat.name
def test_current_fan_mode(self):
async def test_is_on(hass):
"""Test name property."""
with patch('homeassistant.components.melissa'):
api = melissa_mock()
device = (await api.async_fetch_devices())[_SERIAL]
thermostat = MelissaClimate(api, _SERIAL, device)
await thermostat.async_update()
assert thermostat.is_on
thermostat._cur_settings = None
assert not thermostat.is_on
async def test_current_fan_mode(hass):
"""Test current_fan_mode property.""" """Test current_fan_mode property."""
self.thermostat.update() with patch('homeassistant.components.melissa'):
assert SPEED_LOW == self.thermostat.current_fan_mode api = melissa_mock()
self.thermostat._cur_settings = None device = (await api.async_fetch_devices())[_SERIAL]
assert self.thermostat.current_fan_mode is None thermostat = MelissaClimate(api, _SERIAL, device)
await thermostat.async_update()
assert SPEED_LOW == thermostat.current_fan_mode
def test_current_temperature(self): thermostat._cur_settings = None
assert thermostat.current_fan_mode is None
async def test_current_temperature(hass):
"""Test current temperature.""" """Test current temperature."""
assert 27.4 == self.thermostat.current_temperature with patch('homeassistant.components.melissa'):
api = melissa_mock()
device = (await api.async_fetch_devices())[_SERIAL]
thermostat = MelissaClimate(api, _SERIAL, device)
assert 27.4 == thermostat.current_temperature
def test_current_temperature_no_data(self):
async def test_current_temperature_no_data(hass):
"""Test current temperature without data.""" """Test current temperature without data."""
self.thermostat._data = None with patch('homeassistant.components.melissa'):
assert self.thermostat.current_temperature is None api = melissa_mock()
device = (await api.async_fetch_devices())[_SERIAL]
thermostat = MelissaClimate(api, _SERIAL, device)
thermostat._data = None
assert thermostat.current_temperature is None
def test_target_temperature_step(self):
async def test_target_temperature_step(hass):
"""Test current target_temperature_step.""" """Test current target_temperature_step."""
assert 1 == self.thermostat.target_temperature_step with patch('homeassistant.components.melissa'):
api = melissa_mock()
device = (await api.async_fetch_devices())[_SERIAL]
thermostat = MelissaClimate(api, _SERIAL, device)
assert 1 == thermostat.target_temperature_step
def test_current_operation(self):
async def test_current_operation(hass):
"""Test current operation.""" """Test current operation."""
self.thermostat.update() with patch('homeassistant.components.melissa'):
assert self.thermostat.current_operation == STATE_HEAT api = melissa_mock()
self.thermostat._cur_settings = None device = (await api.async_fetch_devices())[_SERIAL]
assert self.thermostat.current_operation is None thermostat = MelissaClimate(api, _SERIAL, device)
await thermostat.async_update()
assert thermostat.current_operation == STATE_HEAT
def test_operation_list(self): thermostat._cur_settings = None
assert thermostat.current_operation is None
async def test_operation_list(hass):
"""Test the operation list.""" """Test the operation list."""
with patch('homeassistant.components.melissa'):
api = melissa_mock()
device = (await api.async_fetch_devices())[_SERIAL]
thermostat = MelissaClimate(api, _SERIAL, device)
assert [STATE_COOL, STATE_DRY, STATE_FAN_ONLY, STATE_HEAT] == \ assert [STATE_COOL, STATE_DRY, STATE_FAN_ONLY, STATE_HEAT] == \
self.thermostat.operation_list thermostat.operation_list
def test_fan_list(self):
async def test_fan_list(hass):
"""Test the fan list.""" """Test the fan list."""
with patch('homeassistant.components.melissa'):
api = melissa_mock()
device = (await api.async_fetch_devices())[_SERIAL]
thermostat = MelissaClimate(api, _SERIAL, device)
assert [STATE_AUTO, SPEED_HIGH, SPEED_LOW, SPEED_MEDIUM] == \ assert [STATE_AUTO, SPEED_HIGH, SPEED_LOW, SPEED_MEDIUM] == \
self.thermostat.fan_list thermostat.fan_list
def test_target_temperature(self):
async def test_target_temperature(hass):
"""Test target temperature.""" """Test target temperature."""
assert 16 == self.thermostat.target_temperature with patch('homeassistant.components.melissa'):
self.thermostat._cur_settings = None api = melissa_mock()
assert self.thermostat.target_temperature is None device = (await api.async_fetch_devices())[_SERIAL]
thermostat = MelissaClimate(api, _SERIAL, device)
await thermostat.async_update()
assert 16 == thermostat.target_temperature
def test_state(self): thermostat._cur_settings = None
assert thermostat.target_temperature is None
async def test_state(hass):
"""Test state.""" """Test state."""
assert STATE_ON == self.thermostat.state with patch('homeassistant.components.melissa'):
self.thermostat._cur_settings = None api = melissa_mock()
assert self.thermostat.state is None device = (await api.async_fetch_devices())[_SERIAL]
thermostat = MelissaClimate(api, _SERIAL, device)
await thermostat.async_update()
assert STATE_ON == thermostat.state
def test_temperature_unit(self): thermostat._cur_settings = None
assert thermostat.state is None
async def test_temperature_unit(hass):
"""Test temperature unit.""" """Test temperature unit."""
assert TEMP_CELSIUS == self.thermostat.temperature_unit with patch('homeassistant.components.melissa'):
api = melissa_mock()
device = (await api.async_fetch_devices())[_SERIAL]
thermostat = MelissaClimate(api, _SERIAL, device)
assert TEMP_CELSIUS == thermostat.temperature_unit
def test_min_temp(self):
async def test_min_temp(hass):
"""Test min temp.""" """Test min temp."""
assert 16 == self.thermostat.min_temp with patch('homeassistant.components.melissa'):
api = melissa_mock()
device = (await api.async_fetch_devices())[_SERIAL]
thermostat = MelissaClimate(api, _SERIAL, device)
assert 16 == thermostat.min_temp
def test_max_temp(self):
async def test_max_temp(hass):
"""Test max temp.""" """Test max temp."""
assert 30 == self.thermostat.max_temp with patch('homeassistant.components.melissa'):
api = melissa_mock()
device = (await api.async_fetch_devices())[_SERIAL]
thermostat = MelissaClimate(api, _SERIAL, device)
assert 30 == thermostat.max_temp
def test_supported_features(self):
async def test_supported_features(hass):
"""Test supported_features property.""" """Test supported_features property."""
with patch('homeassistant.components.melissa'):
api = melissa_mock()
device = (await api.async_fetch_devices())[_SERIAL]
thermostat = MelissaClimate(api, _SERIAL, device)
features = (SUPPORT_TARGET_TEMPERATURE | SUPPORT_OPERATION_MODE | features = (SUPPORT_TARGET_TEMPERATURE | SUPPORT_OPERATION_MODE |
SUPPORT_ON_OFF | SUPPORT_FAN_MODE) SUPPORT_ON_OFF | SUPPORT_FAN_MODE)
assert features == self.thermostat.supported_features assert features == thermostat.supported_features
def test_set_temperature(self):
async def test_set_temperature(hass):
"""Test set_temperature.""" """Test set_temperature."""
self.api.send.return_value = True with patch('homeassistant.components.melissa'):
self.thermostat.update() api = melissa_mock()
self.thermostat.set_temperature(**{ATTR_TEMPERATURE: 25}) device = (await api.async_fetch_devices())[_SERIAL]
assert 25 == self.thermostat.target_temperature thermostat = MelissaClimate(api, _SERIAL, device)
await thermostat.async_update()
await thermostat.async_set_temperature(**{ATTR_TEMPERATURE: 25})
assert 25 == thermostat.target_temperature
def test_fan_mode(self):
async def test_fan_mode(hass):
"""Test set_fan_mode.""" """Test set_fan_mode."""
self.api.send.return_value = True with patch('homeassistant.components.melissa'):
self.thermostat.set_fan_mode(SPEED_HIGH) api = melissa_mock()
assert SPEED_HIGH == self.thermostat.current_fan_mode device = (await api.async_fetch_devices())[_SERIAL]
thermostat = MelissaClimate(api, _SERIAL, device)
await thermostat.async_update()
await hass.async_block_till_done()
await thermostat.async_set_fan_mode(SPEED_HIGH)
await hass.async_block_till_done()
assert SPEED_HIGH == thermostat.current_fan_mode
def test_set_operation_mode(self):
async def test_set_operation_mode(hass):
"""Test set_operation_mode.""" """Test set_operation_mode."""
self.api.send.return_value = True with patch('homeassistant.components.melissa'):
self.thermostat.set_operation_mode(STATE_COOL) api = melissa_mock()
assert STATE_COOL == self.thermostat.current_operation device = (await api.async_fetch_devices())[_SERIAL]
thermostat = MelissaClimate(api, _SERIAL, device)
await thermostat.async_update()
await hass.async_block_till_done()
await thermostat.async_set_operation_mode(STATE_COOL)
await hass.async_block_till_done()
assert STATE_COOL == thermostat.current_operation
def test_turn_on(self):
async def test_turn_on(hass):
"""Test turn_on.""" """Test turn_on."""
self.thermostat.turn_on() with patch('homeassistant.components.melissa'):
assert self.thermostat.state api = melissa_mock()
device = (await api.async_fetch_devices())[_SERIAL]
thermostat = MelissaClimate(api, _SERIAL, device)
await thermostat.async_update()
await hass.async_block_till_done()
await thermostat.async_turn_on()
await hass.async_block_till_done()
assert thermostat.state
def test_turn_off(self):
async def test_turn_off(hass):
"""Test turn_off.""" """Test turn_off."""
self.thermostat.turn_off() with patch('homeassistant.components.melissa'):
assert STATE_OFF == self.thermostat.state api = melissa_mock()
device = (await api.async_fetch_devices())[_SERIAL]
thermostat = MelissaClimate(api, _SERIAL, device)
await thermostat.async_update()
await hass.async_block_till_done()
await thermostat.async_turn_off()
await hass.async_block_till_done()
assert STATE_OFF == thermostat.state
def test_send(self):
async def test_send(hass):
"""Test send.""" """Test send."""
self.thermostat.update() with patch('homeassistant.components.melissa'):
assert self.thermostat.send( api = melissa_mock()
{'fan': self.api.FAN_MEDIUM}) device = (await api.async_fetch_devices())[_SERIAL]
assert SPEED_MEDIUM == self.thermostat.current_fan_mode thermostat = MelissaClimate(api, _SERIAL, device)
self.api.send.return_value = False await thermostat.async_update()
self.thermostat._cur_settings = None await hass.async_block_till_done()
assert not self.thermostat.send({ await thermostat.async_send({'fan': api.FAN_MEDIUM})
'fan': self.api.FAN_LOW}) await hass.async_block_till_done()
assert SPEED_LOW != self.thermostat.current_fan_mode assert SPEED_MEDIUM == thermostat.current_fan_mode
assert self.thermostat._cur_settings is None api.async_send.return_value = mock_coro_func(return_value=False)
thermostat._cur_settings = None
await thermostat.async_send({'fan': api.FAN_LOW})
await hass.async_block_till_done()
assert SPEED_LOW != thermostat.current_fan_mode
assert thermostat._cur_settings is None
@mock.patch('homeassistant.components.climate.melissa._LOGGER.warning')
def test_update(self, mocked_warning): async def test_update(hass):
"""Test update.""" """Test update."""
self.thermostat.update() with patch('homeassistant.components.melissa'):
assert SPEED_LOW == self.thermostat.current_fan_mode with patch('homeassistant.components.climate.melissa._LOGGER.warning'
assert STATE_HEAT == self.thermostat.current_operation ) as mocked_warning:
self.thermostat._api.status.side_effect = KeyError('boom') api = melissa_mock()
self.thermostat.update() device = (await api.async_fetch_devices())[_SERIAL]
thermostat = MelissaClimate(api, _SERIAL, device)
await thermostat.async_update()
assert SPEED_LOW == thermostat.current_fan_mode
assert STATE_HEAT == thermostat.current_operation
api.async_status = mock_coro_func(exception=KeyError('boom'))
await thermostat.async_update()
mocked_warning.assert_called_once_with( mocked_warning.assert_called_once_with(
'Unable to update entity %s', self.thermostat.entity_id) 'Unable to update entity %s', thermostat.entity_id)
def test_melissa_state_to_hass(self):
async def test_melissa_state_to_hass(hass):
"""Test for translate melissa states to hass.""" """Test for translate melissa states to hass."""
assert STATE_OFF == self.thermostat.melissa_state_to_hass(0) with patch('homeassistant.components.melissa'):
assert STATE_ON == self.thermostat.melissa_state_to_hass(1) api = melissa_mock()
assert STATE_IDLE == self.thermostat.melissa_state_to_hass(2) device = (await api.async_fetch_devices())[_SERIAL]
assert self.thermostat.melissa_state_to_hass(3) is None thermostat = MelissaClimate(api, _SERIAL, device)
assert STATE_OFF == thermostat.melissa_state_to_hass(0)
assert STATE_ON == thermostat.melissa_state_to_hass(1)
assert STATE_IDLE == thermostat.melissa_state_to_hass(2)
assert thermostat.melissa_state_to_hass(3) is None
def test_melissa_op_to_hass(self):
async def test_melissa_op_to_hass(hass):
"""Test for translate melissa operations to hass.""" """Test for translate melissa operations to hass."""
assert STATE_FAN_ONLY == self.thermostat.melissa_op_to_hass(1) with patch('homeassistant.components.melissa'):
assert STATE_HEAT == self.thermostat.melissa_op_to_hass(2) api = melissa_mock()
assert STATE_COOL == self.thermostat.melissa_op_to_hass(3) device = (await api.async_fetch_devices())[_SERIAL]
assert STATE_DRY == self.thermostat.melissa_op_to_hass(4) thermostat = MelissaClimate(api, _SERIAL, device)
assert self.thermostat.melissa_op_to_hass(5) is None assert STATE_FAN_ONLY == thermostat.melissa_op_to_hass(1)
assert STATE_HEAT == thermostat.melissa_op_to_hass(2)
assert STATE_COOL == thermostat.melissa_op_to_hass(3)
assert STATE_DRY == thermostat.melissa_op_to_hass(4)
assert thermostat.melissa_op_to_hass(5) is None
def test_melissa_fan_to_hass(self):
async def test_melissa_fan_to_hass(hass):
"""Test for translate melissa fan state to hass.""" """Test for translate melissa fan state to hass."""
assert STATE_AUTO == self.thermostat.melissa_fan_to_hass(0) with patch('homeassistant.components.melissa'):
assert SPEED_LOW == self.thermostat.melissa_fan_to_hass(1) api = melissa_mock()
assert SPEED_MEDIUM == self.thermostat.melissa_fan_to_hass(2) device = (await api.async_fetch_devices())[_SERIAL]
assert SPEED_HIGH == self.thermostat.melissa_fan_to_hass(3) thermostat = MelissaClimate(api, _SERIAL, device)
assert self.thermostat.melissa_fan_to_hass(4) is None assert STATE_AUTO == thermostat.melissa_fan_to_hass(0)
assert SPEED_LOW == thermostat.melissa_fan_to_hass(1)
assert SPEED_MEDIUM == thermostat.melissa_fan_to_hass(2)
assert SPEED_HIGH == thermostat.melissa_fan_to_hass(3)
assert thermostat.melissa_fan_to_hass(4) is None
@mock.patch('homeassistant.components.climate.melissa._LOGGER.warning')
def test_hass_mode_to_melissa(self, mocked_warning): async def test_hass_mode_to_melissa(hass):
"""Test for hass operations to melssa.""" """Test for hass operations to melssa."""
assert 1 == self.thermostat.hass_mode_to_melissa(STATE_FAN_ONLY) with patch('homeassistant.components.melissa'):
assert 2 == self.thermostat.hass_mode_to_melissa(STATE_HEAT) with patch('homeassistant.components.climate.melissa._LOGGER.warning'
assert 3 == self.thermostat.hass_mode_to_melissa(STATE_COOL) ) as mocked_warning:
assert 4 == self.thermostat.hass_mode_to_melissa(STATE_DRY) api = melissa_mock()
self.thermostat.hass_mode_to_melissa("test") device = (await api.async_fetch_devices())[_SERIAL]
thermostat = MelissaClimate(api, _SERIAL, device)
assert 1 == thermostat.hass_mode_to_melissa(STATE_FAN_ONLY)
assert 2 == thermostat.hass_mode_to_melissa(STATE_HEAT)
assert 3 == thermostat.hass_mode_to_melissa(STATE_COOL)
assert 4 == thermostat.hass_mode_to_melissa(STATE_DRY)
thermostat.hass_mode_to_melissa("test")
mocked_warning.assert_called_once_with( mocked_warning.assert_called_once_with(
"Melissa have no setting for %s mode", "test") "Melissa have no setting for %s mode", "test")
@mock.patch('homeassistant.components.climate.melissa._LOGGER.warning')
def test_hass_fan_to_melissa(self, mocked_warning): async def test_hass_fan_to_melissa(hass):
"""Test for translate melissa states to hass.""" """Test for translate melissa states to hass."""
assert 0 == self.thermostat.hass_fan_to_melissa(STATE_AUTO) with patch('homeassistant.components.melissa'):
assert 1 == self.thermostat.hass_fan_to_melissa(SPEED_LOW) with patch('homeassistant.components.climate.melissa._LOGGER.warning'
assert 2 == self.thermostat.hass_fan_to_melissa(SPEED_MEDIUM) ) as mocked_warning:
assert 3 == self.thermostat.hass_fan_to_melissa(SPEED_HIGH) api = melissa_mock()
self.thermostat.hass_fan_to_melissa("test") device = (await api.async_fetch_devices())[_SERIAL]
thermostat = MelissaClimate(api, _SERIAL, device)
assert 0 == thermostat.hass_fan_to_melissa(STATE_AUTO)
assert 1 == thermostat.hass_fan_to_melissa(SPEED_LOW)
assert 2 == thermostat.hass_fan_to_melissa(SPEED_MEDIUM)
assert 3 == thermostat.hass_fan_to_melissa(SPEED_HIGH)
thermostat.hass_fan_to_melissa("test")
mocked_warning.assert_called_once_with( mocked_warning.assert_called_once_with(
"Melissa have no setting for %s fan mode", "test") "Melissa have no setting for %s fan mode", "test")

View File

@ -1,89 +1,112 @@
"""Test for Melissa climate component.""" """Test for Melissa climate component."""
import unittest
import json import json
from unittest.mock import Mock from unittest.mock import Mock, patch
from homeassistant.components.sensor.melissa import MelissaTemperatureSensor, \
MelissaHumiditySensor
from tests.common import load_fixture, mock_coro_func
from homeassistant.components.melissa import DATA_MELISSA from homeassistant.components.melissa import DATA_MELISSA
from homeassistant.components.sensor import melissa from homeassistant.components.sensor import melissa
from homeassistant.components.sensor.melissa import MelissaTemperatureSensor, \
MelissaHumiditySensor
from homeassistant.const import TEMP_CELSIUS from homeassistant.const import TEMP_CELSIUS
from tests.common import get_test_home_assistant, load_fixture
class TestMelissa(unittest.TestCase): _SERIAL = "12345678"
"""Tests for Melissa climate."""
def setUp(self): # pylint: disable=invalid-name
"""Set up test variables."""
self.hass = get_test_home_assistant()
self._serial = '12345678'
self.api = Mock() def melissa_mock():
self.api.fetch_devices.return_value = json.loads(load_fixture( """Use this to mock the melissa api."""
'melissa_fetch_devices.json' api = Mock()
)) api.async_fetch_devices = mock_coro_func(
self.api.status.return_value = json.loads(load_fixture( return_value=json.loads(load_fixture('melissa_fetch_devices.json')))
api.async_status = mock_coro_func(return_value=json.loads(load_fixture(
'melissa_status.json' 'melissa_status.json'
)) )))
self.api.TEMP = 'temp' api.TEMP = 'temp'
self.api.HUMIDITY = 'humidity' api.HUMIDITY = 'humidity'
device = self.api.fetch_devices()[self._serial] return api
self.temp = MelissaTemperatureSensor(device, self.api)
self.hum = MelissaHumiditySensor(device, self.api)
def tearDown(self): # pylint: disable=invalid-name
"""Teardown this test class. Stop hass."""
self.hass.stop()
def test_setup_platform(self): async def test_setup_platform(hass):
"""Test setup_platform.""" """Test setup_platform."""
self.hass.data[DATA_MELISSA] = self.api with patch('homeassistant.components.melissa'):
hass.data[DATA_MELISSA] = melissa_mock()
config = {} config = {}
add_entities = Mock() async_add_entities = mock_coro_func()
discovery_info = {} discovery_info = {}
melissa.setup_platform(self.hass, config, add_entities, discovery_info) await melissa.async_setup_platform(
hass, config, async_add_entities, discovery_info)
def test_name(self):
async def test_name(hass):
"""Test name property.""" """Test name property."""
device = self.api.fetch_devices()[self._serial] with patch('homeassistant.components.melissa'):
assert self.temp.name == '{0} {1}'.format( mocked_melissa = melissa_mock()
device = (await mocked_melissa.async_fetch_devices())[_SERIAL]
temp = MelissaTemperatureSensor(device, mocked_melissa)
hum = MelissaHumiditySensor(device, mocked_melissa)
assert temp.name == '{0} {1}'.format(
device['name'], device['name'],
self.temp._type temp._type
) )
assert self.hum.name == '{0} {1}'.format( assert hum.name == '{0} {1}'.format(
device['name'], device['name'],
self.hum._type hum._type
) )
def test_state(self):
async def test_state(hass):
"""Test state property.""" """Test state property."""
device = self.api.status()[self._serial] with patch('homeassistant.components.melissa'):
self.temp.update() mocked_melissa = melissa_mock()
assert self.temp.state == device[self.api.TEMP] device = (await mocked_melissa.async_fetch_devices())[_SERIAL]
self.hum.update() status = (await mocked_melissa.async_status())[_SERIAL]
assert self.hum.state == device[self.api.HUMIDITY] temp = MelissaTemperatureSensor(device, mocked_melissa)
hum = MelissaHumiditySensor(device, mocked_melissa)
await temp.async_update()
assert temp.state == status[mocked_melissa.TEMP]
await hum.async_update()
assert hum.state == status[mocked_melissa.HUMIDITY]
def test_unit_of_measurement(self):
async def test_unit_of_measurement(hass):
"""Test unit of measurement property.""" """Test unit of measurement property."""
assert self.temp.unit_of_measurement == TEMP_CELSIUS with patch('homeassistant.components.melissa'):
assert self.hum.unit_of_measurement == '%' mocked_melissa = melissa_mock()
device = (await mocked_melissa.async_fetch_devices())[_SERIAL]
temp = MelissaTemperatureSensor(device, mocked_melissa)
hum = MelissaHumiditySensor(device, mocked_melissa)
assert temp.unit_of_measurement == TEMP_CELSIUS
assert hum.unit_of_measurement == '%'
def test_update(self):
async def test_update(hass):
"""Test for update.""" """Test for update."""
self.temp.update() with patch('homeassistant.components.melissa'):
assert self.temp.state == 27.4 mocked_melissa = melissa_mock()
self.hum.update() device = (await mocked_melissa.async_fetch_devices())[_SERIAL]
assert self.hum.state == 18.7 temp = MelissaTemperatureSensor(device, mocked_melissa)
hum = MelissaHumiditySensor(device, mocked_melissa)
await temp.async_update()
assert temp.state == 27.4
await hum.async_update()
assert hum.state == 18.7
def test_update_keyerror(self):
async def test_update_keyerror(hass):
"""Test for faulty update.""" """Test for faulty update."""
self.temp._api.status.return_value = {} with patch('homeassistant.components.melissa'):
self.temp.update() mocked_melissa = melissa_mock()
assert self.temp.state is None device = (await mocked_melissa.async_fetch_devices())[_SERIAL]
self.hum._api.status.return_value = {} temp = MelissaTemperatureSensor(device, mocked_melissa)
self.hum.update() hum = MelissaHumiditySensor(device, mocked_melissa)
assert self.hum.state is None mocked_melissa.async_status = mock_coro_func(return_value={})
await temp.async_update()
assert temp.state is None
await hum.async_update()
assert hum.state is None

View File

@ -1,6 +1,5 @@
"""The test for the Melissa Climate component.""" """The test for the Melissa Climate component."""
import unittest from tests.common import MockDependency, mock_coro_func
from tests.common import get_test_home_assistant, MockDependency
from homeassistant.components import melissa from homeassistant.components import melissa
@ -12,25 +11,15 @@ VALID_CONFIG = {
} }
class TestMelissa(unittest.TestCase): async def test_setup(hass):
"""Test the Melissa component."""
def setUp(self): # pylint: disable=invalid-name
"""Initialize the values for this test class."""
self.hass = get_test_home_assistant()
self.config = VALID_CONFIG
def tearDown(self): # pylint: disable=invalid-name
"""Teardown this test class. Stop hass."""
self.hass.stop()
@MockDependency("melissa")
def test_setup(self, mocked_melissa):
"""Test setting up the Melissa component.""" """Test setting up the Melissa component."""
melissa.setup(self.hass, self.config) with MockDependency('melissa') as mocked_melissa:
mocked_melissa.AsyncMelissa().async_connect = mock_coro_func()
await melissa.async_setup(hass, VALID_CONFIG)
mocked_melissa.Melissa.assert_called_with( mocked_melissa.AsyncMelissa.assert_called_with(
username="********", password="********") username="********", password="********")
assert melissa.DATA_MELISSA in self.hass.data
assert isinstance(self.hass.data[melissa.DATA_MELISSA], type( assert melissa.DATA_MELISSA in hass.data
mocked_melissa.Melissa())) assert isinstance(hass.data[melissa.DATA_MELISSA], type(
mocked_melissa.AsyncMelissa()))