mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 04:37:06 +00:00
Add abode support for CUE automations (#32296)
* Add support for CUE automations * Update requirements * Minor update to string name
This commit is contained in:
parent
2abdfc9da6
commit
d1beb92c5d
@ -2,7 +2,6 @@
|
||||
from asyncio import gather
|
||||
from copy import deepcopy
|
||||
from functools import partial
|
||||
import logging
|
||||
|
||||
from abodepy import Abode
|
||||
from abodepy.exceptions import AbodeException
|
||||
@ -24,15 +23,13 @@ from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers.dispatcher import dispatcher_send
|
||||
from homeassistant.helpers.entity import Entity
|
||||
|
||||
from .const import ATTRIBUTION, DEFAULT_CACHEDB, DOMAIN
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
from .const import ATTRIBUTION, DEFAULT_CACHEDB, DOMAIN, LOGGER
|
||||
|
||||
CONF_POLLING = "polling"
|
||||
|
||||
SERVICE_SETTINGS = "change_setting"
|
||||
SERVICE_CAPTURE_IMAGE = "capture_image"
|
||||
SERVICE_TRIGGER = "trigger_quick_action"
|
||||
SERVICE_TRIGGER_AUTOMATION = "trigger_automation"
|
||||
|
||||
ATTR_DEVICE_ID = "device_id"
|
||||
ATTR_DEVICE_NAME = "device_name"
|
||||
@ -47,8 +44,6 @@ ATTR_APP_TYPE = "app_type"
|
||||
ATTR_EVENT_BY = "event_by"
|
||||
ATTR_VALUE = "value"
|
||||
|
||||
ABODE_DEVICE_ID_LIST_SCHEMA = vol.Schema([str])
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema(
|
||||
{
|
||||
DOMAIN: vol.Schema(
|
||||
@ -68,7 +63,7 @@ CHANGE_SETTING_SCHEMA = vol.Schema(
|
||||
|
||||
CAPTURE_IMAGE_SCHEMA = vol.Schema({ATTR_ENTITY_ID: cv.entity_ids})
|
||||
|
||||
TRIGGER_SCHEMA = vol.Schema({ATTR_ENTITY_ID: cv.entity_ids})
|
||||
AUTOMATION_SCHEMA = vol.Schema({ATTR_ENTITY_ID: cv.entity_ids})
|
||||
|
||||
ABODE_PLATFORMS = [
|
||||
"alarm_control_panel",
|
||||
@ -87,7 +82,6 @@ class AbodeSystem:
|
||||
|
||||
def __init__(self, abode, polling):
|
||||
"""Initialize the system."""
|
||||
|
||||
self.abode = abode
|
||||
self.polling = polling
|
||||
self.entity_ids = set()
|
||||
@ -124,7 +118,7 @@ async def async_setup_entry(hass, config_entry):
|
||||
hass.data[DOMAIN] = AbodeSystem(abode, polling)
|
||||
|
||||
except (AbodeException, ConnectTimeout, HTTPError) as ex:
|
||||
_LOGGER.error("Unable to connect to Abode: %s", str(ex))
|
||||
LOGGER.error("Unable to connect to Abode: %s", str(ex))
|
||||
return False
|
||||
|
||||
for platform in ABODE_PLATFORMS:
|
||||
@ -143,7 +137,7 @@ async def async_unload_entry(hass, config_entry):
|
||||
"""Unload a config entry."""
|
||||
hass.services.async_remove(DOMAIN, SERVICE_SETTINGS)
|
||||
hass.services.async_remove(DOMAIN, SERVICE_CAPTURE_IMAGE)
|
||||
hass.services.async_remove(DOMAIN, SERVICE_TRIGGER)
|
||||
hass.services.async_remove(DOMAIN, SERVICE_TRIGGER_AUTOMATION)
|
||||
|
||||
tasks = []
|
||||
|
||||
@ -174,7 +168,7 @@ def setup_hass_services(hass):
|
||||
try:
|
||||
hass.data[DOMAIN].abode.set_setting(setting, value)
|
||||
except AbodeException as ex:
|
||||
_LOGGER.warning(ex)
|
||||
LOGGER.warning(ex)
|
||||
|
||||
def capture_image(call):
|
||||
"""Capture a new image."""
|
||||
@ -190,8 +184,8 @@ def setup_hass_services(hass):
|
||||
signal = f"abode_camera_capture_{entity_id}"
|
||||
dispatcher_send(hass, signal)
|
||||
|
||||
def trigger_quick_action(call):
|
||||
"""Trigger a quick action."""
|
||||
def trigger_automation(call):
|
||||
"""Trigger an Abode automation."""
|
||||
entity_ids = call.data.get(ATTR_ENTITY_ID, None)
|
||||
|
||||
target_entities = [
|
||||
@ -201,7 +195,7 @@ def setup_hass_services(hass):
|
||||
]
|
||||
|
||||
for entity_id in target_entities:
|
||||
signal = f"abode_trigger_quick_action_{entity_id}"
|
||||
signal = f"abode_trigger_automation_{entity_id}"
|
||||
dispatcher_send(hass, signal)
|
||||
|
||||
hass.services.register(
|
||||
@ -213,7 +207,7 @@ def setup_hass_services(hass):
|
||||
)
|
||||
|
||||
hass.services.register(
|
||||
DOMAIN, SERVICE_TRIGGER, trigger_quick_action, schema=TRIGGER_SCHEMA
|
||||
DOMAIN, SERVICE_TRIGGER_AUTOMATION, trigger_automation, schema=AUTOMATION_SCHEMA
|
||||
)
|
||||
|
||||
|
||||
@ -226,7 +220,7 @@ async def setup_hass_events(hass):
|
||||
hass.data[DOMAIN].abode.events.stop()
|
||||
|
||||
hass.data[DOMAIN].abode.logout()
|
||||
_LOGGER.info("Logged out of Abode")
|
||||
LOGGER.info("Logged out of Abode")
|
||||
|
||||
if not hass.data[DOMAIN].polling:
|
||||
await hass.async_add_executor_job(hass.data[DOMAIN].abode.events.start)
|
||||
@ -384,11 +378,14 @@ class AbodeAutomation(Entity):
|
||||
"""Return the state attributes."""
|
||||
return {
|
||||
ATTR_ATTRIBUTION: ATTRIBUTION,
|
||||
"automation_id": self._automation.automation_id,
|
||||
"type": self._automation.type,
|
||||
"sub_type": self._automation.sub_type,
|
||||
"type": "CUE automation",
|
||||
}
|
||||
|
||||
@property
|
||||
def unique_id(self):
|
||||
"""Return a unique ID to use for this automation."""
|
||||
return self._automation.automation_id
|
||||
|
||||
def _update_callback(self, device):
|
||||
"""Update the automation state."""
|
||||
self._automation.refresh()
|
||||
|
@ -1,6 +1,4 @@
|
||||
"""Support for Abode Security System alarm control panels."""
|
||||
import logging
|
||||
|
||||
import homeassistant.components.alarm_control_panel as alarm
|
||||
from homeassistant.components.alarm_control_panel.const import (
|
||||
SUPPORT_ALARM_ARM_AWAY,
|
||||
@ -16,8 +14,6 @@ from homeassistant.const import (
|
||||
from . import AbodeDevice
|
||||
from .const import ATTRIBUTION, DOMAIN
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
ICON = "mdi:security"
|
||||
|
||||
|
||||
@ -50,6 +46,11 @@ class AbodeAlarm(AbodeDevice, alarm.AlarmControlPanel):
|
||||
state = None
|
||||
return state
|
||||
|
||||
@property
|
||||
def code_arm_required(self):
|
||||
"""Whether the code is required for arm actions."""
|
||||
return False
|
||||
|
||||
@property
|
||||
def supported_features(self) -> int:
|
||||
"""Return the list of supported features."""
|
||||
|
@ -1,17 +1,11 @@
|
||||
"""Support for Abode Security System binary sensors."""
|
||||
import logging
|
||||
|
||||
import abodepy.helpers.constants as CONST
|
||||
import abodepy.helpers.timeline as TIMELINE
|
||||
|
||||
from homeassistant.components.binary_sensor import BinarySensorDevice
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
|
||||
from . import AbodeAutomation, AbodeDevice
|
||||
from . import AbodeDevice
|
||||
from .const import DOMAIN
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up Abode binary sensor devices."""
|
||||
@ -30,13 +24,6 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
for device in data.abode.get_devices(generic_type=device_types):
|
||||
entities.append(AbodeBinarySensor(data, device))
|
||||
|
||||
for automation in data.abode.get_automations(generic_type=CONST.TYPE_QUICK_ACTION):
|
||||
entities.append(
|
||||
AbodeQuickActionBinarySensor(
|
||||
data, automation, TIMELINE.AUTOMATION_EDIT_GROUP
|
||||
)
|
||||
)
|
||||
|
||||
async_add_entities(entities)
|
||||
|
||||
|
||||
@ -52,22 +39,3 @@ class AbodeBinarySensor(AbodeDevice, BinarySensorDevice):
|
||||
def device_class(self):
|
||||
"""Return the class of the binary sensor."""
|
||||
return self._device.generic_type
|
||||
|
||||
|
||||
class AbodeQuickActionBinarySensor(AbodeAutomation, BinarySensorDevice):
|
||||
"""A binary sensor implementation for Abode quick action automations."""
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
"""Subscribe Abode events."""
|
||||
await super().async_added_to_hass()
|
||||
signal = f"abode_trigger_quick_action_{self.entity_id}"
|
||||
async_dispatcher_connect(self.hass, signal, self.trigger)
|
||||
|
||||
def trigger(self):
|
||||
"""Trigger a quick automation."""
|
||||
self._automation.trigger()
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""Return True if the binary sensor is on."""
|
||||
return self._automation.is_active
|
||||
|
@ -1,6 +1,5 @@
|
||||
"""Support for Abode Security System cameras."""
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
|
||||
import abodepy.helpers.constants as CONST
|
||||
import abodepy.helpers.timeline as TIMELINE
|
||||
@ -11,12 +10,10 @@ from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
from homeassistant.util import Throttle
|
||||
|
||||
from . import AbodeDevice
|
||||
from .const import DOMAIN
|
||||
from .const import DOMAIN, LOGGER
|
||||
|
||||
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=90)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up Abode camera devices."""
|
||||
@ -71,7 +68,7 @@ class AbodeCamera(AbodeDevice, Camera):
|
||||
|
||||
self._response.raise_for_status()
|
||||
except requests.HTTPError as err:
|
||||
_LOGGER.warning("Failed to get camera image: %s", err)
|
||||
LOGGER.warning("Failed to get camera image: %s", err)
|
||||
self._response = None
|
||||
else:
|
||||
self._response = None
|
||||
|
@ -1,6 +1,4 @@
|
||||
"""Config flow for the Abode Security System component."""
|
||||
import logging
|
||||
|
||||
from abodepy import Abode
|
||||
from abodepy.exceptions import AbodeException
|
||||
from requests.exceptions import ConnectTimeout, HTTPError
|
||||
@ -10,12 +8,10 @@ from homeassistant import config_entries
|
||||
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
|
||||
from homeassistant.core import callback
|
||||
|
||||
from .const import DEFAULT_CACHEDB, DOMAIN # pylint: disable=unused-import
|
||||
from .const import DEFAULT_CACHEDB, DOMAIN, LOGGER # pylint: disable=unused-import
|
||||
|
||||
CONF_POLLING = "polling"
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class AbodeFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
"""Config flow for Abode."""
|
||||
@ -32,7 +28,6 @@ class AbodeFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
|
||||
async def async_step_user(self, user_input=None):
|
||||
"""Handle a flow initialized by the user."""
|
||||
|
||||
if self._async_current_entries():
|
||||
return self.async_abort(reason="single_instance_allowed")
|
||||
|
||||
@ -50,7 +45,7 @@ class AbodeFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
)
|
||||
|
||||
except (AbodeException, ConnectTimeout, HTTPError) as ex:
|
||||
_LOGGER.error("Unable to connect to Abode: %s", str(ex))
|
||||
LOGGER.error("Unable to connect to Abode: %s", str(ex))
|
||||
if ex.errcode == 400:
|
||||
return self._show_form({"base": "invalid_credentials"})
|
||||
return self._show_form({"base": "connection_error"})
|
||||
@ -76,7 +71,7 @@ class AbodeFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
async def async_step_import(self, import_config):
|
||||
"""Import a config entry from configuration.yaml."""
|
||||
if self._async_current_entries():
|
||||
_LOGGER.warning("Only one configuration of abode is allowed.")
|
||||
LOGGER.warning("Only one configuration of abode is allowed.")
|
||||
return self.async_abort(reason="single_instance_allowed")
|
||||
|
||||
return await self.async_step_user(import_config)
|
||||
|
@ -1,4 +1,8 @@
|
||||
"""Constants for the Abode Security System component."""
|
||||
import logging
|
||||
|
||||
LOGGER = logging.getLogger(__package__)
|
||||
|
||||
DOMAIN = "abode"
|
||||
ATTRIBUTION = "Data provided by goabode.com"
|
||||
|
||||
|
@ -1,6 +1,4 @@
|
||||
"""Support for Abode Security System covers."""
|
||||
import logging
|
||||
|
||||
import abodepy.helpers.constants as CONST
|
||||
|
||||
from homeassistant.components.cover import CoverDevice
|
||||
@ -8,8 +6,6 @@ from homeassistant.components.cover import CoverDevice
|
||||
from . import AbodeDevice
|
||||
from .const import DOMAIN
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up Abode cover devices."""
|
||||
|
@ -1,5 +1,4 @@
|
||||
"""Support for Abode Security System lights."""
|
||||
import logging
|
||||
from math import ceil
|
||||
|
||||
import abodepy.helpers.constants as CONST
|
||||
@ -21,8 +20,6 @@ from homeassistant.util.color import (
|
||||
from . import AbodeDevice
|
||||
from .const import DOMAIN
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up Abode light devices."""
|
||||
|
@ -1,6 +1,4 @@
|
||||
"""Support for the Abode Security System locks."""
|
||||
import logging
|
||||
|
||||
import abodepy.helpers.constants as CONST
|
||||
|
||||
from homeassistant.components.lock import LockDevice
|
||||
@ -8,8 +6,6 @@ from homeassistant.components.lock import LockDevice
|
||||
from . import AbodeDevice
|
||||
from .const import DOMAIN
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up Abode lock devices."""
|
||||
|
@ -3,7 +3,7 @@
|
||||
"name": "Abode",
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/abode",
|
||||
"requirements": ["abodepy==0.17.0"],
|
||||
"requirements": ["abodepy==0.18.1"],
|
||||
"dependencies": [],
|
||||
"codeowners": ["@shred86"]
|
||||
}
|
||||
|
@ -1,6 +1,4 @@
|
||||
"""Support for Abode Security System sensors."""
|
||||
import logging
|
||||
|
||||
import abodepy.helpers.constants as CONST
|
||||
|
||||
from homeassistant.const import (
|
||||
@ -12,8 +10,6 @@ from homeassistant.const import (
|
||||
from . import AbodeDevice
|
||||
from .const import DOMAIN
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
# Sensor types: Name, icon
|
||||
SENSOR_TYPES = {
|
||||
CONST.TEMP_STATUS_KEY: ["Temperature", DEVICE_CLASS_TEMPERATURE],
|
||||
|
@ -7,7 +7,7 @@ change_setting:
|
||||
fields:
|
||||
setting: {description: Setting to change., example: beeper_mute}
|
||||
value: {description: Value of the setting., example: '1'}
|
||||
trigger_quick_action:
|
||||
description: Trigger an Abode quick action.
|
||||
trigger_automation:
|
||||
description: Trigger an Abode automation.
|
||||
fields:
|
||||
entity_id: {description: Entity id of the quick action to trigger., example: binary_sensor.home_quick_action}
|
||||
entity_id: {description: Entity id of the automation to trigger., example: switch.my_automation}
|
@ -1,18 +1,17 @@
|
||||
"""Support for Abode Security System switches."""
|
||||
import logging
|
||||
|
||||
import abodepy.helpers.constants as CONST
|
||||
import abodepy.helpers.timeline as TIMELINE
|
||||
|
||||
from homeassistant.components.switch import SwitchDevice
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
|
||||
from . import AbodeAutomation, AbodeDevice
|
||||
from .const import DOMAIN
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
DEVICE_TYPES = [CONST.TYPE_SWITCH, CONST.TYPE_VALVE]
|
||||
|
||||
ICON = "mdi:robot"
|
||||
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up Abode switch devices."""
|
||||
@ -24,7 +23,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
for device in data.abode.get_devices(generic_type=device_type):
|
||||
entities.append(AbodeSwitch(data, device))
|
||||
|
||||
for automation in data.abode.get_automations(generic_type=CONST.TYPE_AUTOMATION):
|
||||
for automation in data.abode.get_automations():
|
||||
entities.append(
|
||||
AbodeAutomationSwitch(data, automation, TIMELINE.AUTOMATION_EDIT_GROUP)
|
||||
)
|
||||
@ -52,15 +51,33 @@ class AbodeSwitch(AbodeDevice, SwitchDevice):
|
||||
class AbodeAutomationSwitch(AbodeAutomation, SwitchDevice):
|
||||
"""A switch implementation for Abode automations."""
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
"""Subscribe Abode events."""
|
||||
await super().async_added_to_hass()
|
||||
|
||||
signal = f"abode_trigger_automation_{self.entity_id}"
|
||||
async_dispatcher_connect(self.hass, signal, self.trigger)
|
||||
|
||||
def turn_on(self, **kwargs):
|
||||
"""Turn on the device."""
|
||||
self._automation.set_active(True)
|
||||
"""Enable the automation."""
|
||||
if self._automation.enable(True):
|
||||
self.schedule_update_ha_state()
|
||||
|
||||
def turn_off(self, **kwargs):
|
||||
"""Turn off the device."""
|
||||
self._automation.set_active(False)
|
||||
"""Disable the automation."""
|
||||
if self._automation.enable(False):
|
||||
self.schedule_update_ha_state()
|
||||
|
||||
def trigger(self):
|
||||
"""Trigger the automation."""
|
||||
self._automation.trigger()
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""Return True if the binary sensor is on."""
|
||||
return self._automation.is_active
|
||||
"""Return True if the automation is enabled."""
|
||||
return self._automation.is_enabled
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
"""Return the robot icon to match Home Assistant automations."""
|
||||
return ICON
|
||||
|
@ -106,7 +106,7 @@ WazeRouteCalculator==0.12
|
||||
YesssSMS==0.4.1
|
||||
|
||||
# homeassistant.components.abode
|
||||
abodepy==0.17.0
|
||||
abodepy==0.18.1
|
||||
|
||||
# homeassistant.components.mcp23017
|
||||
adafruit-blinka==3.9.0
|
||||
|
@ -26,7 +26,7 @@ RtmAPI==0.7.2
|
||||
YesssSMS==0.4.1
|
||||
|
||||
# homeassistant.components.abode
|
||||
abodepy==0.17.0
|
||||
abodepy==0.18.1
|
||||
|
||||
# homeassistant.components.androidtv
|
||||
adb-shell==0.1.1
|
||||
|
Loading…
x
Reference in New Issue
Block a user