forked from home-assistant/core
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for nexia automations (home-assistant#33049)
* Add support for nexia automations Bump nexia to 0.7.1 Start adding tests Fix some of the climate attributes that were wrong (discovered while adding tests) Pass the name of the instance so the nexia UI does not display "My Mobile" * fix mocking * faster asserts, scene * scene makes so much more sense * pylint * Update homeassistant/components/nexia/scene.py Co-Authored-By: Martin Hjelmare <[email protected]> * docstring cleanup Co-authored-by: Martin Hjelmare <[email protected]>
- Loading branch information
1 parent
836413a
commit 8532839
Showing
14 changed files
with
8,362 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
"""Support for Nexia Automations.""" | ||
|
||
from homeassistant.components.scene import Scene | ||
from homeassistant.const import ATTR_ATTRIBUTION | ||
|
||
from .const import ( | ||
ATTR_DESCRIPTION, | ||
ATTRIBUTION, | ||
DATA_NEXIA, | ||
DOMAIN, | ||
NEXIA_DEVICE, | ||
UPDATE_COORDINATOR, | ||
) | ||
from .entity import NexiaEntity | ||
|
||
|
||
async def async_setup_entry(hass, config_entry, async_add_entities): | ||
"""Set up automations for a Nexia device.""" | ||
|
||
nexia_data = hass.data[DOMAIN][config_entry.entry_id][DATA_NEXIA] | ||
nexia_home = nexia_data[NEXIA_DEVICE] | ||
coordinator = nexia_data[UPDATE_COORDINATOR] | ||
entities = [] | ||
|
||
# Automation switches | ||
for automation_id in nexia_home.get_automation_ids(): | ||
automation = nexia_home.get_automation_by_id(automation_id) | ||
|
||
entities.append(NexiaAutomationScene(coordinator, automation)) | ||
|
||
async_add_entities(entities, True) | ||
|
||
|
||
class NexiaAutomationScene(NexiaEntity, Scene): | ||
"""Provides Nexia automation support.""" | ||
|
||
def __init__(self, coordinator, automation): | ||
"""Initialize the automation scene.""" | ||
super().__init__(coordinator) | ||
self._automation = automation | ||
|
||
@property | ||
def unique_id(self): | ||
"""Return the unique id of the automation scene.""" | ||
# This is the automation unique_id | ||
return self._automation.automation_id | ||
|
||
@property | ||
def name(self): | ||
"""Return the name of the automation scene.""" | ||
return self._automation.name | ||
|
||
@property | ||
def device_state_attributes(self): | ||
"""Return the scene specific state attributes.""" | ||
return { | ||
ATTR_ATTRIBUTION: ATTRIBUTION, | ||
ATTR_DESCRIPTION: self._automation.description, | ||
} | ||
|
||
@property | ||
def icon(self): | ||
"""Return the icon of the automation scene.""" | ||
return "mdi:script-text-outline" | ||
|
||
def activate(self): | ||
"""Activate an automation scene.""" | ||
self._automation.activate() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
"""The lock tests for the august platform.""" | ||
|
||
from homeassistant.components.climate.const import HVAC_MODE_HEAT_COOL | ||
|
||
from .util import async_init_integration | ||
|
||
|
||
async def test_climate_zones(hass): | ||
"""Test creation climate zones.""" | ||
|
||
await async_init_integration(hass) | ||
|
||
state = hass.states.get("climate.nick_office") | ||
assert state.state == HVAC_MODE_HEAT_COOL | ||
expected_attributes = { | ||
"attribution": "Data provided by mynexia.com", | ||
"current_humidity": 52.0, | ||
"current_temperature": 22.8, | ||
"dehumidify_setpoint": 45.0, | ||
"dehumidify_supported": True, | ||
"fan_mode": "auto", | ||
"fan_modes": ["auto", "on", "circulate"], | ||
"friendly_name": "Nick Office", | ||
"humidify_supported": False, | ||
"humidity": 45.0, | ||
"hvac_action": "cooling", | ||
"hvac_modes": ["off", "auto", "heat_cool", "heat", "cool"], | ||
"max_humidity": 65.0, | ||
"max_temp": 37.2, | ||
"min_humidity": 35.0, | ||
"min_temp": 12.8, | ||
"preset_mode": "None", | ||
"preset_modes": ["None", "Home", "Away", "Sleep"], | ||
"supported_features": 31, | ||
"target_temp_high": 26.1, | ||
"target_temp_low": 17.2, | ||
"target_temp_step": 1.0, | ||
"temperature": None, | ||
"zone_status": "Relieving Air", | ||
} | ||
# Only test for a subset of attributes in case | ||
# HA changes the implementation and a new one appears | ||
assert all( | ||
state.attributes[key] == expected_attributes[key] for key in expected_attributes | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
"""The lock tests for the august platform.""" | ||
|
||
from .util import async_init_integration | ||
|
||
|
||
async def test_automation_scenees(hass): | ||
"""Test creation automation scenees.""" | ||
|
||
await async_init_integration(hass) | ||
|
||
state = hass.states.get("scene.away_short") | ||
expected_attributes = { | ||
"attribution": "Data provided by mynexia.com", | ||
"description": "When IFTTT activates the automation Upstairs " | ||
"West Wing will permanently hold the heat to 63.0 " | ||
"and cool to 80.0 AND Downstairs East Wing will " | ||
"permanently hold the heat to 63.0 and cool to " | ||
"79.0 AND Downstairs West Wing will permanently " | ||
"hold the heat to 63.0 and cool to 79.0 AND " | ||
"Upstairs West Wing will permanently hold the " | ||
"heat to 63.0 and cool to 81.0 AND Upstairs West " | ||
"Wing will change Fan Mode to Auto AND Downstairs " | ||
"East Wing will change Fan Mode to Auto AND " | ||
"Downstairs West Wing will change Fan Mode to " | ||
"Auto AND Activate the mode named 'Away Short' " | ||
"AND Master Suite will permanently hold the heat " | ||
"to 63.0 and cool to 79.0 AND Master Suite will " | ||
"change Fan Mode to Auto", | ||
"friendly_name": "Away Short", | ||
"icon": "mdi:script-text-outline", | ||
} | ||
# Only test for a subset of attributes in case | ||
# HA changes the implementation and a new one appears | ||
assert all( | ||
state.attributes[key] == expected_attributes[key] for key in expected_attributes | ||
) | ||
|
||
state = hass.states.get("scene.power_outage") | ||
expected_attributes = { | ||
"attribution": "Data provided by mynexia.com", | ||
"description": "When IFTTT activates the automation Upstairs " | ||
"West Wing will permanently hold the heat to 55.0 " | ||
"and cool to 90.0 AND Downstairs East Wing will " | ||
"permanently hold the heat to 55.0 and cool to " | ||
"90.0 AND Downstairs West Wing will permanently " | ||
"hold the heat to 55.0 and cool to 90.0 AND " | ||
"Activate the mode named 'Power Outage'", | ||
"friendly_name": "Power Outage", | ||
"icon": "mdi:script-text-outline", | ||
} | ||
# Only test for a subset of attributes in case | ||
# HA changes the implementation and a new one appears | ||
assert all( | ||
state.attributes[key] == expected_attributes[key] for key in expected_attributes | ||
) | ||
|
||
state = hass.states.get("scene.power_restored") | ||
expected_attributes = { | ||
"attribution": "Data provided by mynexia.com", | ||
"description": "When IFTTT activates the automation Upstairs " | ||
"West Wing will Run Schedule AND Downstairs East " | ||
"Wing will Run Schedule AND Downstairs West Wing " | ||
"will Run Schedule AND Activate the mode named " | ||
"'Home'", | ||
"friendly_name": "Power Restored", | ||
"icon": "mdi:script-text-outline", | ||
} | ||
# Only test for a subset of attributes in case | ||
# HA changes the implementation and a new one appears | ||
assert all( | ||
state.attributes[key] == expected_attributes[key] for key in expected_attributes | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
"""Tests for the nexia integration.""" | ||
import uuid | ||
|
||
from asynctest import patch | ||
from nexia.home import NexiaHome | ||
import requests_mock | ||
|
||
from homeassistant.components.nexia.const import DOMAIN | ||
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME | ||
from homeassistant.core import HomeAssistant | ||
|
||
from tests.common import MockConfigEntry, load_fixture | ||
|
||
|
||
async def async_init_integration( | ||
hass: HomeAssistant, skip_setup: bool = False, | ||
) -> MockConfigEntry: | ||
"""Set up the nexia integration in Home Assistant.""" | ||
|
||
house_fixture = "nexia/mobile_houses_123456.json" | ||
session_fixture = "nexia/session_123456.json" | ||
sign_in_fixture = "nexia/sign_in.json" | ||
|
||
with requests_mock.mock() as m, patch( | ||
"nexia.home.load_or_create_uuid", return_value=uuid.uuid4() | ||
): | ||
m.post(NexiaHome.API_MOBILE_SESSION_URL, text=load_fixture(session_fixture)) | ||
m.get( | ||
NexiaHome.API_MOBILE_HOUSES_URL.format(house_id=123456), | ||
text=load_fixture(house_fixture), | ||
) | ||
m.post( | ||
NexiaHome.API_MOBILE_ACCOUNTS_SIGN_IN_URL, | ||
text=load_fixture(sign_in_fixture), | ||
) | ||
entry = MockConfigEntry( | ||
domain=DOMAIN, data={CONF_USERNAME: "mock", CONF_PASSWORD: "mock"} | ||
) | ||
entry.add_to_hass(hass) | ||
|
||
if not skip_setup: | ||
await hass.config_entries.async_setup(entry.entry_id) | ||
await hass.async_block_till_done() | ||
|
||
return entry |
Oops, something went wrong.