Move SmartThings imports to top (#24878)

* Move imports to top

* use lib constants

* Add missing three_axis mapping
This commit is contained in:
Andrew Sayre 2019-06-30 22:29:21 -04:00 committed by GitHub
parent 7d651e2b7a
commit 7db4eeaf7f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 176 additions and 191 deletions

View file

@ -6,6 +6,8 @@ from typing import Iterable
from aiohttp.client_exceptions import ( from aiohttp.client_exceptions import (
ClientConnectionError, ClientResponseError) ClientConnectionError, ClientResponseError)
from pysmartapp.event import EVENT_TYPE_DEVICE
from pysmartthings import Attribute, Capability, SmartThings
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_ACCESS_TOKEN from homeassistant.const import CONF_ACCESS_TOKEN
@ -60,8 +62,6 @@ async def async_migrate_entry(hass: HomeAssistantType, entry: ConfigEntry):
async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry): async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry):
"""Initialize config entry which represents an installed SmartApp.""" """Initialize config entry which represents an installed SmartApp."""
from pysmartthings import SmartThings
if not validate_webhook_requirements(hass): if not validate_webhook_requirements(hass):
_LOGGER.warning("The 'base_url' of the 'http' component must be " _LOGGER.warning("The 'base_url' of the 'http' component must be "
"configured and start with 'https://'") "configured and start with 'https://'")
@ -179,8 +179,6 @@ async def async_unload_entry(hass: HomeAssistantType, entry: ConfigEntry):
async def async_remove_entry( async def async_remove_entry(
hass: HomeAssistantType, entry: ConfigEntry) -> None: hass: HomeAssistantType, entry: ConfigEntry) -> None:
"""Perform clean-up when entry is being removed.""" """Perform clean-up when entry is being removed."""
from pysmartthings import SmartThings
api = SmartThings(async_get_clientsession(hass), api = SmartThings(async_get_clientsession(hass),
entry.data[CONF_ACCESS_TOKEN]) entry.data[CONF_ACCESS_TOKEN])
@ -301,9 +299,6 @@ class DeviceBroker:
async def _event_handler(self, req, resp, app): async def _event_handler(self, req, resp, app):
"""Broker for incoming events.""" """Broker for incoming events."""
from pysmartapp.event import EVENT_TYPE_DEVICE
from pysmartthings import Capability, Attribute
# Do not process events received from a different installed app # Do not process events received from a different installed app
# under the same parent SmartApp (valid use-scenario) # under the same parent SmartApp (valid use-scenario)
if req.installed_app_id != self._installed_app_id: if req.installed_app_id != self._installed_app_id:

View file

@ -1,32 +1,34 @@
"""Support for binary sensors through the SmartThings cloud API.""" """Support for binary sensors through the SmartThings cloud API."""
from typing import Optional, Sequence from typing import Optional, Sequence
from pysmartthings import Attribute, Capability
from homeassistant.components.binary_sensor import BinarySensorDevice from homeassistant.components.binary_sensor import BinarySensorDevice
from . import SmartThingsEntity from . import SmartThingsEntity
from .const import DATA_BROKERS, DOMAIN from .const import DATA_BROKERS, DOMAIN
CAPABILITY_TO_ATTRIB = { CAPABILITY_TO_ATTRIB = {
'accelerationSensor': 'acceleration', Capability.acceleration_sensor: Attribute.acceleration,
'contactSensor': 'contact', Capability.contact_sensor: Attribute.contact,
'filterStatus': 'filterStatus', Capability.filter_status: Attribute.filter_status,
'motionSensor': 'motion', Capability.motion_sensor: Attribute.motion,
'presenceSensor': 'presence', Capability.presence_sensor: Attribute.presence,
'soundSensor': 'sound', Capability.sound_sensor: Attribute.sound,
'tamperAlert': 'tamper', Capability.tamper_alert: Attribute.tamper,
'valve': 'valve', Capability.valve: Attribute.valve,
'waterSensor': 'water', Capability.water_sensor: Attribute.water,
} }
ATTRIB_TO_CLASS = { ATTRIB_TO_CLASS = {
'acceleration': 'moving', Attribute.acceleration: 'moving',
'contact': 'opening', Attribute.contact: 'opening',
'filterStatus': 'problem', Attribute.filter_status: 'problem',
'motion': 'motion', Attribute.motion: 'motion',
'presence': 'presence', Attribute.presence: 'presence',
'sound': 'sound', Attribute.sound: 'sound',
'tamper': 'problem', Attribute.tamper: 'problem',
'valve': 'opening', Attribute.valve: 'opening',
'water': 'moisture', Attribute.water: 'moisture',
} }

View file

@ -3,6 +3,8 @@ import asyncio
import logging import logging
from typing import Iterable, Optional, Sequence from typing import Iterable, Optional, Sequence
from pysmartthings import Attribute, Capability
from homeassistant.components.climate import ( from homeassistant.components.climate import (
DOMAIN as CLIMATE_DOMAIN, ClimateDevice) DOMAIN as CLIMATE_DOMAIN, ClimateDevice)
from homeassistant.components.climate.const import ( from homeassistant.components.climate.const import (
@ -69,8 +71,6 @@ async def async_setup_platform(
async def async_setup_entry(hass, config_entry, async_add_entities): async def async_setup_entry(hass, config_entry, async_add_entities):
"""Add climate entities for a config entry.""" """Add climate entities for a config entry."""
from pysmartthings import Capability
ac_capabilities = [ ac_capabilities = [
Capability.air_conditioner_mode, Capability.air_conditioner_mode,
Capability.air_conditioner_fan_mode, Capability.air_conditioner_fan_mode,
@ -93,8 +93,6 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
def get_capabilities(capabilities: Sequence[str]) -> Optional[Sequence[str]]: def get_capabilities(capabilities: Sequence[str]) -> Optional[Sequence[str]]:
"""Return all capabilities supported if minimum required are present.""" """Return all capabilities supported if minimum required are present."""
from pysmartthings import Capability
supported = [ supported = [
Capability.air_conditioner_mode, Capability.air_conditioner_mode,
Capability.demand_response_load_control, Capability.demand_response_load_control,
@ -145,8 +143,6 @@ class SmartThingsThermostat(SmartThingsEntity, ClimateDevice):
self._operations = None self._operations = None
def _determine_features(self): def _determine_features(self):
from pysmartthings import Capability
flags = SUPPORT_OPERATION_MODE \ flags = SUPPORT_OPERATION_MODE \
| SUPPORT_TARGET_TEMPERATURE \ | SUPPORT_TARGET_TEMPERATURE \
| SUPPORT_TARGET_TEMPERATURE_LOW \ | SUPPORT_TARGET_TEMPERATURE_LOW \
@ -301,7 +297,6 @@ class SmartThingsThermostat(SmartThingsEntity, ClimateDevice):
@property @property
def temperature_unit(self): def temperature_unit(self):
"""Return the unit of measurement.""" """Return the unit of measurement."""
from pysmartthings import Attribute
return UNIT_MAP.get( return UNIT_MAP.get(
self._device.status.attributes[Attribute.temperature].unit) self._device.status.attributes[Attribute.temperature].unit)
@ -440,6 +435,5 @@ class SmartThingsAirConditioner(SmartThingsEntity, ClimateDevice):
@property @property
def temperature_unit(self): def temperature_unit(self):
"""Return the unit of measurement.""" """Return the unit of measurement."""
from pysmartthings import Attribute
return UNIT_MAP.get( return UNIT_MAP.get(
self._device.status.attributes[Attribute.temperature].unit) self._device.status.attributes[Attribute.temperature].unit)

View file

@ -2,6 +2,7 @@
import logging import logging
from aiohttp import ClientResponseError from aiohttp import ClientResponseError
from pysmartthings import APIResponseError, AppOAuth, SmartThings
import voluptuous as vol import voluptuous as vol
from homeassistant import config_entries from homeassistant import config_entries
@ -54,8 +55,6 @@ class SmartThingsFlowHandler(config_entries.ConfigFlow):
async def async_step_user(self, user_input=None): async def async_step_user(self, user_input=None):
"""Get access token and validate it.""" """Get access token and validate it."""
from pysmartthings import APIResponseError, AppOAuth, SmartThings
errors = {} errors = {}
if user_input is None or CONF_ACCESS_TOKEN not in user_input: if user_input is None or CONF_ACCESS_TOKEN not in user_input:
return self._show_step_user(errors) return self._show_step_user(errors)
@ -182,8 +181,6 @@ class SmartThingsFlowHandler(config_entries.ConfigFlow):
Launched when the user completes the flow or when the SmartApp Launched when the user completes the flow or when the SmartApp
is installed into an additional location. is installed into an additional location.
""" """
from pysmartthings import SmartThings
if not self.api: if not self.api:
# Launched from the SmartApp install event handler # Launched from the SmartApp install event handler
self.api = SmartThings( self.api = SmartThings(

View file

@ -1,6 +1,8 @@
"""Support for covers through the SmartThings cloud API.""" """Support for covers through the SmartThings cloud API."""
from typing import Optional, Sequence from typing import Optional, Sequence
from pysmartthings import Attribute, Capability
from homeassistant.components.cover import ( from homeassistant.components.cover import (
ATTR_POSITION, DEVICE_CLASS_DOOR, DEVICE_CLASS_GARAGE, DEVICE_CLASS_SHADE, ATTR_POSITION, DEVICE_CLASS_DOOR, DEVICE_CLASS_GARAGE, DEVICE_CLASS_SHADE,
DOMAIN as COVER_DOMAIN, STATE_CLOSED, STATE_CLOSING, STATE_OPEN, DOMAIN as COVER_DOMAIN, STATE_CLOSED, STATE_CLOSING, STATE_OPEN,
@ -37,8 +39,6 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
def get_capabilities(capabilities: Sequence[str]) -> Optional[Sequence[str]]: def get_capabilities(capabilities: Sequence[str]) -> Optional[Sequence[str]]:
"""Return all capabilities supported if minimum required are present.""" """Return all capabilities supported if minimum required are present."""
from pysmartthings import Capability
min_required = [ min_required = [
Capability.door_control, Capability.door_control,
Capability.garage_door_control, Capability.garage_door_control,
@ -58,8 +58,6 @@ class SmartThingsCover(SmartThingsEntity, CoverDevice):
def __init__(self, device): def __init__(self, device):
"""Initialize the cover class.""" """Initialize the cover class."""
from pysmartthings import Capability
super().__init__(device) super().__init__(device)
self._device_class = None self._device_class = None
self._state = None self._state = None
@ -93,8 +91,6 @@ class SmartThingsCover(SmartThingsEntity, CoverDevice):
async def async_update(self): async def async_update(self):
"""Update the attrs of the cover.""" """Update the attrs of the cover."""
from pysmartthings import Attribute, Capability
value = None value = None
if Capability.door_control in self._device.capabilities: if Capability.door_control in self._device.capabilities:
self._device_class = DEVICE_CLASS_DOOR self._device_class = DEVICE_CLASS_DOOR

View file

@ -1,6 +1,8 @@
"""Support for fans through the SmartThings cloud API.""" """Support for fans through the SmartThings cloud API."""
from typing import Optional, Sequence from typing import Optional, Sequence
from pysmartthings import Capability
from homeassistant.components.fan import ( from homeassistant.components.fan import (
SPEED_HIGH, SPEED_LOW, SPEED_MEDIUM, SPEED_OFF, SUPPORT_SET_SPEED, SPEED_HIGH, SPEED_LOW, SPEED_MEDIUM, SPEED_OFF, SUPPORT_SET_SPEED,
FanEntity) FanEntity)
@ -34,8 +36,6 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
def get_capabilities(capabilities: Sequence[str]) -> Optional[Sequence[str]]: def get_capabilities(capabilities: Sequence[str]) -> Optional[Sequence[str]]:
"""Return all capabilities supported if minimum required are present.""" """Return all capabilities supported if minimum required are present."""
from pysmartthings import Capability
supported = [Capability.switch, Capability.fan_speed] supported = [Capability.switch, Capability.fan_speed]
# Must have switch and fan_speed # Must have switch and fan_speed
if all(capability in capabilities for capability in supported): if all(capability in capabilities for capability in supported):

View file

@ -2,6 +2,8 @@
import asyncio import asyncio
from typing import Optional, Sequence from typing import Optional, Sequence
from pysmartthings import Capability
from homeassistant.components.light import ( from homeassistant.components.light import (
ATTR_BRIGHTNESS, ATTR_COLOR_TEMP, ATTR_HS_COLOR, ATTR_TRANSITION, ATTR_BRIGHTNESS, ATTR_COLOR_TEMP, ATTR_HS_COLOR, ATTR_TRANSITION,
SUPPORT_BRIGHTNESS, SUPPORT_COLOR, SUPPORT_COLOR_TEMP, SUPPORT_TRANSITION, SUPPORT_BRIGHTNESS, SUPPORT_COLOR, SUPPORT_COLOR_TEMP, SUPPORT_TRANSITION,
@ -28,8 +30,6 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
def get_capabilities(capabilities: Sequence[str]) -> Optional[Sequence[str]]: def get_capabilities(capabilities: Sequence[str]) -> Optional[Sequence[str]]:
"""Return all capabilities supported if minimum required are present.""" """Return all capabilities supported if minimum required are present."""
from pysmartthings import Capability
supported = [ supported = [
Capability.switch, Capability.switch,
Capability.switch_level, Capability.switch_level,
@ -69,8 +69,6 @@ class SmartThingsLight(SmartThingsEntity, Light):
def _determine_features(self): def _determine_features(self):
"""Get features supported by the device.""" """Get features supported by the device."""
from pysmartthings.device import Capability
features = 0 features = 0
# Brightness and transition # Brightness and transition
if Capability.switch_level in self._device.capabilities: if Capability.switch_level in self._device.capabilities:

View file

@ -1,6 +1,8 @@
"""Support for locks through the SmartThings cloud API.""" """Support for locks through the SmartThings cloud API."""
from typing import Optional, Sequence from typing import Optional, Sequence
from pysmartthings import Attribute, Capability
from homeassistant.components.lock import LockDevice from homeassistant.components.lock import LockDevice
from . import SmartThingsEntity from . import SmartThingsEntity
@ -33,8 +35,6 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
def get_capabilities(capabilities: Sequence[str]) -> Optional[Sequence[str]]: def get_capabilities(capabilities: Sequence[str]) -> Optional[Sequence[str]]:
"""Return all capabilities supported if minimum required are present.""" """Return all capabilities supported if minimum required are present."""
from pysmartthings import Capability
if Capability.lock in capabilities: if Capability.lock in capabilities:
return [Capability.lock] return [Capability.lock]
return None return None
@ -61,7 +61,6 @@ class SmartThingsLock(SmartThingsEntity, LockDevice):
@property @property
def device_state_attributes(self): def device_state_attributes(self):
"""Return device specific state attributes.""" """Return device specific state attributes."""
from pysmartthings import Attribute
state_attrs = {} state_attrs = {}
status = self._device.status.attributes[Attribute.lock] status = self._device.status.attributes[Attribute.lock]
if status.value: if status.value:

View file

@ -2,10 +2,12 @@
from collections import namedtuple from collections import namedtuple
from typing import Optional, Sequence from typing import Optional, Sequence
from pysmartthings import Attribute, Capability
from homeassistant.const import ( from homeassistant.const import (
DEVICE_CLASS_BATTERY, DEVICE_CLASS_HUMIDITY, DEVICE_CLASS_ILLUMINANCE, DEVICE_CLASS_BATTERY, DEVICE_CLASS_HUMIDITY, DEVICE_CLASS_ILLUMINANCE,
DEVICE_CLASS_TEMPERATURE, DEVICE_CLASS_TIMESTAMP, MASS_KILOGRAMS, DEVICE_CLASS_TEMPERATURE, DEVICE_CLASS_TIMESTAMP, ENERGY_KILO_WATT_HOUR,
ENERGY_KILO_WATT_HOUR, POWER_WATT, TEMP_CELSIUS, TEMP_FAHRENHEIT) MASS_KILOGRAMS, POWER_WATT, TEMP_CELSIUS, TEMP_FAHRENHEIT)
from . import SmartThingsEntity from . import SmartThingsEntity
from .const import DATA_BROKERS, DOMAIN from .const import DATA_BROKERS, DOMAIN
@ -13,132 +15,139 @@ from .const import DATA_BROKERS, DOMAIN
Map = namedtuple("map", "attribute name default_unit device_class") Map = namedtuple("map", "attribute name default_unit device_class")
CAPABILITY_TO_SENSORS = { CAPABILITY_TO_SENSORS = {
'activityLightingMode': [ Capability.activity_lighting_mode: [
Map('lightingMode', "Activity Lighting Mode", None, None)], Map(Attribute.lighting_mode, "Activity Lighting Mode", None, None)],
'airConditionerMode': [ Capability.air_conditioner_mode: [
Map('airConditionerMode', "Air Conditioner Mode", None, None)], Map(Attribute.air_conditioner_mode, "Air Conditioner Mode", None,
'airQualitySensor': [
Map('airQuality', "Air Quality", 'CAQI', None)],
'alarm': [
Map('alarm', "Alarm", None, None)],
'audioVolume': [
Map('volume', "Volume", "%", None)],
'battery': [
Map('battery', "Battery", "%", DEVICE_CLASS_BATTERY)],
'bodyMassIndexMeasurement': [
Map('bmiMeasurement', "Body Mass Index", "kg/m^2", None)],
'bodyWeightMeasurement': [
Map('bodyWeightMeasurement', "Body Weight", MASS_KILOGRAMS, None)],
'carbonDioxideMeasurement': [
Map('carbonDioxide', "Carbon Dioxide Measurement", "ppm", None)],
'carbonMonoxideDetector': [
Map('carbonMonoxide', "Carbon Monoxide Detector", None, None)],
'carbonMonoxideMeasurement': [
Map('carbonMonoxideLevel', "Carbon Monoxide Measurement", "ppm",
None)], None)],
'dishwasherOperatingState': [ Capability.air_quality_sensor: [
Map('machineState', "Dishwasher Machine State", None, None), Map(Attribute.air_quality, "Air Quality", 'CAQI', None)],
Map('dishwasherJobState', "Dishwasher Job State", None, None), Capability.alarm: [
Map('completionTime', "Dishwasher Completion Time", None, Map(Attribute.alarm, "Alarm", None, None)],
Capability.audio_volume: [
Map(Attribute.volume, "Volume", "%", None)],
Capability.battery: [
Map(Attribute.battery, "Battery", "%", DEVICE_CLASS_BATTERY)],
Capability.body_mass_index_measurement: [
Map(Attribute.bmi_measurement, "Body Mass Index", "kg/m^2", None)],
Capability.body_weight_measurement: [
Map(Attribute.body_weight_measurement, "Body Weight", MASS_KILOGRAMS,
None)],
Capability.carbon_dioxide_measurement: [
Map(Attribute.carbon_dioxide, "Carbon Dioxide Measurement", "ppm",
None)],
Capability.carbon_monoxide_detector: [
Map(Attribute.carbon_monoxide, "Carbon Monoxide Detector", None,
None)],
Capability.carbon_monoxide_measurement: [
Map(Attribute.carbon_monoxide_level, "Carbon Monoxide Measurement",
"ppm", None)],
Capability.dishwasher_operating_state: [
Map(Attribute.machine_state, "Dishwasher Machine State", None, None),
Map(Attribute.dishwasher_job_state, "Dishwasher Job State", None,
None),
Map(Attribute.completion_time, "Dishwasher Completion Time", None,
DEVICE_CLASS_TIMESTAMP)], DEVICE_CLASS_TIMESTAMP)],
'dryerMode': [ Capability.dryer_mode: [
Map('dryerMode', "Dryer Mode", None, None)], Map(Attribute.dryer_mode, "Dryer Mode", None, None)],
'dryerOperatingState': [ Capability.dryer_operating_state: [
Map('machineState', "Dryer Machine State", None, None), Map(Attribute.machine_state, "Dryer Machine State", None, None),
Map('dryerJobState', "Dryer Job State", None, None), Map(Attribute.dryer_job_state, "Dryer Job State", None, None),
Map('completionTime', "Dryer Completion Time", None, Map(Attribute.completion_time, "Dryer Completion Time", None,
DEVICE_CLASS_TIMESTAMP)], DEVICE_CLASS_TIMESTAMP)],
'dustSensor': [ Capability.dust_sensor: [
Map('fineDustLevel', "Fine Dust Level", None, None), Map(Attribute.fine_dust_level, "Fine Dust Level", None, None),
Map('dustLevel', "Dust Level", None, None)], Map(Attribute.dust_level, "Dust Level", None, None)],
'energyMeter': [ Capability.energy_meter: [
Map('energy', "Energy Meter", ENERGY_KILO_WATT_HOUR, None)], Map(Attribute.energy, "Energy Meter", ENERGY_KILO_WATT_HOUR, None)],
'equivalentCarbonDioxideMeasurement': [ Capability.equivalent_carbon_dioxide_measurement: [
Map('equivalentCarbonDioxideMeasurement', Map(Attribute.equivalent_carbon_dioxide_measurement,
'Equivalent Carbon Dioxide Measurement', 'ppm', None)], 'Equivalent Carbon Dioxide Measurement', 'ppm', None)],
'formaldehydeMeasurement': [ Capability.formaldehyde_measurement: [
Map('formaldehydeLevel', 'Formaldehyde Measurement', 'ppm', None)], Map(Attribute.formaldehyde_level, 'Formaldehyde Measurement', 'ppm',
'illuminanceMeasurement': [ None)],
Map('illuminance', "Illuminance", 'lux', DEVICE_CLASS_ILLUMINANCE)], Capability.illuminance_measurement: [
'infraredLevel': [ Map(Attribute.illuminance, "Illuminance", 'lux',
Map('infraredLevel', "Infrared Level", '%', None)], DEVICE_CLASS_ILLUMINANCE)],
'lock': [ Capability.infrared_level: [
Map('lock', "Lock", None, None)], Map(Attribute.infrared_level, "Infrared Level", '%', None)],
'mediaInputSource': [ Capability.media_input_source: [
Map('inputSource', "Media Input Source", None, None)], Map(Attribute.input_source, "Media Input Source", None, None)],
'mediaPlaybackRepeat': [ Capability.media_playback_repeat: [
Map('playbackRepeatMode', "Media Playback Repeat", None, None)], Map(Attribute.playback_repeat_mode, "Media Playback Repeat", None,
'mediaPlaybackShuffle': [ None)],
Map('playbackShuffle', "Media Playback Shuffle", None, None)], Capability.media_playback_shuffle: [
'mediaPlayback': [ Map(Attribute.playback_shuffle, "Media Playback Shuffle", None, None)],
Map('playbackStatus', "Media Playback Status", None, None)], Capability.media_playback: [
'odorSensor': [ Map(Attribute.playback_status, "Media Playback Status", None, None)],
Map('odorLevel', "Odor Sensor", None, None)], Capability.odor_sensor: [
'ovenMode': [ Map(Attribute.odor_level, "Odor Sensor", None, None)],
Map('ovenMode', "Oven Mode", None, None)], Capability.oven_mode: [
'ovenOperatingState': [ Map(Attribute.oven_mode, "Oven Mode", None, None)],
Map('machineState', "Oven Machine State", None, None), Capability.oven_operating_state: [
Map('ovenJobState', "Oven Job State", None, None), Map(Attribute.machine_state, "Oven Machine State", None, None),
Map('completionTime', "Oven Completion Time", None, None)], Map(Attribute.oven_job_state, "Oven Job State", None, None),
'ovenSetpoint': [ Map(Attribute.completion_time, "Oven Completion Time", None, None)],
Map('ovenSetpoint', "Oven Set Point", None, None)], Capability.oven_setpoint: [
'powerMeter': [ Map(Attribute.oven_setpoint, "Oven Set Point", None, None)],
Map('power', "Power Meter", POWER_WATT, None)], Capability.power_meter: [
'powerSource': [ Map(Attribute.power, "Power Meter", POWER_WATT, None)],
Map('powerSource', "Power Source", None, None)], Capability.power_source: [
'refrigerationSetpoint': [ Map(Attribute.power_source, "Power Source", None, None)],
Map('refrigerationSetpoint', "Refrigeration Setpoint", None, Capability.refrigeration_setpoint: [
Map(Attribute.refrigeration_setpoint, "Refrigeration Setpoint", None,
DEVICE_CLASS_TEMPERATURE)], DEVICE_CLASS_TEMPERATURE)],
'relativeHumidityMeasurement': [ Capability.relative_humidity_measurement: [
Map('humidity', "Relative Humidity Measurement", '%', Map(Attribute.humidity, "Relative Humidity Measurement", '%',
DEVICE_CLASS_HUMIDITY)], DEVICE_CLASS_HUMIDITY)],
'robotCleanerCleaningMode': [ Capability.robot_cleaner_cleaning_mode: [
Map('robotCleanerCleaningMode', "Robot Cleaner Cleaning Mode", Map(Attribute.robot_cleaner_cleaning_mode,
"Robot Cleaner Cleaning Mode", None, None)],
Capability.robot_cleaner_movement: [
Map(Attribute.robot_cleaner_movement, "Robot Cleaner Movement", None,
None)],
Capability.robot_cleaner_turbo_mode: [
Map(Attribute.robot_cleaner_turbo_mode, "Robot Cleaner Turbo Mode",
None, None)], None, None)],
'robotCleanerMovement': [ Capability.signal_strength: [
Map('robotCleanerMovement', "Robot Cleaner Movement", None, None)], Map(Attribute.lqi, "LQI Signal Strength", None, None),
'robotCleanerTurboMode': [ Map(Attribute.rssi, "RSSI Signal Strength", None, None)],
Map('robotCleanerTurboMode', "Robot Cleaner Turbo Mode", None, None)], Capability.smoke_detector: [
'signalStrength': [ Map(Attribute.smoke, "Smoke Detector", None, None)],
Map('lqi', "LQI Signal Strength", None, None), Capability.temperature_measurement: [
Map('rssi', "RSSI Signal Strength", None, None)], Map(Attribute.temperature, "Temperature Measurement", None,
'smokeDetector': [
Map('smoke', "Smoke Detector", None, None)],
'temperatureMeasurement': [
Map('temperature', "Temperature Measurement", None,
DEVICE_CLASS_TEMPERATURE)], DEVICE_CLASS_TEMPERATURE)],
'thermostatCoolingSetpoint': [ Capability.thermostat_cooling_setpoint: [
Map('coolingSetpoint', "Thermostat Cooling Setpoint", None, Map(Attribute.cooling_setpoint, "Thermostat Cooling Setpoint", None,
DEVICE_CLASS_TEMPERATURE)], DEVICE_CLASS_TEMPERATURE)],
'thermostatFanMode': [ Capability.thermostat_fan_mode: [
Map('thermostatFanMode', "Thermostat Fan Mode", None, None)], Map(Attribute.thermostat_fan_mode, "Thermostat Fan Mode", None, None)],
'thermostatHeatingSetpoint': [ Capability.thermostat_heating_setpoint: [
Map('heatingSetpoint', "Thermostat Heating Setpoint", None, Map(Attribute.heating_setpoint, "Thermostat Heating Setpoint", None,
DEVICE_CLASS_TEMPERATURE)], DEVICE_CLASS_TEMPERATURE)],
'thermostatMode': [ Capability.thermostat_mode: [
Map('thermostatMode', "Thermostat Mode", None, None)], Map(Attribute.thermostat_mode, "Thermostat Mode", None, None)],
'thermostatOperatingState': [ Capability.thermostat_operating_state: [
Map('thermostatOperatingState', "Thermostat Operating State", Map(Attribute.thermostat_operating_state, "Thermostat Operating State",
None, None)], None, None)],
'thermostatSetpoint': [ Capability.thermostat_setpoint: [
Map('thermostatSetpoint', "Thermostat Setpoint", None, Map(Attribute.thermostat_setpoint, "Thermostat Setpoint", None,
DEVICE_CLASS_TEMPERATURE)], DEVICE_CLASS_TEMPERATURE)],
'threeAxis': [ Capability.three_axis: [],
Map('threeAxis', "Three Axis", None, None)], Capability.tv_channel: [
'tvChannel': [ Map(Attribute.tv_channel, "Tv Channel", None, None)],
Map('tvChannel', "Tv Channel", None, None)], Capability.tvoc_measurement: [
'tvocMeasurement': [ Map(Attribute.tvoc_level, "Tvoc Measurement", 'ppm', None)],
Map('tvocLevel', "Tvoc Measurement", 'ppm', None)], Capability.ultraviolet_index: [
'ultravioletIndex': [ Map(Attribute.ultraviolet_index, "Ultraviolet Index", None, None)],
Map('ultravioletIndex', "Ultraviolet Index", None, None)], Capability.voltage_measurement: [
'voltageMeasurement': [ Map(Attribute.voltage, "Voltage Measurement", 'V', None)],
Map('voltage', "Voltage Measurement", 'V', None)], Capability.washer_mode: [
'washerMode': [ Map(Attribute.washer_mode, "Washer Mode", None, None)],
Map('washerMode', "Washer Mode", None, None)], Capability.washer_operating_state: [
'washerOperatingState': [ Map(Attribute.machine_state, "Washer Machine State", None, None),
Map('machineState', "Washer Machine State", None, None), Map(Attribute.washer_job_state, "Washer Job State", None, None),
Map('washerJobState', "Washer Job State", None, None), Map(Attribute.completion_time, "Washer Completion Time", None,
Map('completionTime', "Washer Completion Time", None,
DEVICE_CLASS_TIMESTAMP)] DEVICE_CLASS_TIMESTAMP)]
} }
@ -158,7 +167,6 @@ async def async_setup_platform(
async def async_setup_entry(hass, config_entry, async_add_entities): async def async_setup_entry(hass, config_entry, async_add_entities):
"""Add binary sensors for a config entry.""" """Add binary sensors for a config entry."""
from pysmartthings import Capability
broker = hass.data[DOMAIN][DATA_BROKERS][config_entry.entry_id] broker = hass.data[DOMAIN][DATA_BROKERS][config_entry.entry_id]
sensors = [] sensors = []
for device in broker.devices.values(): for device in broker.devices.values():
@ -245,7 +253,6 @@ class SmartThingsThreeAxisSensor(SmartThingsEntity):
@property @property
def state(self): def state(self):
"""Return the state of the sensor.""" """Return the state of the sensor."""
from pysmartthings import Attribute
three_axis = self._device.status.attributes[Attribute.three_axis].value three_axis = self._device.status.attributes[Attribute.three_axis].value
try: try:
return three_axis[self._index] return three_axis[self._index]

View file

@ -6,6 +6,12 @@ from urllib.parse import urlparse
from uuid import uuid4 from uuid import uuid4
from aiohttp import web from aiohttp import web
from pysmartapp import Dispatcher, SmartAppManager
from pysmartapp.const import SETTINGS_APP_ID
from pysmartthings import (
APP_TYPE_WEBHOOK, CAPABILITIES, CLASSIFICATION_AUTOMATION, App, AppOAuth,
AppSettings, InstalledAppStatus, SmartThings, SourceType, Subscription,
SubscriptionEntity)
from homeassistant.components import cloud, webhook from homeassistant.components import cloud, webhook
from homeassistant.const import CONF_WEBHOOK_ID from homeassistant.const import CONF_WEBHOOK_ID
@ -43,8 +49,6 @@ async def validate_installed_app(api, installed_app_id: str):
Query the API for the installed SmartApp and validate that it is tied to Query the API for the installed SmartApp and validate that it is tied to
the specified app_id and is in an authorized state. the specified app_id and is in an authorized state.
""" """
from pysmartthings import InstalledAppStatus
installed_app = await api.installed_app(installed_app_id) installed_app = await api.installed_app(installed_app_id)
if installed_app.installed_app_status != InstalledAppStatus.AUTHORIZED: if installed_app.installed_app_status != InstalledAppStatus.AUTHORIZED:
raise RuntimeWarning("Installed SmartApp instance '{}' ({}) is not " raise RuntimeWarning("Installed SmartApp instance '{}' ({}) is not "
@ -77,8 +81,6 @@ def get_webhook_url(hass: HomeAssistantType) -> str:
def _get_app_template(hass: HomeAssistantType): def _get_app_template(hass: HomeAssistantType):
from pysmartthings import APP_TYPE_WEBHOOK, CLASSIFICATION_AUTOMATION
endpoint = "at " + hass.config.api.base_url endpoint = "at " + hass.config.api.base_url
cloudhook_url = hass.data[DOMAIN][CONF_CLOUDHOOK_URL] cloudhook_url = hass.data[DOMAIN][CONF_CLOUDHOOK_URL]
if cloudhook_url is not None: if cloudhook_url is not None:
@ -98,9 +100,6 @@ def _get_app_template(hass: HomeAssistantType):
async def create_app(hass: HomeAssistantType, api): async def create_app(hass: HomeAssistantType, api):
"""Create a SmartApp for this instance of hass.""" """Create a SmartApp for this instance of hass."""
from pysmartthings import App, AppOAuth, AppSettings
from pysmartapp.const import SETTINGS_APP_ID
# Create app from template attributes # Create app from template attributes
template = _get_app_template(hass) template = _get_app_template(hass)
app = App() app = App()
@ -170,8 +169,6 @@ async def setup_smartapp_endpoint(hass: HomeAssistantType):
SmartApps are an extension point within the SmartThings ecosystem and SmartApps are an extension point within the SmartThings ecosystem and
is used to receive push updates (i.e. device updates) from the cloud. is used to receive push updates (i.e. device updates) from the cloud.
""" """
from pysmartapp import Dispatcher, SmartAppManager
data = hass.data.get(DOMAIN) data = hass.data.get(DOMAIN)
if data: if data:
# already setup # already setup
@ -264,11 +261,6 @@ async def smartapp_sync_subscriptions(
hass: HomeAssistantType, auth_token: str, location_id: str, hass: HomeAssistantType, auth_token: str, location_id: str,
installed_app_id: str, devices): installed_app_id: str, devices):
"""Synchronize subscriptions of an installed up.""" """Synchronize subscriptions of an installed up."""
from pysmartthings import (
CAPABILITIES, SmartThings, SourceType, Subscription,
SubscriptionEntity
)
api = SmartThings(async_get_clientsession(hass), auth_token) api = SmartThings(async_get_clientsession(hass), auth_token)
tasks = [] tasks = []

View file

@ -1,6 +1,8 @@
"""Support for switches through the SmartThings cloud API.""" """Support for switches through the SmartThings cloud API."""
from typing import Optional, Sequence from typing import Optional, Sequence
from pysmartthings import Attribute, Capability
from homeassistant.components.switch import SwitchDevice from homeassistant.components.switch import SwitchDevice
from . import SmartThingsEntity from . import SmartThingsEntity
@ -23,8 +25,6 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
def get_capabilities(capabilities: Sequence[str]) -> Optional[Sequence[str]]: def get_capabilities(capabilities: Sequence[str]) -> Optional[Sequence[str]]:
"""Return all capabilities supported if minimum required are present.""" """Return all capabilities supported if minimum required are present."""
from pysmartthings import Capability
# Must be able to be turned on/off. # Must be able to be turned on/off.
if Capability.switch in capabilities: if Capability.switch in capabilities:
return [Capability.switch, return [Capability.switch,
@ -53,13 +53,11 @@ class SmartThingsSwitch(SmartThingsEntity, SwitchDevice):
@property @property
def current_power_w(self): def current_power_w(self):
"""Return the current power usage in W.""" """Return the current power usage in W."""
from pysmartthings import Attribute
return self._device.status.attributes[Attribute.power].value return self._device.status.attributes[Attribute.power].value
@property @property
def today_energy_kwh(self): def today_energy_kwh(self):
"""Return the today total energy usage in kWh.""" """Return the today total energy usage in kWh."""
from pysmartthings import Attribute
return self._device.status.attributes[Attribute.energy].value return self._device.status.attributes[Attribute.energy].value
@property @property

View file

@ -5,7 +5,8 @@ from uuid import uuid4
from pysmartthings import ( from pysmartthings import (
CLASSIFICATION_AUTOMATION, AppEntity, AppOAuthClient, AppSettings, CLASSIFICATION_AUTOMATION, AppEntity, AppOAuthClient, AppSettings,
DeviceEntity, InstalledApp, Location, SceneEntity, Subscription) DeviceEntity, InstalledApp, Location, SceneEntity, SmartThings,
Subscription)
from pysmartthings.api import Api from pysmartthings.api import Api
import pytest import pytest
@ -23,6 +24,8 @@ from homeassistant.setup import async_setup_component
from tests.common import mock_coro from tests.common import mock_coro
COMPONENT_PREFIX = "homeassistant.components.smartthings."
async def setup_platform(hass, platform: str, *, async def setup_platform(hass, platform: str, *,
devices=None, scenes=None): devices=None, scenes=None):
@ -163,8 +166,12 @@ def smartthings_mock_fixture(locations):
return_value=next(location for location in locations return_value=next(location for location in locations
if location.location_id == location_id)) if location.location_id == location_id))
with patch("pysmartthings.SmartThings", autospec=True) as mock: smartthings_mock = Mock(SmartThings)
mock.return_value.location.side_effect = _location smartthings_mock.location.side_effect = _location
mock = Mock(return_value=smartthings_mock)
with patch(COMPONENT_PREFIX + "SmartThings", new=mock), \
patch(COMPONENT_PREFIX + "config_flow.SmartThings", new=mock), \
patch(COMPONENT_PREFIX + "smartapp.SmartThings", new=mock):
yield mock yield mock