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.""" """Test setup_platform."""
self.hass.stop() with patch("homeassistant.components.climate.melissa.MelissaClimate"
) as mocked_thermostat:
@patch("homeassistant.components.climate.melissa.MelissaClimate") api = melissa_mock()
def test_setup_platform(self, mocked_thermostat): device = (await api.async_fetch_devices())[_SERIAL]
"""Test setup_platform.""" thermostat = mocked_thermostat(api, device['serial_number'],
device = self.api.fetch_devices()[self._serial]
thermostat = mocked_thermostat(self.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):
"""Test current_fan_mode property."""
self.thermostat.update()
assert SPEED_LOW == self.thermostat.current_fan_mode
self.thermostat._cur_settings = None
assert self.thermostat.current_fan_mode is None
def test_current_temperature(self): async def test_is_on(hass):
"""Test current temperature.""" """Test name property."""
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)
await thermostat.async_update()
assert thermostat.is_on
def test_current_temperature_no_data(self): thermostat._cur_settings = None
"""Test current temperature without data.""" assert not thermostat.is_on
self.thermostat._data = None
assert self.thermostat.current_temperature is None
def test_target_temperature_step(self):
"""Test current target_temperature_step."""
assert 1 == self.thermostat.target_temperature_step
def test_current_operation(self): async def test_current_fan_mode(hass):
"""Test current operation.""" """Test current_fan_mode property."""
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 SPEED_LOW == thermostat.current_fan_mode
def test_operation_list(self): thermostat._cur_settings = None
"""Test the operation list.""" assert thermostat.current_fan_mode is None
async def test_current_temperature(hass):
"""Test 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
async def test_current_temperature_no_data(hass):
"""Test current temperature without data."""
with patch('homeassistant.components.melissa'):
api = melissa_mock()
device = (await api.async_fetch_devices())[_SERIAL]
thermostat = MelissaClimate(api, _SERIAL, device)
thermostat._data = None
assert thermostat.current_temperature is None
async def test_target_temperature_step(hass):
"""Test current 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
async def test_current_operation(hass):
"""Test current operation."""
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.current_operation == STATE_HEAT
thermostat._cur_settings = None
assert thermostat.current_operation is None
async def test_operation_list(hass):
"""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):
"""Test the fan list.""" async def test_fan_list(hass):
"""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):
"""Test target temperature."""
assert 16 == self.thermostat.target_temperature
self.thermostat._cur_settings = None
assert self.thermostat.target_temperature is None
def test_state(self): async def test_target_temperature(hass):
"""Test state.""" """Test target temperature."""
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 16 == thermostat.target_temperature
def test_temperature_unit(self): thermostat._cur_settings = None
"""Test temperature unit.""" assert thermostat.target_temperature is None
assert TEMP_CELSIUS == self.thermostat.temperature_unit
def test_min_temp(self):
"""Test min temp."""
assert 16 == self.thermostat.min_temp
def test_max_temp(self): async def test_state(hass):
"""Test max temp.""" """Test state."""
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)
await thermostat.async_update()
assert STATE_ON == thermostat.state
def test_supported_features(self): thermostat._cur_settings = None
"""Test supported_features property.""" assert thermostat.state is None
async def test_temperature_unit(hass):
"""Test 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
async def test_min_temp(hass):
"""Test 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
async def test_max_temp(hass):
"""Test 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
async def test_supported_features(hass):
"""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):
"""Test set_temperature."""
self.api.send.return_value = True
self.thermostat.update()
self.thermostat.set_temperature(**{ATTR_TEMPERATURE: 25})
assert 25 == self.thermostat.target_temperature
def test_fan_mode(self): async def test_set_temperature(hass):
"""Test set_fan_mode.""" """Test set_temperature."""
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 thermostat.async_set_temperature(**{ATTR_TEMPERATURE: 25})
assert 25 == thermostat.target_temperature
def test_set_operation_mode(self):
"""Test set_operation_mode."""
self.api.send.return_value = True
self.thermostat.set_operation_mode(STATE_COOL)
assert STATE_COOL == self.thermostat.current_operation
def test_turn_on(self): async def test_fan_mode(hass):
"""Test turn_on.""" """Test set_fan_mode."""
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_set_fan_mode(SPEED_HIGH)
await hass.async_block_till_done()
assert SPEED_HIGH == thermostat.current_fan_mode
def test_turn_off(self):
"""Test turn_off."""
self.thermostat.turn_off()
assert STATE_OFF == self.thermostat.state
def test_send(self): async def test_set_operation_mode(hass):
"""Test send.""" """Test set_operation_mode."""
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_set_operation_mode(STATE_COOL)
'fan': self.api.FAN_LOW}) await hass.async_block_till_done()
assert SPEED_LOW != self.thermostat.current_fan_mode assert STATE_COOL == thermostat.current_operation
assert self.thermostat._cur_settings is None
@mock.patch('homeassistant.components.climate.melissa._LOGGER.warning')
def test_update(self, mocked_warning):
"""Test update."""
self.thermostat.update()
assert SPEED_LOW == self.thermostat.current_fan_mode
assert STATE_HEAT == self.thermostat.current_operation
self.thermostat._api.status.side_effect = KeyError('boom')
self.thermostat.update()
mocked_warning.assert_called_once_with(
'Unable to update entity %s', self.thermostat.entity_id)
def test_melissa_state_to_hass(self): async def test_turn_on(hass):
"""Test for translate melissa states to hass.""" """Test turn_on."""
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)
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_melissa_op_to_hass(self):
"""Test for translate melissa operations to hass."""
assert STATE_FAN_ONLY == self.thermostat.melissa_op_to_hass(1)
assert STATE_HEAT == self.thermostat.melissa_op_to_hass(2)
assert STATE_COOL == self.thermostat.melissa_op_to_hass(3)
assert STATE_DRY == self.thermostat.melissa_op_to_hass(4)
assert self.thermostat.melissa_op_to_hass(5) is None
def test_melissa_fan_to_hass(self): async def test_turn_off(hass):
"""Test for translate melissa fan state to hass.""" """Test turn_off."""
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 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
@mock.patch('homeassistant.components.climate.melissa._LOGGER.warning')
def test_hass_mode_to_melissa(self, mocked_warning):
"""Test for hass operations to melssa."""
assert 1 == self.thermostat.hass_mode_to_melissa(STATE_FAN_ONLY)
assert 2 == self.thermostat.hass_mode_to_melissa(STATE_HEAT)
assert 3 == self.thermostat.hass_mode_to_melissa(STATE_COOL)
assert 4 == self.thermostat.hass_mode_to_melissa(STATE_DRY)
self.thermostat.hass_mode_to_melissa("test")
mocked_warning.assert_called_once_with(
"Melissa have no setting for %s mode", "test")
@mock.patch('homeassistant.components.climate.melissa._LOGGER.warning') async def test_send(hass):
def test_hass_fan_to_melissa(self, mocked_warning): """Test send."""
"""Test for translate melissa states to hass.""" with patch('homeassistant.components.melissa'):
assert 0 == self.thermostat.hass_fan_to_melissa(STATE_AUTO) api = melissa_mock()
assert 1 == self.thermostat.hass_fan_to_melissa(SPEED_LOW) device = (await api.async_fetch_devices())[_SERIAL]
assert 2 == self.thermostat.hass_fan_to_melissa(SPEED_MEDIUM) thermostat = MelissaClimate(api, _SERIAL, device)
assert 3 == self.thermostat.hass_fan_to_melissa(SPEED_HIGH) await thermostat.async_update()
self.thermostat.hass_fan_to_melissa("test") await hass.async_block_till_done()
mocked_warning.assert_called_once_with( await thermostat.async_send({'fan': api.FAN_MEDIUM})
"Melissa have no setting for %s fan mode", "test") await hass.async_block_till_done()
assert SPEED_MEDIUM == thermostat.current_fan_mode
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
async def test_update(hass):
"""Test update."""
with patch('homeassistant.components.melissa'):
with patch('homeassistant.components.climate.melissa._LOGGER.warning'
) as mocked_warning:
api = melissa_mock()
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(
'Unable to update entity %s', thermostat.entity_id)
async def test_melissa_state_to_hass(hass):
"""Test for translate melissa states to hass."""
with patch('homeassistant.components.melissa'):
api = melissa_mock()
device = (await api.async_fetch_devices())[_SERIAL]
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
async def test_melissa_op_to_hass(hass):
"""Test for translate melissa operations to hass."""
with patch('homeassistant.components.melissa'):
api = melissa_mock()
device = (await api.async_fetch_devices())[_SERIAL]
thermostat = MelissaClimate(api, _SERIAL, device)
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
async def test_melissa_fan_to_hass(hass):
"""Test for translate melissa fan state to hass."""
with patch('homeassistant.components.melissa'):
api = melissa_mock()
device = (await api.async_fetch_devices())[_SERIAL]
thermostat = MelissaClimate(api, _SERIAL, device)
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
async def test_hass_mode_to_melissa(hass):
"""Test for hass operations to melssa."""
with patch('homeassistant.components.melissa'):
with patch('homeassistant.components.climate.melissa._LOGGER.warning'
) as mocked_warning:
api = melissa_mock()
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(
"Melissa have no setting for %s mode", "test")
async def test_hass_fan_to_melissa(hass):
"""Test for translate melissa states to hass."""
with patch('homeassistant.components.melissa'):
with patch('homeassistant.components.climate.melissa._LOGGER.warning'
) as mocked_warning:
api = melissa_mock()
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(
"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')))
'melissa_status.json' api.async_status = mock_coro_func(return_value=json.loads(load_fixture(
)) '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):
"""Test name property.""" async def test_name(hass):
device = self.api.fetch_devices()[self._serial] """Test name property."""
assert self.temp.name == '{0} {1}'.format( with patch('homeassistant.components.melissa'):
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):
"""Test state property."""
device = self.api.status()[self._serial]
self.temp.update()
assert self.temp.state == device[self.api.TEMP]
self.hum.update()
assert self.hum.state == device[self.api.HUMIDITY]
def test_unit_of_measurement(self): async def test_state(hass):
"""Test unit of measurement property.""" """Test state 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]
status = (await mocked_melissa.async_status())[_SERIAL]
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_update(self):
"""Test for update."""
self.temp.update()
assert self.temp.state == 27.4
self.hum.update()
assert self.hum.state == 18.7
def test_update_keyerror(self): async def test_unit_of_measurement(hass):
"""Test for faulty update.""" """Test unit of measurement property."""
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 assert temp.unit_of_measurement == TEMP_CELSIUS
assert hum.unit_of_measurement == '%'
async def test_update(hass):
"""Test for update."""
with patch('homeassistant.components.melissa'):
mocked_melissa = melissa_mock()
device = (await mocked_melissa.async_fetch_devices())[_SERIAL]
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
async def test_update_keyerror(hass):
"""Test for faulty update."""
with patch('homeassistant.components.melissa'):
mocked_melissa = melissa_mock()
device = (await mocked_melissa.async_fetch_devices())[_SERIAL]
temp = MelissaTemperatureSensor(device, mocked_melissa)
hum = MelissaHumiditySensor(device, mocked_melissa)
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.""" """Test setting up the Melissa component."""
with MockDependency('melissa') as mocked_melissa:
mocked_melissa.AsyncMelissa().async_connect = mock_coro_func()
await melissa.async_setup(hass, VALID_CONFIG)
def setUp(self): # pylint: disable=invalid-name mocked_melissa.AsyncMelissa.assert_called_with(
"""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."""
melissa.setup(self.hass, self.config)
mocked_melissa.Melissa.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()))