diff --git a/.coveragerc b/.coveragerc
index 0f453518adc..18139bddf08 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -1191,7 +1191,6 @@ omit =
homeassistant/components/webostv/*
homeassistant/components/whois/sensor.py
homeassistant/components/wiffi/*
- homeassistant/components/wink/*
homeassistant/components/wirelesstag/*
homeassistant/components/wolflink/__init__.py
homeassistant/components/wolflink/sensor.py
diff --git a/homeassistant/components/discovery/__init__.py b/homeassistant/components/discovery/__init__.py
index bade569bb46..595771cd673 100644
--- a/homeassistant/components/discovery/__init__.py
+++ b/homeassistant/components/discovery/__init__.py
@@ -38,7 +38,6 @@ SERVICE_SAMSUNG_PRINTER = "samsung_printer"
SERVICE_TELLDUSLIVE = "tellstick"
SERVICE_YEELIGHT = "yeelight"
SERVICE_WEMO = "belkin_wemo"
-SERVICE_WINK = "wink"
SERVICE_XIAOMI_GW = "xiaomi_gw"
# These have custom protocols
@@ -94,7 +93,6 @@ MIGRATED_SERVICE_HANDLERS = [
"sonos",
"songpal",
SERVICE_WEMO,
- SERVICE_WINK,
SERVICE_XIAOMI_GW,
"volumio",
SERVICE_YEELIGHT,
diff --git a/homeassistant/components/wink/__init__.py b/homeassistant/components/wink/__init__.py
deleted file mode 100644
index 702851a5e14..00000000000
--- a/homeassistant/components/wink/__init__.py
+++ /dev/null
@@ -1,971 +0,0 @@
-"""Support for Wink hubs."""
-from __future__ import annotations
-
-from datetime import timedelta
-import json
-import logging
-import os
-import time
-from typing import Any
-
-from aiohttp.web import Response
-from pubnubsubhandler import PubNubSubscriptionHandler
-import pywink
-import voluptuous as vol
-
-from homeassistant.components.http import HomeAssistantView
-from homeassistant.const import (
- ATTR_BATTERY_LEVEL,
- ATTR_NAME,
- CONF_CLIENT_ID,
- CONF_CLIENT_SECRET,
- CONF_EMAIL,
- CONF_PASSWORD,
- EVENT_HOMEASSISTANT_START,
- EVENT_HOMEASSISTANT_STOP,
- STATE_OFF,
- STATE_ON,
- __version__,
-)
-from homeassistant.core import callback
-from homeassistant.helpers import discovery
-import homeassistant.helpers.config_validation as cv
-from homeassistant.helpers.config_validation import make_entity_service_schema
-from homeassistant.helpers.entity import Entity
-from homeassistant.helpers.entity_component import EntityComponent
-from homeassistant.helpers.event import track_time_interval
-from homeassistant.helpers.network import get_url
-from homeassistant.util.json import load_json, save_json
-
-_LOGGER = logging.getLogger(__name__)
-
-DOMAIN = "wink"
-
-SUBSCRIPTION_HANDLER = None
-
-CONF_USER_AGENT = "user_agent"
-CONF_OAUTH = "oauth"
-CONF_LOCAL_CONTROL = "local_control"
-CONF_MISSING_OAUTH_MSG = "Missing oauth2 credentials."
-
-ATTR_ACCESS_TOKEN = "access_token"
-ATTR_REFRESH_TOKEN = "refresh_token"
-ATTR_PAIRING_MODE = "pairing_mode"
-ATTR_KIDDE_RADIO_CODE = "kidde_radio_code"
-ATTR_HUB_NAME = "hub_name"
-
-WINK_AUTH_CALLBACK_PATH = "/auth/wink/callback"
-WINK_AUTH_START = "/auth/wink"
-WINK_CONFIG_FILE = ".wink.conf"
-USER_AGENT = f"Manufacturer/Home-Assistant{__version__} python/3 Wink/3"
-
-DEFAULT_CONFIG = {
- CONF_CLIENT_ID: "CLIENT_ID_HERE",
- CONF_CLIENT_SECRET: "CLIENT_SECRET_HERE",
-}
-
-SERVICE_ADD_NEW_DEVICES = "pull_newly_added_devices_from_wink"
-SERVICE_REFRESH_STATES = "refresh_state_from_wink"
-SERVICE_RENAME_DEVICE = "rename_wink_device"
-SERVICE_DELETE_DEVICE = "delete_wink_device"
-SERVICE_SET_PAIRING_MODE = "pair_new_device"
-SERVICE_SET_CHIME_VOLUME = "set_chime_volume"
-SERVICE_SET_SIREN_VOLUME = "set_siren_volume"
-SERVICE_ENABLE_CHIME = "enable_chime"
-SERVICE_SET_SIREN_TONE = "set_siren_tone"
-SERVICE_SET_AUTO_SHUTOFF = "siren_set_auto_shutoff"
-SERVICE_SIREN_STROBE_ENABLED = "set_siren_strobe_enabled"
-SERVICE_CHIME_STROBE_ENABLED = "set_chime_strobe_enabled"
-SERVICE_ENABLE_SIREN = "enable_siren"
-SERVICE_SET_DIAL_CONFIG = "set_nimbus_dial_configuration"
-SERVICE_SET_DIAL_STATE = "set_nimbus_dial_state"
-
-ATTR_VOLUME = "volume"
-ATTR_TONE = "tone"
-ATTR_ENABLED = "enabled"
-ATTR_AUTO_SHUTOFF = "auto_shutoff"
-ATTR_MIN_VALUE = "min_value"
-ATTR_MAX_VALUE = "max_value"
-ATTR_ROTATION = "rotation"
-ATTR_SCALE = "scale"
-ATTR_TICKS = "ticks"
-ATTR_MIN_POSITION = "min_position"
-ATTR_MAX_POSITION = "max_position"
-ATTR_VALUE = "value"
-ATTR_LABELS = "labels"
-
-SCALES = ["linear", "log"]
-ROTATIONS = ["cw", "ccw"]
-
-VOLUMES = ["low", "medium", "high"]
-TONES = [
- "doorbell",
- "fur_elise",
- "doorbell_extended",
- "alert",
- "william_tell",
- "rondo_alla_turca",
- "police_siren",
- "evacuation",
- "beep_beep",
- "beep",
-]
-CHIME_TONES = TONES + ["inactive"]
-AUTO_SHUTOFF_TIMES = [None, -1, 30, 60, 120]
-
-CONFIG_SCHEMA = vol.Schema(
- vol.All(
- cv.deprecated(DOMAIN),
- {
- DOMAIN: vol.Schema(
- {
- vol.Inclusive(
- CONF_EMAIL, CONF_OAUTH, msg=CONF_MISSING_OAUTH_MSG
- ): cv.string,
- vol.Inclusive(
- CONF_PASSWORD, CONF_OAUTH, msg=CONF_MISSING_OAUTH_MSG
- ): cv.string,
- vol.Inclusive(
- CONF_CLIENT_ID, CONF_OAUTH, msg=CONF_MISSING_OAUTH_MSG
- ): cv.string,
- vol.Inclusive(
- CONF_CLIENT_SECRET, CONF_OAUTH, msg=CONF_MISSING_OAUTH_MSG
- ): cv.string,
- vol.Optional(CONF_LOCAL_CONTROL, default=False): cv.boolean,
- }
- ),
- },
- ),
- extra=vol.ALLOW_EXTRA,
-)
-
-RENAME_DEVICE_SCHEMA = make_entity_service_schema(
- {vol.Required(ATTR_NAME): cv.string}, extra=vol.ALLOW_EXTRA
-)
-
-DELETE_DEVICE_SCHEMA = make_entity_service_schema({}, extra=vol.ALLOW_EXTRA)
-
-SET_PAIRING_MODE_SCHEMA = vol.Schema(
- {
- vol.Required(ATTR_HUB_NAME): cv.string,
- vol.Required(ATTR_PAIRING_MODE): cv.string,
- vol.Optional(ATTR_KIDDE_RADIO_CODE): cv.string,
- },
- extra=vol.ALLOW_EXTRA,
-)
-
-SET_VOLUME_SCHEMA = make_entity_service_schema(
- {vol.Required(ATTR_VOLUME): vol.In(VOLUMES)}
-)
-
-SET_SIREN_TONE_SCHEMA = make_entity_service_schema(
- {vol.Required(ATTR_TONE): vol.In(TONES)}
-)
-
-SET_CHIME_MODE_SCHEMA = make_entity_service_schema(
- {vol.Required(ATTR_TONE): vol.In(CHIME_TONES)}
-)
-
-SET_AUTO_SHUTOFF_SCHEMA = make_entity_service_schema(
- {vol.Required(ATTR_AUTO_SHUTOFF): vol.In(AUTO_SHUTOFF_TIMES)}
-)
-
-SET_STROBE_ENABLED_SCHEMA = make_entity_service_schema(
- {vol.Required(ATTR_ENABLED): cv.boolean}
-)
-
-ENABLED_SIREN_SCHEMA = make_entity_service_schema(
- {vol.Required(ATTR_ENABLED): cv.boolean}
-)
-
-DIAL_CONFIG_SCHEMA = make_entity_service_schema(
- {
- vol.Optional(ATTR_MIN_VALUE): vol.Coerce(int),
- vol.Optional(ATTR_MAX_VALUE): vol.Coerce(int),
- vol.Optional(ATTR_MIN_POSITION): cv.positive_int,
- vol.Optional(ATTR_MAX_POSITION): cv.positive_int,
- vol.Optional(ATTR_ROTATION): vol.In(ROTATIONS),
- vol.Optional(ATTR_SCALE): vol.In(SCALES),
- vol.Optional(ATTR_TICKS): cv.positive_int,
- }
-)
-
-DIAL_STATE_SCHEMA = make_entity_service_schema(
- {
- vol.Required(ATTR_VALUE): vol.Coerce(int),
- vol.Optional(ATTR_LABELS): cv.ensure_list(cv.string),
- }
-)
-
-WINK_COMPONENTS = [
- "binary_sensor",
- "sensor",
- "light",
- "switch",
- "lock",
- "cover",
- "climate",
- "fan",
- "alarm_control_panel",
- "scene",
- "water_heater",
-]
-
-WINK_HUBS: list[Any] = []
-
-
-def _request_app_setup(hass, config):
- """Assist user with configuring the Wink dev application."""
- hass.data[DOMAIN]["configurator"] = True
- configurator = hass.components.configurator
-
- def wink_configuration_callback(callback_data):
- """Handle configuration updates."""
- _config_path = hass.config.path(WINK_CONFIG_FILE)
- if not os.path.isfile(_config_path):
- setup(hass, config)
- return
-
- client_id = callback_data.get(CONF_CLIENT_ID).strip()
- client_secret = callback_data.get(CONF_CLIENT_SECRET).strip()
- if None not in (client_id, client_secret):
- save_json(
- _config_path,
- {CONF_CLIENT_ID: client_id, CONF_CLIENT_SECRET: client_secret},
- )
- setup(hass, config)
- return
- error_msg = "Your input was invalid. Please try again."
- _configurator = hass.data[DOMAIN]["configuring"][DOMAIN]
- configurator.notify_errors(_configurator, error_msg)
-
- start_url = f"{get_url(hass)}{WINK_AUTH_CALLBACK_PATH}"
-
- description = f"""Please create a Wink developer app at
- https://developer.wink.com.
- Add a Redirect URI of {start_url}.
- They will provide you a Client ID and secret
- after reviewing your request.
- (This can take several days).
- """
-
- hass.data[DOMAIN]["configuring"][DOMAIN] = configurator.request_config(
- DOMAIN,
- wink_configuration_callback,
- description=description,
- submit_caption="submit",
- description_image="/static/images/config_wink.png",
- fields=[
- {"id": CONF_CLIENT_ID, "name": "Client ID", "type": "string"},
- {"id": CONF_CLIENT_SECRET, "name": "Client secret", "type": "string"},
- ],
- )
-
-
-def _request_oauth_completion(hass, config):
- """Request user complete Wink OAuth2 flow."""
- hass.data[DOMAIN]["configurator"] = True
- configurator = hass.components.configurator
- if DOMAIN in hass.data[DOMAIN]["configuring"]:
- configurator.notify_errors(
- hass.data[DOMAIN]["configuring"][DOMAIN],
- "Failed to register, please try again.",
- )
- return
-
- def wink_configuration_callback(callback_data):
- """Call setup again."""
- setup(hass, config)
-
- start_url = f"{get_url(hass)}{WINK_AUTH_START}"
-
- description = f"Please authorize Wink by visiting {start_url}"
-
- hass.data[DOMAIN]["configuring"][DOMAIN] = configurator.request_config(
- DOMAIN, wink_configuration_callback, description=description
- )
-
-
-def setup(hass, config): # noqa: C901
- """Set up the Wink component."""
- _LOGGER.warning(
- "The Wink integration has been deprecated and is pending removal in "
- "Home Assistant Core 2021.11"
- )
-
- if hass.data.get(DOMAIN) is None:
- hass.data[DOMAIN] = {
- "unique_ids": [],
- "entities": {},
- "oauth": {},
- "configuring": {},
- "pubnub": None,
- "configurator": False,
- }
-
- if config.get(DOMAIN) is not None:
- client_id = config[DOMAIN].get(CONF_CLIENT_ID)
- client_secret = config[DOMAIN].get(CONF_CLIENT_SECRET)
- email = config[DOMAIN].get(CONF_EMAIL)
- password = config[DOMAIN].get(CONF_PASSWORD)
- local_control = config[DOMAIN].get(CONF_LOCAL_CONTROL)
- else:
- client_id = None
- client_secret = None
- email = None
- password = None
- local_control = None
- hass.data[DOMAIN]["configurator"] = True
- if None not in [client_id, client_secret]:
- _LOGGER.info("Using legacy OAuth authentication")
- if not local_control:
- pywink.disable_local_control()
- hass.data[DOMAIN]["oauth"][CONF_CLIENT_ID] = client_id
- hass.data[DOMAIN]["oauth"][CONF_CLIENT_SECRET] = client_secret
- hass.data[DOMAIN]["oauth"]["email"] = email
- hass.data[DOMAIN]["oauth"]["password"] = password
- pywink.legacy_set_wink_credentials(email, password, client_id, client_secret)
- else:
- _LOGGER.info("Using OAuth authentication")
- if not local_control:
- pywink.disable_local_control()
- config_path = hass.config.path(WINK_CONFIG_FILE)
- if os.path.isfile(config_path):
- config_file = load_json(config_path)
- if config_file == DEFAULT_CONFIG:
- _request_app_setup(hass, config)
- return True
- # else move on because the user modified the file
- else:
- save_json(config_path, DEFAULT_CONFIG)
- _request_app_setup(hass, config)
- return True
-
- if DOMAIN in hass.data[DOMAIN]["configuring"]:
- _configurator = hass.data[DOMAIN]["configuring"]
- hass.components.configurator.request_done(_configurator.pop(DOMAIN))
-
- # Using oauth
- access_token = config_file.get(ATTR_ACCESS_TOKEN)
- refresh_token = config_file.get(ATTR_REFRESH_TOKEN)
-
- # This will be called after authorizing Home-Assistant
- if None not in (access_token, refresh_token):
- pywink.set_wink_credentials(
- config_file.get(CONF_CLIENT_ID),
- config_file.get(CONF_CLIENT_SECRET),
- access_token=access_token,
- refresh_token=refresh_token,
- )
- # This is called to create the redirect so the user can Authorize
- # Home .
- else:
-
- redirect_uri = f"{get_url(hass)}{WINK_AUTH_CALLBACK_PATH}"
-
- wink_auth_start_url = pywink.get_authorization_url(
- config_file.get(CONF_CLIENT_ID), redirect_uri
- )
- hass.http.register_redirect(WINK_AUTH_START, wink_auth_start_url)
- hass.http.register_view(
- WinkAuthCallbackView(config, config_file, pywink.request_token)
- )
- _request_oauth_completion(hass, config)
- return True
-
- pywink.set_user_agent(USER_AGENT)
- sub_details = pywink.get_subscription_details()
- hass.data[DOMAIN]["pubnub"] = PubNubSubscriptionHandler(
- sub_details[0], origin=sub_details[1]
- )
-
- def _subscribe():
- hass.data[DOMAIN]["pubnub"].subscribe()
-
- # Call subscribe after the user sets up wink via the configurator
- # All other methods will complete setup before
- # EVENT_HOMEASSISTANT_START is called meaning they
- # will call subscribe via the method below. (start_subscription)
- if hass.data[DOMAIN]["configurator"]:
- _subscribe()
-
- def keep_alive_call(event_time):
- """Call the Wink API endpoints to keep PubNub working."""
- _LOGGER.info("Polling the Wink API to keep PubNub updates flowing")
- pywink.set_user_agent(str(int(time.time())))
- _temp_response = pywink.get_user()
- _LOGGER.debug(str(json.dumps(_temp_response)))
- time.sleep(1)
- pywink.set_user_agent(USER_AGENT)
- _temp_response = pywink.wink_api_fetch()
- _LOGGER.debug("%s", _temp_response)
- _temp_response = pywink.post_session()
- _LOGGER.debug("%s", _temp_response)
-
- # Call the Wink API every hour to keep PubNub updates flowing
- track_time_interval(hass, keep_alive_call, timedelta(minutes=60))
-
- def start_subscription(event):
- """Start the PubNub subscription."""
- _subscribe()
-
- hass.bus.listen(EVENT_HOMEASSISTANT_START, start_subscription)
-
- def stop_subscription(event):
- """Stop the PubNub subscription."""
- hass.data[DOMAIN]["pubnub"].unsubscribe()
- hass.data[DOMAIN]["pubnub"] = None
-
- hass.bus.listen(EVENT_HOMEASSISTANT_STOP, stop_subscription)
-
- def save_credentials(event):
- """Save currently set OAuth credentials."""
- if hass.data[DOMAIN]["oauth"].get("email") is None:
- config_path = hass.config.path(WINK_CONFIG_FILE)
- _config = pywink.get_current_oauth_credentials()
- save_json(config_path, _config)
-
- hass.bus.listen(EVENT_HOMEASSISTANT_STOP, save_credentials)
-
- # Save the users potentially updated oauth credentials at a regular
- # interval to prevent them from being expired after a HA reboot.
- track_time_interval(hass, save_credentials, timedelta(minutes=60))
-
- def force_update(call):
- """Force all devices to poll the Wink API."""
- _LOGGER.info("Refreshing Wink states from API")
- for entity_list in hass.data[DOMAIN]["entities"].values():
- # Throttle the calls to Wink API
- for entity in entity_list:
- time.sleep(1)
- entity.schedule_update_ha_state(True)
-
- hass.services.register(DOMAIN, SERVICE_REFRESH_STATES, force_update)
-
- def pull_new_devices(call):
- """Pull new devices added to users Wink account since startup."""
- _LOGGER.info("Getting new devices from Wink API")
- for _component in WINK_COMPONENTS:
- discovery.load_platform(hass, _component, DOMAIN, {}, config)
-
- hass.services.register(DOMAIN, SERVICE_ADD_NEW_DEVICES, pull_new_devices)
-
- def set_pairing_mode(call):
- """Put the hub in provided pairing mode."""
- hub_name = call.data.get("hub_name")
- pairing_mode = call.data.get("pairing_mode")
- kidde_code = call.data.get("kidde_radio_code")
- for hub in WINK_HUBS:
- if hub.name() == hub_name:
- hub.pair_new_device(pairing_mode, kidde_radio_code=kidde_code)
-
- def rename_device(call):
- """Set specified device's name."""
- # This should only be called on one device at a time.
- found_device = None
- entity_id = call.data.get("entity_id")[0]
- all_devices = []
- for list_of_devices in hass.data[DOMAIN]["entities"].values():
- all_devices += list_of_devices
- for device in all_devices:
- if device.entity_id == entity_id:
- found_device = device
- if found_device is not None:
- name = call.data.get("name")
- found_device.wink.set_name(name)
-
- hass.services.register(
- DOMAIN, SERVICE_RENAME_DEVICE, rename_device, schema=RENAME_DEVICE_SCHEMA
- )
-
- def delete_device(call):
- """Delete specified device."""
- # This should only be called on one device at a time.
- found_device = None
- entity_id = call.data.get("entity_id")[0]
- all_devices = []
- for list_of_devices in hass.data[DOMAIN]["entities"].values():
- all_devices += list_of_devices
- for device in all_devices:
- if device.entity_id == entity_id:
- found_device = device
- if found_device is not None:
- found_device.wink.remove_device()
-
- hass.services.register(
- DOMAIN, SERVICE_DELETE_DEVICE, delete_device, schema=DELETE_DEVICE_SCHEMA
- )
-
- hubs = pywink.get_hubs()
- for hub in hubs:
- if hub.device_manufacturer() == "wink":
- WINK_HUBS.append(hub)
-
- if WINK_HUBS:
- hass.services.register(
- DOMAIN,
- SERVICE_SET_PAIRING_MODE,
- set_pairing_mode,
- schema=SET_PAIRING_MODE_SCHEMA,
- )
-
- def nimbus_service_handle(service):
- """Handle nimbus services."""
- entity_id = service.data.get("entity_id")[0]
- _all_dials = []
- for sensor in hass.data[DOMAIN]["entities"]["sensor"]:
- if isinstance(sensor, WinkNimbusDialDevice):
- _all_dials.append(sensor)
- for _dial in _all_dials:
- if _dial.entity_id == entity_id:
- if service.service == SERVICE_SET_DIAL_CONFIG:
- _dial.set_configuration(**service.data)
- if service.service == SERVICE_SET_DIAL_STATE:
- _dial.wink.set_state(
- service.data.get("value"), service.data.get("labels")
- )
-
- def siren_service_handle(service):
- """Handle siren services."""
- entity_ids = service.data.get("entity_id")
- all_sirens = []
- for switch in hass.data[DOMAIN]["entities"]["switch"]:
- if isinstance(switch, WinkSirenDevice):
- all_sirens.append(switch)
- sirens_to_set = []
- if entity_ids is None:
- sirens_to_set = all_sirens
- else:
- for siren in all_sirens:
- if siren.entity_id in entity_ids:
- sirens_to_set.append(siren)
-
- for siren in sirens_to_set:
- _man = siren.wink.device_manufacturer()
- if (
- service.service != SERVICE_SET_AUTO_SHUTOFF
- and service.service != SERVICE_ENABLE_SIREN
- and _man not in ("dome", "wink")
- ):
- _LOGGER.error("Service only valid for Dome or Wink sirens")
- return
-
- if service.service == SERVICE_ENABLE_SIREN:
- siren.wink.set_state(service.data.get(ATTR_ENABLED))
- elif service.service == SERVICE_SET_AUTO_SHUTOFF:
- siren.wink.set_auto_shutoff(service.data.get(ATTR_AUTO_SHUTOFF))
- elif service.service == SERVICE_SET_CHIME_VOLUME:
- siren.wink.set_chime_volume(service.data.get(ATTR_VOLUME))
- elif service.service == SERVICE_SET_SIREN_VOLUME:
- siren.wink.set_siren_volume(service.data.get(ATTR_VOLUME))
- elif service.service == SERVICE_SET_SIREN_TONE:
- siren.wink.set_siren_sound(service.data.get(ATTR_TONE))
- elif service.service == SERVICE_ENABLE_CHIME:
- siren.wink.set_chime(service.data.get(ATTR_TONE))
- elif service.service == SERVICE_SIREN_STROBE_ENABLED:
- siren.wink.set_siren_strobe_enabled(service.data.get(ATTR_ENABLED))
- elif service.service == SERVICE_CHIME_STROBE_ENABLED:
- siren.wink.set_chime_strobe_enabled(service.data.get(ATTR_ENABLED))
-
- # Load components for the devices in Wink that we support
- for wink_component in WINK_COMPONENTS:
- hass.data[DOMAIN]["entities"][wink_component] = []
- discovery.load_platform(hass, wink_component, DOMAIN, {}, config)
-
- component = EntityComponent(_LOGGER, DOMAIN, hass)
-
- sirens = []
- has_dome_or_wink_siren = False
- for siren in pywink.get_sirens():
- _man = siren.device_manufacturer()
- if _man in ("dome", "wink"):
- has_dome_or_wink_siren = True
- _id = siren.object_id() + siren.name()
- if _id not in hass.data[DOMAIN]["unique_ids"]:
- sirens.append(WinkSirenDevice(siren, hass))
-
- if sirens:
-
- hass.services.register(
- DOMAIN,
- SERVICE_SET_AUTO_SHUTOFF,
- siren_service_handle,
- schema=SET_AUTO_SHUTOFF_SCHEMA,
- )
-
- hass.services.register(
- DOMAIN,
- SERVICE_ENABLE_SIREN,
- siren_service_handle,
- schema=ENABLED_SIREN_SCHEMA,
- )
-
- if has_dome_or_wink_siren:
-
- hass.services.register(
- DOMAIN,
- SERVICE_SET_SIREN_TONE,
- siren_service_handle,
- schema=SET_SIREN_TONE_SCHEMA,
- )
-
- hass.services.register(
- DOMAIN,
- SERVICE_ENABLE_CHIME,
- siren_service_handle,
- schema=SET_CHIME_MODE_SCHEMA,
- )
-
- hass.services.register(
- DOMAIN,
- SERVICE_SET_SIREN_VOLUME,
- siren_service_handle,
- schema=SET_VOLUME_SCHEMA,
- )
-
- hass.services.register(
- DOMAIN,
- SERVICE_SET_CHIME_VOLUME,
- siren_service_handle,
- schema=SET_VOLUME_SCHEMA,
- )
-
- hass.services.register(
- DOMAIN,
- SERVICE_SIREN_STROBE_ENABLED,
- siren_service_handle,
- schema=SET_STROBE_ENABLED_SCHEMA,
- )
-
- hass.services.register(
- DOMAIN,
- SERVICE_CHIME_STROBE_ENABLED,
- siren_service_handle,
- schema=SET_STROBE_ENABLED_SCHEMA,
- )
-
- component.add_entities(sirens)
-
- nimbi = []
- dials = {}
- all_nimbi = pywink.get_cloud_clocks()
- all_dials = []
- for nimbus in all_nimbi:
- if nimbus.object_type() == "cloud_clock":
- nimbi.append(nimbus)
- dials[nimbus.object_id()] = []
- for nimbus in all_nimbi:
- if nimbus.object_type() == "dial":
- dials[nimbus.parent_id()].append(nimbus)
-
- for nimbus in nimbi:
- for dial in dials[nimbus.object_id()]:
- all_dials.append(WinkNimbusDialDevice(nimbus, dial, hass))
-
- if nimbi:
- hass.services.register(
- DOMAIN,
- SERVICE_SET_DIAL_CONFIG,
- nimbus_service_handle,
- schema=DIAL_CONFIG_SCHEMA,
- )
-
- hass.services.register(
- DOMAIN,
- SERVICE_SET_DIAL_STATE,
- nimbus_service_handle,
- schema=DIAL_STATE_SCHEMA,
- )
-
- component.add_entities(all_dials)
-
- return True
-
-
-class WinkAuthCallbackView(HomeAssistantView):
- """Handle OAuth finish callback requests."""
-
- url = "/auth/wink/callback"
- name = "auth:wink:callback"
- requires_auth = False
-
- def __init__(self, config, config_file, request_token):
- """Initialize the OAuth callback view."""
- self.config = config
- self.config_file = config_file
- self.request_token = request_token
-
- @callback
- def get(self, request):
- """Finish OAuth callback request."""
- hass = request.app["hass"]
- data = request.query
-
- response_message = """Wink has been successfully authorized!
- You can close this window now! For the best results you should reboot
- Home Assistant"""
- html_response = """
Wink Auth
- {}
"""
-
- if data.get("code") is not None:
- response = self.request_token(
- data.get("code"), self.config_file[CONF_CLIENT_SECRET]
- )
-
- config_contents = {
- ATTR_ACCESS_TOKEN: response["access_token"],
- ATTR_REFRESH_TOKEN: response["refresh_token"],
- CONF_CLIENT_ID: self.config_file[CONF_CLIENT_ID],
- CONF_CLIENT_SECRET: self.config_file[CONF_CLIENT_SECRET],
- }
- save_json(hass.config.path(WINK_CONFIG_FILE), config_contents)
-
- hass.async_add_job(setup, hass, self.config)
-
- return Response(
- text=html_response.format(response_message), content_type="text/html"
- )
-
- error_msg = "No code returned from Wink API"
- _LOGGER.error(error_msg)
- return Response(text=html_response.format(error_msg), content_type="text/html")
-
-
-class WinkDevice(Entity):
- """Representation a base Wink device."""
-
- def __init__(self, wink, hass):
- """Initialize the Wink device."""
- self.hass = hass
- self.wink = wink
- hass.data[DOMAIN]["pubnub"].add_subscription(
- self.wink.pubnub_channel, self._pubnub_update
- )
- hass.data[DOMAIN]["unique_ids"].append(self.wink.object_id() + self.wink.name())
-
- def _pubnub_update(self, message):
- _LOGGER.debug(message)
- try:
- if message is None:
- _LOGGER.error(
- "Error on pubnub update for %s polling API for current state",
- self.name,
- )
- self.schedule_update_ha_state(True)
- else:
- self.wink.pubnub_update(message)
- self.schedule_update_ha_state()
- except (ValueError, KeyError, AttributeError):
- _LOGGER.error(
- "Error in pubnub JSON for %s polling API for current state", self.name
- )
- self.schedule_update_ha_state(True)
-
- @property
- def name(self):
- """Return the name of the device."""
- return self.wink.name()
-
- @property
- def unique_id(self):
- """Return the unique id of the Wink device."""
- if hasattr(self.wink, "capability") and self.wink.capability() is not None:
- return f"{self.wink.object_id()}_{self.wink.capability()}"
- return self.wink.object_id()
-
- @property
- def available(self):
- """Return true if connection == True."""
- return self.wink.available()
-
- def update(self):
- """Update state of the device."""
- self.wink.update_state()
-
- @property
- def should_poll(self):
- """Only poll if we are not subscribed to pubnub."""
- return self.wink.pubnub_channel is None
-
- @property
- def extra_state_attributes(self):
- """Return the state attributes."""
- attributes = {}
- battery = self._battery_level
- if battery:
- attributes[ATTR_BATTERY_LEVEL] = battery
- man_dev_model = self._manufacturer_device_model
- if man_dev_model:
- attributes["manufacturer_device_model"] = man_dev_model
- man_dev_id = self._manufacturer_device_id
- if man_dev_id:
- attributes["manufacturer_device_id"] = man_dev_id
- dev_man = self._device_manufacturer
- if dev_man:
- attributes["device_manufacturer"] = dev_man
- model_name = self._model_name
- if model_name:
- attributes["model_name"] = model_name
- tamper = self._tamper
- if tamper is not None:
- attributes["tamper_detected"] = tamper
- return attributes
-
- @property
- def _battery_level(self):
- """Return the battery level."""
- if self.wink.battery_level() is not None:
- return self.wink.battery_level() * 100
-
- @property
- def _manufacturer_device_model(self):
- """Return the manufacturer device model."""
- return self.wink.manufacturer_device_model()
-
- @property
- def _manufacturer_device_id(self):
- """Return the manufacturer device id."""
- return self.wink.manufacturer_device_id()
-
- @property
- def _device_manufacturer(self):
- """Return the device manufacturer."""
- return self.wink.device_manufacturer()
-
- @property
- def _model_name(self):
- """Return the model name."""
- return self.wink.model_name()
-
- @property
- def _tamper(self):
- """Return the devices tamper status."""
- if hasattr(self.wink, "tamper_detected"):
- return self.wink.tamper_detected()
- return None
-
-
-class WinkSirenDevice(WinkDevice):
- """Representation of a Wink siren device."""
-
- async def async_added_to_hass(self):
- """Call when entity is added to hass."""
- self.hass.data[DOMAIN]["entities"]["switch"].append(self)
-
- @property
- def state(self):
- """Return sirens state."""
- if self.wink.state():
- return STATE_ON
- return STATE_OFF
-
- @property
- def icon(self):
- """Return the icon to use in the frontend, if any."""
- return "mdi:bell-ring"
-
- @property
- def extra_state_attributes(self):
- """Return the device state attributes."""
- attributes = super().extra_state_attributes
-
- auto_shutoff = self.wink.auto_shutoff()
- if auto_shutoff is not None:
- attributes["auto_shutoff"] = auto_shutoff
-
- siren_volume = self.wink.siren_volume()
- if siren_volume is not None:
- attributes["siren_volume"] = siren_volume
-
- chime_volume = self.wink.chime_volume()
- if chime_volume is not None:
- attributes["chime_volume"] = chime_volume
-
- strobe_enabled = self.wink.strobe_enabled()
- if strobe_enabled is not None:
- attributes["siren_strobe_enabled"] = strobe_enabled
-
- chime_strobe_enabled = self.wink.chime_strobe_enabled()
- if chime_strobe_enabled is not None:
- attributes["chime_strobe_enabled"] = chime_strobe_enabled
-
- siren_sound = self.wink.siren_sound()
- if siren_sound is not None:
- attributes["siren_sound"] = siren_sound
-
- chime_mode = self.wink.chime_mode()
- if chime_mode is not None:
- attributes["chime_mode"] = chime_mode
-
- return attributes
-
-
-class WinkNimbusDialDevice(WinkDevice):
- """Representation of the Quirky Nimbus device."""
-
- def __init__(self, nimbus, dial, hass):
- """Initialize the Nimbus dial."""
- super().__init__(dial, hass)
- self.parent = nimbus
-
- async def async_added_to_hass(self):
- """Call when entity is added to hass."""
- self.hass.data[DOMAIN]["entities"]["sensor"].append(self)
-
- @property
- def state(self):
- """Return dials current value."""
- return self.wink.state()
-
- @property
- def name(self):
- """Return the name of the device."""
- return f"{self.parent.name()} dial {self.wink.index() + 1}"
-
- @property
- def extra_state_attributes(self):
- """Return the device state attributes."""
- attributes = super().extra_state_attributes
- dial_attributes = self.dial_attributes()
-
- return {**attributes, **dial_attributes}
-
- def dial_attributes(self):
- """Return the dial only attributes."""
- return {
- "labels": self.wink.labels(),
- "position": self.wink.position(),
- "rotation": self.wink.rotation(),
- "max_value": self.wink.max_value(),
- "min_value": self.wink.min_value(),
- "num_ticks": self.wink.ticks(),
- "scale_type": self.wink.scale(),
- "max_position": self.wink.max_position(),
- "min_position": self.wink.min_position(),
- }
-
- def set_configuration(self, **kwargs):
- """
- Set the dial config.
-
- Anything not sent will default to current setting.
- """
- attributes = {**self.dial_attributes(), **kwargs}
-
- min_value = attributes["min_value"]
- max_value = attributes["max_value"]
- rotation = attributes["rotation"]
- ticks = attributes["num_ticks"]
- scale = attributes["scale_type"]
- min_position = attributes["min_position"]
- max_position = attributes["max_position"]
-
- self.wink.set_configuration(
- min_value,
- max_value,
- rotation,
- scale=scale,
- ticks=ticks,
- min_position=min_position,
- max_position=max_position,
- )
diff --git a/homeassistant/components/wink/alarm_control_panel.py b/homeassistant/components/wink/alarm_control_panel.py
deleted file mode 100644
index 2f5ac83c6f5..00000000000
--- a/homeassistant/components/wink/alarm_control_panel.py
+++ /dev/null
@@ -1,75 +0,0 @@
-"""Support Wink alarm control panels."""
-import pywink
-
-import homeassistant.components.alarm_control_panel as alarm
-from homeassistant.components.alarm_control_panel.const import (
- SUPPORT_ALARM_ARM_AWAY,
- SUPPORT_ALARM_ARM_HOME,
-)
-from homeassistant.const import (
- STATE_ALARM_ARMED_AWAY,
- STATE_ALARM_ARMED_HOME,
- STATE_ALARM_DISARMED,
-)
-
-from . import DOMAIN, WinkDevice
-
-STATE_ALARM_PRIVACY = "Private"
-
-
-def setup_platform(hass, config, add_entities, discovery_info=None):
- """Set up the Wink platform."""
-
- for camera in pywink.get_cameras():
- # get_cameras returns multiple device types.
- # Only add those that aren't sensors.
- try:
- camera.capability()
- except AttributeError:
- _id = camera.object_id() + camera.name()
- if _id not in hass.data[DOMAIN]["unique_ids"]:
- add_entities([WinkCameraDevice(camera, hass)])
-
-
-class WinkCameraDevice(WinkDevice, alarm.AlarmControlPanelEntity):
- """Representation a Wink camera alarm."""
-
- async def async_added_to_hass(self):
- """Call when entity is added to hass."""
- self.hass.data[DOMAIN]["entities"]["alarm_control_panel"].append(self)
-
- @property
- def state(self):
- """Return the state of the device."""
- wink_state = self.wink.state()
- if wink_state == "away":
- state = STATE_ALARM_ARMED_AWAY
- elif wink_state == "home":
- state = STATE_ALARM_DISARMED
- elif wink_state == "night":
- state = STATE_ALARM_ARMED_HOME
- else:
- state = None
- return state
-
- @property
- def supported_features(self) -> int:
- """Return the list of supported features."""
- return SUPPORT_ALARM_ARM_HOME | SUPPORT_ALARM_ARM_AWAY
-
- def alarm_disarm(self, code=None):
- """Send disarm command."""
- self.wink.set_mode("home")
-
- def alarm_arm_home(self, code=None):
- """Send arm home command."""
- self.wink.set_mode("night")
-
- def alarm_arm_away(self, code=None):
- """Send arm away command."""
- self.wink.set_mode("away")
-
- @property
- def extra_state_attributes(self):
- """Return the state attributes."""
- return {"private": self.wink.private()}
diff --git a/homeassistant/components/wink/binary_sensor.py b/homeassistant/components/wink/binary_sensor.py
deleted file mode 100644
index 6a5977c1dc2..00000000000
--- a/homeassistant/components/wink/binary_sensor.py
+++ /dev/null
@@ -1,197 +0,0 @@
-"""Support for Wink binary sensors."""
-import logging
-
-import pywink
-
-from homeassistant.components.binary_sensor import (
- DEVICE_CLASS_MOISTURE,
- DEVICE_CLASS_MOTION,
- DEVICE_CLASS_OCCUPANCY,
- DEVICE_CLASS_OPENING,
- DEVICE_CLASS_SMOKE,
- DEVICE_CLASS_SOUND,
- DEVICE_CLASS_VIBRATION,
- BinarySensorEntity,
-)
-
-from . import DOMAIN, WinkDevice
-
-_LOGGER = logging.getLogger(__name__)
-
-# These are the available sensors mapped to binary_sensor class
-SENSOR_TYPES = {
- "brightness": "light",
- "capturing_audio": DEVICE_CLASS_SOUND,
- "capturing_video": None,
- "co_detected": "gas",
- "liquid_detected": DEVICE_CLASS_MOISTURE,
- "loudness": DEVICE_CLASS_SOUND,
- "motion": DEVICE_CLASS_MOTION,
- "noise": DEVICE_CLASS_SOUND,
- "opened": DEVICE_CLASS_OPENING,
- "presence": DEVICE_CLASS_OCCUPANCY,
- "smoke_detected": DEVICE_CLASS_SMOKE,
- "vibration": DEVICE_CLASS_VIBRATION,
-}
-
-
-def setup_platform(hass, config, add_entities, discovery_info=None):
- """Set up the Wink binary sensor platform."""
-
- for sensor in pywink.get_sensors():
- _id = sensor.object_id() + sensor.name()
- if (
- _id not in hass.data[DOMAIN]["unique_ids"]
- and sensor.capability() in SENSOR_TYPES
- ):
- add_entities([WinkBinarySensorEntity(sensor, hass)])
-
- for key in pywink.get_keys():
- _id = key.object_id() + key.name()
- if _id not in hass.data[DOMAIN]["unique_ids"]:
- add_entities([WinkBinarySensorEntity(key, hass)])
-
- for sensor in pywink.get_smoke_and_co_detectors():
- _id = sensor.object_id() + sensor.name()
- if _id not in hass.data[DOMAIN]["unique_ids"]:
- add_entities([WinkSmokeDetector(sensor, hass)])
-
- for hub in pywink.get_hubs():
- _id = hub.object_id() + hub.name()
- if _id not in hass.data[DOMAIN]["unique_ids"]:
- add_entities([WinkHub(hub, hass)])
-
- for remote in pywink.get_remotes():
- _id = remote.object_id() + remote.name()
- if _id not in hass.data[DOMAIN]["unique_ids"]:
- add_entities([WinkRemote(remote, hass)])
-
- for button in pywink.get_buttons():
- _id = button.object_id() + button.name()
- if _id not in hass.data[DOMAIN]["unique_ids"]:
- add_entities([WinkButton(button, hass)])
-
- for gang in pywink.get_gangs():
- _id = gang.object_id() + gang.name()
- if _id not in hass.data[DOMAIN]["unique_ids"]:
- add_entities([WinkGang(gang, hass)])
-
- for door_bell_sensor in pywink.get_door_bells():
- _id = door_bell_sensor.object_id() + door_bell_sensor.name()
- if _id not in hass.data[DOMAIN]["unique_ids"]:
- add_entities([WinkBinarySensorEntity(door_bell_sensor, hass)])
-
- for camera_sensor in pywink.get_cameras():
- _id = camera_sensor.object_id() + camera_sensor.name()
- if _id not in hass.data[DOMAIN]["unique_ids"]:
- try:
- if camera_sensor.capability() in SENSOR_TYPES:
- add_entities([WinkBinarySensorEntity(camera_sensor, hass)])
- except AttributeError:
- _LOGGER.info("Device isn't a sensor, skipping")
-
-
-class WinkBinarySensorEntity(WinkDevice, BinarySensorEntity):
- """Representation of a Wink binary sensor."""
-
- def __init__(self, wink, hass):
- """Initialize the Wink binary sensor."""
- super().__init__(wink, hass)
- if hasattr(self.wink, "unit"):
- self._unit_of_measurement = self.wink.unit()
- else:
- self._unit_of_measurement = None
- if hasattr(self.wink, "capability"):
- self.capability = self.wink.capability()
- else:
- self.capability = None
-
- async def async_added_to_hass(self):
- """Call when entity is added to hass."""
- self.hass.data[DOMAIN]["entities"]["binary_sensor"].append(self)
-
- @property
- def is_on(self):
- """Return true if the binary sensor is on."""
- return self.wink.state()
-
- @property
- def device_class(self):
- """Return the class of this sensor, from DEVICE_CLASSES."""
- return SENSOR_TYPES.get(self.capability)
-
- @property
- def extra_state_attributes(self):
- """Return the device state attributes."""
- return super().extra_state_attributes
-
-
-class WinkSmokeDetector(WinkBinarySensorEntity):
- """Representation of a Wink Smoke detector."""
-
- @property
- def extra_state_attributes(self):
- """Return the device state attributes."""
- _attributes = super().extra_state_attributes
- _attributes["test_activated"] = self.wink.test_activated()
- return _attributes
-
-
-class WinkHub(WinkBinarySensorEntity):
- """Representation of a Wink Hub."""
-
- @property
- def extra_state_attributes(self):
- """Return the device state attributes."""
- _attributes = super().extra_state_attributes
- _attributes["update_needed"] = self.wink.update_needed()
- _attributes["firmware_version"] = self.wink.firmware_version()
- _attributes["pairing_mode"] = self.wink.pairing_mode()
- _kidde_code = self.wink.kidde_radio_code()
- if _kidde_code is not None:
- # The service call to set the Kidde code
- # takes a string of 1s and 0s so it makes
- # sense to display it to the user that way
- _formatted_kidde_code = f"{_kidde_code:b}".zfill(8)
- _attributes["kidde_radio_code"] = _formatted_kidde_code
- return _attributes
-
-
-class WinkRemote(WinkBinarySensorEntity):
- """Representation of a Wink Lutron Connected bulb remote."""
-
- @property
- def extra_state_attributes(self):
- """Return the state attributes."""
- _attributes = super().extra_state_attributes
- _attributes["button_on_pressed"] = self.wink.button_on_pressed()
- _attributes["button_off_pressed"] = self.wink.button_off_pressed()
- _attributes["button_up_pressed"] = self.wink.button_up_pressed()
- _attributes["button_down_pressed"] = self.wink.button_down_pressed()
- return _attributes
-
- @property
- def device_class(self):
- """Return the class of this sensor, from DEVICE_CLASSES."""
- return None
-
-
-class WinkButton(WinkBinarySensorEntity):
- """Representation of a Wink Relay button."""
-
- @property
- def extra_state_attributes(self):
- """Return the device state attributes."""
- _attributes = super().extra_state_attributes
- _attributes["pressed"] = self.wink.pressed()
- _attributes["long_pressed"] = self.wink.long_pressed()
- return _attributes
-
-
-class WinkGang(WinkBinarySensorEntity):
- """Representation of a Wink Relay gang."""
-
- @property
- def is_on(self):
- """Return true if the gang is connected."""
- return self.wink.state()
diff --git a/homeassistant/components/wink/climate.py b/homeassistant/components/wink/climate.py
deleted file mode 100644
index 7836d71614f..00000000000
--- a/homeassistant/components/wink/climate.py
+++ /dev/null
@@ -1,520 +0,0 @@
-"""Support for Wink thermostats and Air Conditioners."""
-import logging
-
-import pywink
-
-from homeassistant.components.climate import ClimateEntity
-from homeassistant.components.climate.const import (
- ATTR_TARGET_TEMP_HIGH,
- ATTR_TARGET_TEMP_LOW,
- CURRENT_HVAC_COOL,
- CURRENT_HVAC_HEAT,
- CURRENT_HVAC_IDLE,
- CURRENT_HVAC_OFF,
- FAN_AUTO,
- FAN_HIGH,
- FAN_LOW,
- FAN_MEDIUM,
- FAN_ON,
- HVAC_MODE_AUTO,
- HVAC_MODE_COOL,
- HVAC_MODE_FAN_ONLY,
- HVAC_MODE_HEAT,
- HVAC_MODE_OFF,
- PRESET_AWAY,
- PRESET_ECO,
- PRESET_NONE,
- SUPPORT_AUX_HEAT,
- SUPPORT_FAN_MODE,
- SUPPORT_PRESET_MODE,
- SUPPORT_TARGET_TEMPERATURE,
- SUPPORT_TARGET_TEMPERATURE_RANGE,
-)
-from homeassistant.const import ATTR_TEMPERATURE, PRECISION_TENTHS, TEMP_CELSIUS
-from homeassistant.helpers.temperature import display_temp as show_temp
-
-from . import DOMAIN, WinkDevice
-
-_LOGGER = logging.getLogger(__name__)
-
-ATTR_ECO_TARGET = "eco_target"
-ATTR_EXTERNAL_TEMPERATURE = "external_temperature"
-ATTR_OCCUPIED = "occupied"
-ATTR_SCHEDULE_ENABLED = "schedule_enabled"
-ATTR_SMART_TEMPERATURE = "smart_temperature"
-ATTR_TOTAL_CONSUMPTION = "total_consumption"
-
-HA_HVAC_TO_WINK = {
- HVAC_MODE_AUTO: "auto",
- HVAC_MODE_COOL: "cool_only",
- HVAC_MODE_FAN_ONLY: "fan_only",
- HVAC_MODE_HEAT: "heat_only",
- HVAC_MODE_OFF: "off",
-}
-
-WINK_HVAC_TO_HA = {value: key for key, value in HA_HVAC_TO_WINK.items()}
-
-SUPPORT_FLAGS_THERMOSTAT = (
- SUPPORT_TARGET_TEMPERATURE
- | SUPPORT_TARGET_TEMPERATURE_RANGE
- | SUPPORT_FAN_MODE
- | SUPPORT_AUX_HEAT
-)
-SUPPORT_FAN_THERMOSTAT = [FAN_AUTO, FAN_ON]
-SUPPORT_PRESET_THERMOSTAT = [PRESET_AWAY, PRESET_ECO]
-
-SUPPORT_FLAGS_AC = SUPPORT_TARGET_TEMPERATURE | SUPPORT_FAN_MODE | SUPPORT_PRESET_MODE
-SUPPORT_FAN_AC = [FAN_HIGH, FAN_LOW, FAN_MEDIUM]
-SUPPORT_PRESET_AC = [PRESET_NONE, PRESET_ECO]
-
-
-def setup_platform(hass, config, add_entities, discovery_info=None):
- """Set up the Wink climate devices."""
- for climate in pywink.get_thermostats():
- _id = climate.object_id() + climate.name()
- if _id not in hass.data[DOMAIN]["unique_ids"]:
- add_entities([WinkThermostat(climate, hass)])
- for climate in pywink.get_air_conditioners():
- _id = climate.object_id() + climate.name()
- if _id not in hass.data[DOMAIN]["unique_ids"]:
- add_entities([WinkAC(climate, hass)])
-
-
-class WinkThermostat(WinkDevice, ClimateEntity):
- """Representation of a Wink thermostat."""
-
- @property
- def supported_features(self):
- """Return the list of supported features."""
- return SUPPORT_FLAGS_THERMOSTAT
-
- async def async_added_to_hass(self):
- """Call when entity is added to hass."""
- self.hass.data[DOMAIN]["entities"]["climate"].append(self)
-
- @property
- def temperature_unit(self):
- """Return the unit of measurement."""
- # The Wink API always returns temp in Celsius
- return TEMP_CELSIUS
-
- @property
- def extra_state_attributes(self):
- """Return the optional device state attributes."""
- data = {}
- if self.external_temperature is not None:
- data[ATTR_EXTERNAL_TEMPERATURE] = show_temp(
- self.hass,
- self.external_temperature,
- self.temperature_unit,
- PRECISION_TENTHS,
- )
-
- if self.smart_temperature:
- data[ATTR_SMART_TEMPERATURE] = self.smart_temperature
-
- if self.occupied is not None:
- data[ATTR_OCCUPIED] = self.occupied
-
- if self.eco_target is not None:
- data[ATTR_ECO_TARGET] = self.eco_target
-
- return data
-
- @property
- def current_temperature(self):
- """Return the current temperature."""
- return self.wink.current_temperature()
-
- @property
- def current_humidity(self):
- """Return the current humidity."""
- if self.wink.current_humidity() is not None:
- # The API states humidity will be a float 0-1
- # the only example API response with humidity listed show an int
- # This will address both possibilities
- if self.wink.current_humidity() < 1:
- return self.wink.current_humidity() * 100
- return self.wink.current_humidity()
- return None
-
- @property
- def external_temperature(self):
- """Return the current external temperature."""
- return self.wink.current_external_temperature()
-
- @property
- def smart_temperature(self):
- """Return the current average temp of all remote sensor."""
- return self.wink.current_smart_temperature()
-
- @property
- def eco_target(self):
- """Return status of eco target (Is the thermostat in eco mode)."""
- return self.wink.eco_target()
-
- @property
- def occupied(self):
- """Return status of if the thermostat has detected occupancy."""
- return self.wink.occupied()
-
- @property
- def preset_mode(self):
- """Return the current preset mode, e.g., home, away, temp."""
- mode = self.wink.current_hvac_mode()
- if mode == "eco":
- return PRESET_ECO
- if self.wink.away():
- return PRESET_AWAY
- return None
-
- @property
- def preset_modes(self):
- """Return a list of available preset modes."""
- return SUPPORT_PRESET_THERMOSTAT
-
- @property
- def target_humidity(self):
- """Return the humidity we try to reach."""
- target_hum = None
- if self.wink.current_humidifier_mode() == "on":
- if self.wink.current_humidifier_set_point() is not None:
- target_hum = self.wink.current_humidifier_set_point() * 100
- elif self.wink.current_dehumidifier_mode() == "on":
- if self.wink.current_dehumidifier_set_point() is not None:
- target_hum = self.wink.current_dehumidifier_set_point() * 100
- else:
- target_hum = None
- return target_hum
-
- @property
- def target_temperature(self):
- """Return the temperature we try to reach."""
- if self.hvac_mode != HVAC_MODE_AUTO and not self.wink.away():
- if self.hvac_mode == HVAC_MODE_COOL:
- return self.wink.current_max_set_point()
- if self.hvac_mode == HVAC_MODE_HEAT:
- return self.wink.current_min_set_point()
- return None
-
- @property
- def target_temperature_low(self):
- """Return the lower bound temperature we try to reach."""
- if self.hvac_mode == HVAC_MODE_AUTO:
- return self.wink.current_min_set_point()
- return None
-
- @property
- def target_temperature_high(self):
- """Return the higher bound temperature we try to reach."""
- if self.hvac_mode == HVAC_MODE_AUTO:
- return self.wink.current_max_set_point()
- return None
-
- @property
- def is_aux_heat(self):
- """Return true if aux heater."""
- if "aux" not in self.wink.hvac_modes():
- return None
- if self.wink.current_hvac_mode() == "aux":
- return True
- return False
-
- @property
- def hvac_mode(self) -> str:
- """Return hvac operation ie. heat, cool mode.
-
- Need to be one of HVAC_MODE_*.
- """
- if not self.wink.is_on():
- return HVAC_MODE_OFF
-
- wink_mode = self.wink.current_hvac_mode()
- if wink_mode == "aux":
- return HVAC_MODE_HEAT
- if wink_mode == "eco":
- return HVAC_MODE_AUTO
- return WINK_HVAC_TO_HA.get(wink_mode, "")
-
- @property
- def hvac_modes(self):
- """Return the list of available hvac operation modes.
-
- Need to be a subset of HVAC_MODES.
- """
- hvac_list = [HVAC_MODE_OFF]
-
- modes = self.wink.hvac_modes()
- for mode in modes:
- if mode in ("eco", "aux"):
- continue
- try:
- ha_mode = WINK_HVAC_TO_HA[mode]
- hvac_list.append(ha_mode)
- except KeyError:
- _LOGGER.error(
- "Invalid operation mode mapping. %s doesn't map. "
- "Please report this",
- mode,
- )
- return hvac_list
-
- @property
- def hvac_action(self):
- """Return the current running hvac operation if supported.
-
- Need to be one of CURRENT_HVAC_*.
- """
- if not self.wink.is_on():
- return CURRENT_HVAC_OFF
- if self.wink.cool_on():
- return CURRENT_HVAC_COOL
- if self.wink.heat_on():
- return CURRENT_HVAC_HEAT
- return CURRENT_HVAC_IDLE
-
- def set_temperature(self, **kwargs):
- """Set new target temperature."""
- target_temp = kwargs.get(ATTR_TEMPERATURE)
- target_temp_low = kwargs.get(ATTR_TARGET_TEMP_LOW)
- target_temp_high = kwargs.get(ATTR_TARGET_TEMP_HIGH)
- if target_temp is not None:
- if self.hvac_mode == HVAC_MODE_COOL:
- target_temp_high = target_temp
- if self.hvac_mode == HVAC_MODE_HEAT:
- target_temp_low = target_temp
- self.wink.set_temperature(target_temp_low, target_temp_high)
-
- def set_hvac_mode(self, hvac_mode):
- """Set new target hvac mode."""
- hvac_mode_to_set = HA_HVAC_TO_WINK.get(hvac_mode)
- self.wink.set_operation_mode(hvac_mode_to_set)
-
- def set_preset_mode(self, preset_mode):
- """Set new preset mode."""
- # Away
- if preset_mode != PRESET_AWAY and self.wink.away():
- self.wink.set_away_mode(False)
- elif preset_mode == PRESET_AWAY:
- self.wink.set_away_mode()
-
- if preset_mode == PRESET_ECO:
- self.wink.set_operation_mode("eco")
-
- @property
- def fan_mode(self):
- """Return whether the fan is on."""
- if self.wink.current_fan_mode() == "on":
- return FAN_ON
- if self.wink.current_fan_mode() == "auto":
- return FAN_AUTO
- # No Fan available so disable slider
- return None
-
- @property
- def fan_modes(self):
- """List of available fan modes."""
- if self.wink.has_fan():
- return SUPPORT_FAN_THERMOSTAT
- return None
-
- def set_fan_mode(self, fan_mode):
- """Turn fan on/off."""
- self.wink.set_fan_mode(fan_mode.lower())
-
- def turn_aux_heat_on(self):
- """Turn auxiliary heater on."""
- self.wink.set_operation_mode("aux")
-
- def turn_aux_heat_off(self):
- """Turn auxiliary heater off."""
- self.wink.set_operation_mode("heat_only")
-
- @property
- def min_temp(self):
- """Return the minimum temperature."""
- minimum = 7 # Default minimum
- min_min = self.wink.min_min_set_point()
- min_max = self.wink.min_max_set_point()
- if self.hvac_mode == HVAC_MODE_HEAT:
- if min_min:
- return_value = min_min
- else:
- return_value = minimum
- elif self.hvac_mode == HVAC_MODE_COOL:
- if min_max:
- return_value = min_max
- else:
- return_value = minimum
- elif self.hvac_mode == HVAC_MODE_AUTO:
- if min_min and min_max:
- return_value = min(min_min, min_max)
- else:
- return_value = minimum
- else:
- return_value = minimum
- return return_value
-
- @property
- def max_temp(self):
- """Return the maximum temperature."""
- maximum = 35 # Default maximum
- max_min = self.wink.max_min_set_point()
- max_max = self.wink.max_max_set_point()
- if self.hvac_mode == HVAC_MODE_HEAT:
- if max_min:
- return_value = max_min
- else:
- return_value = maximum
- elif self.hvac_mode == HVAC_MODE_COOL:
- if max_max:
- return_value = max_max
- else:
- return_value = maximum
- elif self.hvac_mode == HVAC_MODE_AUTO:
- if max_min and max_max:
- return_value = min(max_min, max_max)
- else:
- return_value = maximum
- else:
- return_value = maximum
- return return_value
-
-
-class WinkAC(WinkDevice, ClimateEntity):
- """Representation of a Wink air conditioner."""
-
- @property
- def supported_features(self):
- """Return the list of supported features."""
- return SUPPORT_FLAGS_AC
-
- @property
- def temperature_unit(self):
- """Return the unit of measurement."""
- # The Wink API always returns temp in Celsius
- return TEMP_CELSIUS
-
- @property
- def extra_state_attributes(self):
- """Return the optional device state attributes."""
- data = {}
- data[ATTR_TOTAL_CONSUMPTION] = self.wink.total_consumption()
- data[ATTR_SCHEDULE_ENABLED] = self.wink.schedule_enabled()
-
- return data
-
- @property
- def current_temperature(self):
- """Return the current temperature."""
- return self.wink.current_temperature()
-
- @property
- def preset_mode(self):
- """Return the current preset mode, e.g., home, away, temp."""
- if not self.wink.is_on():
- return PRESET_NONE
-
- mode = self.wink.current_mode()
- if mode == "auto_eco":
- return PRESET_ECO
- return PRESET_NONE
-
- @property
- def preset_modes(self):
- """Return a list of available preset modes."""
- return SUPPORT_PRESET_AC
-
- @property
- def hvac_mode(self) -> str:
- """Return hvac operation ie. heat, cool mode.
-
- Need to be one of HVAC_MODE_*.
- """
- if not self.wink.is_on():
- return HVAC_MODE_OFF
-
- wink_mode = self.wink.current_mode()
- if wink_mode == "auto_eco":
- return HVAC_MODE_COOL
- return WINK_HVAC_TO_HA.get(wink_mode, "")
-
- @property
- def hvac_modes(self):
- """Return the list of available hvac operation modes.
-
- Need to be a subset of HVAC_MODES.
- """
- hvac_list = [HVAC_MODE_OFF]
-
- modes = self.wink.modes()
- for mode in modes:
- if mode == "auto_eco":
- continue
- try:
- ha_mode = WINK_HVAC_TO_HA[mode]
- hvac_list.append(ha_mode)
- except KeyError:
- _LOGGER.error(
- "Invalid operation mode mapping. %s doesn't map. "
- "Please report this",
- mode,
- )
- return hvac_list
-
- def set_temperature(self, **kwargs):
- """Set new target temperature."""
- target_temp = kwargs.get(ATTR_TEMPERATURE)
- self.wink.set_temperature(target_temp)
-
- def set_hvac_mode(self, hvac_mode):
- """Set new target hvac mode."""
- hvac_mode_to_set = HA_HVAC_TO_WINK.get(hvac_mode)
- self.wink.set_operation_mode(hvac_mode_to_set)
-
- def set_preset_mode(self, preset_mode):
- """Set new preset mode."""
- if preset_mode == PRESET_ECO:
- self.wink.set_operation_mode("auto_eco")
- elif self.hvac_mode == HVAC_MODE_COOL and preset_mode == PRESET_NONE:
- self.set_hvac_mode(HVAC_MODE_COOL)
-
- @property
- def target_temperature(self):
- """Return the temperature we try to reach."""
- return self.wink.current_max_set_point()
-
- @property
- def fan_mode(self):
- """
- Return the current fan mode.
-
- The official Wink app only supports 3 modes [low, medium, high]
- which are equal to [0.33, 0.66, 1.0] respectively.
- """
- speed = self.wink.current_fan_speed()
- if speed <= 0.33:
- return FAN_LOW
- if speed <= 0.66:
- return FAN_MEDIUM
- return FAN_HIGH
-
- @property
- def fan_modes(self):
- """Return a list of available fan modes."""
- return SUPPORT_FAN_AC
-
- def set_fan_mode(self, fan_mode):
- """
- Set fan speed.
-
- The official Wink app only supports 3 modes [low, medium, high]
- which are equal to [0.33, 0.66, 1.0] respectively.
- """
- if fan_mode == FAN_LOW:
- speed = 0.33
- elif fan_mode == FAN_MEDIUM:
- speed = 0.66
- elif fan_mode == FAN_HIGH:
- speed = 1.0
- self.wink.set_ac_fan_speed(speed)
diff --git a/homeassistant/components/wink/cover.py b/homeassistant/components/wink/cover.py
deleted file mode 100644
index f2f4241c64d..00000000000
--- a/homeassistant/components/wink/cover.py
+++ /dev/null
@@ -1,57 +0,0 @@
-"""Support for Wink covers."""
-import pywink
-
-from homeassistant.components.cover import ATTR_POSITION, CoverEntity
-
-from . import DOMAIN, WinkDevice
-
-
-def setup_platform(hass, config, add_entities, discovery_info=None):
- """Set up the Wink cover platform."""
-
- for shade in pywink.get_shades():
- _id = shade.object_id() + shade.name()
- if _id not in hass.data[DOMAIN]["unique_ids"]:
- add_entities([WinkCoverEntity(shade, hass)])
- for shade in pywink.get_shade_groups():
- _id = shade.object_id() + shade.name()
- if _id not in hass.data[DOMAIN]["unique_ids"]:
- add_entities([WinkCoverEntity(shade, hass)])
- for door in pywink.get_garage_doors():
- _id = door.object_id() + door.name()
- if _id not in hass.data[DOMAIN]["unique_ids"]:
- add_entities([WinkCoverEntity(door, hass)])
-
-
-class WinkCoverEntity(WinkDevice, CoverEntity):
- """Representation of a Wink cover device."""
-
- async def async_added_to_hass(self):
- """Call when entity is added to hass."""
- self.hass.data[DOMAIN]["entities"]["cover"].append(self)
-
- def close_cover(self, **kwargs):
- """Close the cover."""
- self.wink.set_state(0)
-
- def open_cover(self, **kwargs):
- """Open the cover."""
- self.wink.set_state(1)
-
- def set_cover_position(self, **kwargs):
- """Move the cover shutter to a specific position."""
- position = kwargs.get(ATTR_POSITION)
- self.wink.set_state(position / 100)
-
- @property
- def current_cover_position(self):
- """Return the current position of cover shutter."""
- if self.wink.state() is not None:
- return int(self.wink.state() * 100)
- return None
-
- @property
- def is_closed(self):
- """Return if the cover is closed."""
- state = self.wink.state()
- return bool(state == 0)
diff --git a/homeassistant/components/wink/fan.py b/homeassistant/components/wink/fan.py
deleted file mode 100644
index b918d596ef4..00000000000
--- a/homeassistant/components/wink/fan.py
+++ /dev/null
@@ -1,112 +0,0 @@
-"""Support for Wink fans."""
-from __future__ import annotations
-
-import pywink
-
-from homeassistant.components.fan import (
- SPEED_HIGH,
- SPEED_LOW,
- SPEED_MEDIUM,
- SUPPORT_DIRECTION,
- SUPPORT_SET_SPEED,
- FanEntity,
-)
-
-from . import DOMAIN, WinkDevice
-
-SPEED_AUTO = "auto"
-SPEED_LOWEST = "lowest"
-SUPPORTED_FEATURES = SUPPORT_DIRECTION + SUPPORT_SET_SPEED
-
-
-def setup_platform(hass, config, add_entities, discovery_info=None):
- """Set up the Wink platform."""
-
- for fan in pywink.get_fans():
- if fan.object_id() + fan.name() not in hass.data[DOMAIN]["unique_ids"]:
- add_entities([WinkFanDevice(fan, hass)])
-
-
-class WinkFanDevice(WinkDevice, FanEntity):
- """Representation of a Wink fan."""
-
- async def async_added_to_hass(self):
- """Call when entity is added to hass."""
- self.hass.data[DOMAIN]["entities"]["fan"].append(self)
-
- def set_direction(self, direction: str) -> None:
- """Set the direction of the fan."""
- self.wink.set_fan_direction(direction)
-
- def set_speed(self, speed: str) -> None:
- """Set the speed of the fan."""
- self.wink.set_state(True, speed)
-
- #
- # The fan entity model has changed to use percentages and preset_modes
- # instead of speeds.
- #
- # Please review
- # https://developers.home-assistant.io/docs/core/entity/fan/
- #
- def turn_on(
- self,
- speed: str = None,
- percentage: int = None,
- preset_mode: str = None,
- **kwargs,
- ) -> None:
- """Turn on the fan."""
- self.wink.set_state(True, speed)
-
- def turn_off(self, **kwargs) -> None:
- """Turn off the fan."""
- self.wink.set_state(False)
-
- @property
- def is_on(self):
- """Return true if the entity is on."""
- return self.wink.state()
-
- @property
- def speed(self) -> str | None:
- """Return the current speed."""
- current_wink_speed = self.wink.current_fan_speed()
- if SPEED_AUTO == current_wink_speed:
- return SPEED_AUTO
- if SPEED_LOWEST == current_wink_speed:
- return SPEED_LOWEST
- if SPEED_LOW == current_wink_speed:
- return SPEED_LOW
- if SPEED_MEDIUM == current_wink_speed:
- return SPEED_MEDIUM
- if SPEED_HIGH == current_wink_speed:
- return SPEED_HIGH
- return None
-
- @property
- def current_direction(self):
- """Return direction of the fan [forward, reverse]."""
- return self.wink.current_fan_direction()
-
- @property
- def speed_list(self) -> list:
- """Get the list of available speeds."""
- wink_supported_speeds = self.wink.fan_speeds()
- supported_speeds = []
- if SPEED_AUTO in wink_supported_speeds:
- supported_speeds.append(SPEED_AUTO)
- if SPEED_LOWEST in wink_supported_speeds:
- supported_speeds.append(SPEED_LOWEST)
- if SPEED_LOW in wink_supported_speeds:
- supported_speeds.append(SPEED_LOW)
- if SPEED_MEDIUM in wink_supported_speeds:
- supported_speeds.append(SPEED_MEDIUM)
- if SPEED_HIGH in wink_supported_speeds:
- supported_speeds.append(SPEED_HIGH)
- return supported_speeds
-
- @property
- def supported_features(self) -> int:
- """Flag supported features."""
- return SUPPORTED_FEATURES
diff --git a/homeassistant/components/wink/light.py b/homeassistant/components/wink/light.py
deleted file mode 100644
index 4d20cf4dd5a..00000000000
--- a/homeassistant/components/wink/light.py
+++ /dev/null
@@ -1,114 +0,0 @@
-"""Support for Wink lights."""
-import pywink
-
-from homeassistant.components.light import (
- ATTR_BRIGHTNESS,
- ATTR_COLOR_TEMP,
- ATTR_HS_COLOR,
- SUPPORT_BRIGHTNESS,
- SUPPORT_COLOR,
- SUPPORT_COLOR_TEMP,
- LightEntity,
-)
-from homeassistant.util import color as color_util
-from homeassistant.util.color import (
- color_temperature_mired_to_kelvin as mired_to_kelvin,
-)
-
-from . import DOMAIN, WinkDevice
-
-
-def setup_platform(hass, config, add_entities, discovery_info=None):
- """Set up the Wink lights."""
-
- for light in pywink.get_light_bulbs():
- _id = light.object_id() + light.name()
- if _id not in hass.data[DOMAIN]["unique_ids"]:
- add_entities([WinkLight(light, hass)])
- for light in pywink.get_light_groups():
- _id = light.object_id() + light.name()
- if _id not in hass.data[DOMAIN]["unique_ids"]:
- add_entities([WinkLight(light, hass)])
-
-
-class WinkLight(WinkDevice, LightEntity):
- """Representation of a Wink light."""
-
- async def async_added_to_hass(self):
- """Call when entity is added to hass."""
- self.hass.data[DOMAIN]["entities"]["light"].append(self)
-
- @property
- def is_on(self):
- """Return true if light is on."""
- return self.wink.state()
-
- @property
- def brightness(self):
- """Return the brightness of the light."""
- if self.wink.brightness() is not None:
- return int(self.wink.brightness() * 255)
- return None
-
- @property
- def hs_color(self):
- """Define current bulb color."""
- if self.wink.supports_xy_color():
- return color_util.color_xy_to_hs(*self.wink.color_xy())
-
- if self.wink.supports_hue_saturation():
- hue = self.wink.color_hue()
- saturation = self.wink.color_saturation()
- if hue is not None and saturation is not None:
- return hue * 360, saturation * 100
-
- return None
-
- @property
- def color_temp(self):
- """Define current bulb color in degrees Kelvin."""
- if not self.wink.supports_temperature():
- return None
- return color_util.color_temperature_kelvin_to_mired(
- self.wink.color_temperature_kelvin()
- )
-
- @property
- def supported_features(self):
- """Flag supported features."""
- supports = SUPPORT_BRIGHTNESS
- if self.wink.supports_temperature():
- supports = supports | SUPPORT_COLOR_TEMP
- if self.wink.supports_xy_color():
- supports = supports | SUPPORT_COLOR
- elif self.wink.supports_hue_saturation():
- supports = supports | SUPPORT_COLOR
- return supports
-
- def turn_on(self, **kwargs):
- """Turn the switch on."""
- brightness = kwargs.get(ATTR_BRIGHTNESS)
- hs_color = kwargs.get(ATTR_HS_COLOR)
- color_temp_mired = kwargs.get(ATTR_COLOR_TEMP)
-
- state_kwargs = {}
-
- if hs_color:
- if self.wink.supports_xy_color():
- xy_color = color_util.color_hs_to_xy(*hs_color)
- state_kwargs["color_xy"] = xy_color
- if self.wink.supports_hue_saturation():
- hs_scaled = hs_color[0] / 360, hs_color[1] / 100
- state_kwargs["color_hue_saturation"] = hs_scaled
-
- if color_temp_mired:
- state_kwargs["color_kelvin"] = mired_to_kelvin(color_temp_mired)
-
- if brightness:
- state_kwargs["brightness"] = brightness / 255.0
-
- self.wink.set_state(True, **state_kwargs)
-
- def turn_off(self, **kwargs):
- """Turn the switch off."""
- self.wink.set_state(False)
diff --git a/homeassistant/components/wink/lock.py b/homeassistant/components/wink/lock.py
deleted file mode 100644
index 63a67d9f1ac..00000000000
--- a/homeassistant/components/wink/lock.py
+++ /dev/null
@@ -1,211 +0,0 @@
-"""Support for Wink locks."""
-import pywink
-import voluptuous as vol
-
-from homeassistant.components.lock import LockEntity
-from homeassistant.const import (
- ATTR_CODE,
- ATTR_ENTITY_ID,
- ATTR_MODE,
- ATTR_NAME,
- STATE_UNKNOWN,
-)
-import homeassistant.helpers.config_validation as cv
-
-from . import DOMAIN, WinkDevice
-
-SERVICE_SET_VACATION_MODE = "set_lock_vacation_mode"
-SERVICE_SET_ALARM_MODE = "set_lock_alarm_mode"
-SERVICE_SET_ALARM_SENSITIVITY = "set_lock_alarm_sensitivity"
-SERVICE_SET_ALARM_STATE = "set_lock_alarm_state"
-SERVICE_SET_BEEPER_STATE = "set_lock_beeper_state"
-SERVICE_ADD_KEY = "add_new_lock_key_code"
-
-ATTR_ENABLED = "enabled"
-ATTR_SENSITIVITY = "sensitivity"
-
-ALARM_SENSITIVITY_MAP = {
- "low": 0.2,
- "medium_low": 0.4,
- "medium": 0.6,
- "medium_high": 0.8,
- "high": 1.0,
-}
-
-ALARM_MODES_MAP = {
- "activity": "alert",
- "forced_entry": "forced_entry",
- "tamper": "tamper",
-}
-
-SET_ENABLED_SCHEMA = vol.Schema(
- {vol.Optional(ATTR_ENTITY_ID): cv.entity_ids, vol.Required(ATTR_ENABLED): cv.string}
-)
-
-SET_SENSITIVITY_SCHEMA = vol.Schema(
- {
- vol.Optional(ATTR_ENTITY_ID): cv.entity_ids,
- vol.Required(ATTR_SENSITIVITY): vol.In(ALARM_SENSITIVITY_MAP),
- }
-)
-
-SET_ALARM_MODES_SCHEMA = vol.Schema(
- {
- vol.Optional(ATTR_ENTITY_ID): cv.entity_ids,
- vol.Required(ATTR_MODE): vol.In(ALARM_MODES_MAP),
- }
-)
-
-ADD_KEY_SCHEMA = vol.Schema(
- {
- vol.Optional(ATTR_ENTITY_ID): cv.entity_ids,
- vol.Required(ATTR_NAME): cv.string,
- vol.Required(ATTR_CODE): cv.positive_int,
- }
-)
-
-
-def setup_platform(hass, config, add_entities, discovery_info=None):
- """Set up the Wink platform."""
-
- for lock in pywink.get_locks():
- _id = lock.object_id() + lock.name()
- if _id not in hass.data[DOMAIN]["unique_ids"]:
- add_entities([WinkLockDevice(lock, hass)])
-
- def service_handle(service):
- """Handle for services."""
- entity_ids = service.data.get("entity_id")
- all_locks = hass.data[DOMAIN]["entities"]["lock"]
- locks_to_set = []
- if entity_ids is None:
- locks_to_set = all_locks
- else:
- for lock in all_locks:
- if lock.entity_id in entity_ids:
- locks_to_set.append(lock)
-
- for lock in locks_to_set:
- if service.service == SERVICE_SET_VACATION_MODE:
- lock.set_vacation_mode(service.data.get(ATTR_ENABLED))
- elif service.service == SERVICE_SET_ALARM_STATE:
- lock.set_alarm_state(service.data.get(ATTR_ENABLED))
- elif service.service == SERVICE_SET_BEEPER_STATE:
- lock.set_beeper_state(service.data.get(ATTR_ENABLED))
- elif service.service == SERVICE_SET_ALARM_MODE:
- lock.set_alarm_mode(service.data.get(ATTR_MODE))
- elif service.service == SERVICE_SET_ALARM_SENSITIVITY:
- lock.set_alarm_sensitivity(service.data.get(ATTR_SENSITIVITY))
- elif service.service == SERVICE_ADD_KEY:
- name = service.data.get(ATTR_NAME)
- code = service.data.get(ATTR_CODE)
- lock.add_new_key(code, name)
-
- hass.services.register(
- DOMAIN, SERVICE_SET_VACATION_MODE, service_handle, schema=SET_ENABLED_SCHEMA
- )
-
- hass.services.register(
- DOMAIN, SERVICE_SET_ALARM_STATE, service_handle, schema=SET_ENABLED_SCHEMA
- )
-
- hass.services.register(
- DOMAIN, SERVICE_SET_BEEPER_STATE, service_handle, schema=SET_ENABLED_SCHEMA
- )
-
- hass.services.register(
- DOMAIN, SERVICE_SET_ALARM_MODE, service_handle, schema=SET_ALARM_MODES_SCHEMA
- )
-
- hass.services.register(
- DOMAIN,
- SERVICE_SET_ALARM_SENSITIVITY,
- service_handle,
- schema=SET_SENSITIVITY_SCHEMA,
- )
-
- hass.services.register(
- DOMAIN, SERVICE_ADD_KEY, service_handle, schema=ADD_KEY_SCHEMA
- )
-
-
-class WinkLockDevice(WinkDevice, LockEntity):
- """Representation of a Wink lock."""
-
- async def async_added_to_hass(self):
- """Call when entity is added to hass."""
- self.hass.data[DOMAIN]["entities"]["lock"].append(self)
-
- @property
- def is_locked(self):
- """Return true if device is locked."""
- return self.wink.state()
-
- def lock(self, **kwargs):
- """Lock the device."""
- self.wink.set_state(True)
-
- def unlock(self, **kwargs):
- """Unlock the device."""
- self.wink.set_state(False)
-
- def set_alarm_state(self, enabled):
- """Set lock's alarm state."""
- self.wink.set_alarm_state(enabled)
-
- def set_vacation_mode(self, enabled):
- """Set lock's vacation mode."""
- self.wink.set_vacation_mode(enabled)
-
- def set_beeper_state(self, enabled):
- """Set lock's beeper mode."""
- self.wink.set_beeper_mode(enabled)
-
- def add_new_key(self, code, name):
- """Add a new user key code."""
- self.wink.add_new_key(code, name)
-
- def set_alarm_sensitivity(self, sensitivity):
- """
- Set lock's alarm sensitivity.
-
- Valid sensitivities:
- 0.2, 0.4, 0.6, 0.8, 1.0
- """
- self.wink.set_alarm_sensitivity(sensitivity)
-
- def set_alarm_mode(self, mode):
- """
- Set lock's alarm mode.
-
- Valid modes:
- alert - Beep when lock is locked or unlocked
- tamper - 15 sec alarm when lock is disturbed when locked
- forced_entry - 3 min alarm when significant force applied
- to door when locked.
- """
- self.wink.set_alarm_mode(mode)
-
- @property
- def extra_state_attributes(self):
- """Return the state attributes."""
- super_attrs = super().extra_state_attributes
- sensitivity = dict_value_to_key(
- ALARM_SENSITIVITY_MAP, self.wink.alarm_sensitivity()
- )
- super_attrs["alarm_sensitivity"] = sensitivity
- super_attrs["vacation_mode"] = self.wink.vacation_mode_enabled()
- super_attrs["beeper_mode"] = self.wink.beeper_enabled()
- super_attrs["auto_lock"] = self.wink.auto_lock_enabled()
- alarm_mode = dict_value_to_key(ALARM_MODES_MAP, self.wink.alarm_mode())
- super_attrs["alarm_mode"] = alarm_mode
- super_attrs["alarm_enabled"] = self.wink.alarm_enabled()
- return super_attrs
-
-
-def dict_value_to_key(dict_map, comp_value):
- """Return the key that has the provided value."""
- for key, value in dict_map.items():
- if value == comp_value:
- return key
- return STATE_UNKNOWN
diff --git a/homeassistant/components/wink/manifest.json b/homeassistant/components/wink/manifest.json
deleted file mode 100644
index e4da7b9c03a..00000000000
--- a/homeassistant/components/wink/manifest.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "domain": "wink",
- "name": "Wink",
- "documentation": "https://www.home-assistant.io/integrations/wink",
- "requirements": ["pubnubsub-handler==1.0.9", "python-wink==1.10.5"],
- "dependencies": ["configurator", "http"],
- "codeowners": [],
- "iot_class": "cloud_polling"
-}
diff --git a/homeassistant/components/wink/scene.py b/homeassistant/components/wink/scene.py
deleted file mode 100644
index 3f4724957f8..00000000000
--- a/homeassistant/components/wink/scene.py
+++ /dev/null
@@ -1,34 +0,0 @@
-"""Support for Wink scenes."""
-from typing import Any
-
-import pywink
-
-from homeassistant.components.scene import Scene
-
-from . import DOMAIN, WinkDevice
-
-
-def setup_platform(hass, config, add_entities, discovery_info=None):
- """Set up the Wink platform."""
-
- for scene in pywink.get_scenes():
- _id = scene.object_id() + scene.name()
- if _id not in hass.data[DOMAIN]["unique_ids"]:
- add_entities([WinkScene(scene, hass)])
-
-
-class WinkScene(WinkDevice, Scene):
- """Representation of a Wink shortcut/scene."""
-
- def __init__(self, wink, hass):
- """Initialize the Wink device."""
- super().__init__(wink, hass)
- hass.data[DOMAIN]["entities"]["scene"].append(self)
-
- async def async_added_to_hass(self):
- """Call when entity is added to hass."""
- self.hass.data[DOMAIN]["entities"]["scene"].append(self)
-
- def activate(self, **kwargs: Any) -> None:
- """Activate the scene."""
- self.wink.activate()
diff --git a/homeassistant/components/wink/sensor.py b/homeassistant/components/wink/sensor.py
deleted file mode 100644
index 86199f44e91..00000000000
--- a/homeassistant/components/wink/sensor.py
+++ /dev/null
@@ -1,98 +0,0 @@
-"""Support for Wink sensors."""
-from contextlib import suppress
-import logging
-
-import pywink
-
-from homeassistant.components.sensor import SensorEntity
-from homeassistant.const import DEGREE, TEMP_CELSIUS
-
-from . import DOMAIN, WinkDevice
-
-_LOGGER = logging.getLogger(__name__)
-
-SENSOR_TYPES = ["temperature", "humidity", "balance", "proximity"]
-
-
-def setup_platform(hass, config, add_entities, discovery_info=None):
- """Set up the Wink platform."""
-
- for sensor in pywink.get_sensors():
- _id = sensor.object_id() + sensor.name()
- if (
- _id not in hass.data[DOMAIN]["unique_ids"]
- and sensor.capability() in SENSOR_TYPES
- ):
- add_entities([WinkSensorEntity(sensor, hass)])
-
- for eggtray in pywink.get_eggtrays():
- _id = eggtray.object_id() + eggtray.name()
- if _id not in hass.data[DOMAIN]["unique_ids"]:
- add_entities([WinkSensorEntity(eggtray, hass)])
-
- for tank in pywink.get_propane_tanks():
- _id = tank.object_id() + tank.name()
- if _id not in hass.data[DOMAIN]["unique_ids"]:
- add_entities([WinkSensorEntity(tank, hass)])
-
- for piggy_bank in pywink.get_piggy_banks():
- _id = piggy_bank.object_id() + piggy_bank.name()
- if _id not in hass.data[DOMAIN]["unique_ids"]:
- try:
- if piggy_bank.capability() in SENSOR_TYPES:
- add_entities([WinkSensorEntity(piggy_bank, hass)])
- except AttributeError:
- _LOGGER.info("Device is not a sensor")
-
-
-class WinkSensorEntity(WinkDevice, SensorEntity):
- """Representation of a Wink sensor."""
-
- def __init__(self, wink, hass):
- """Initialize the Wink device."""
- super().__init__(wink, hass)
- self.capability = self.wink.capability()
- if self.wink.unit() == DEGREE:
- self._unit_of_measurement = TEMP_CELSIUS
- else:
- self._unit_of_measurement = self.wink.unit()
-
- async def async_added_to_hass(self):
- """Call when entity is added to hass."""
- self.hass.data[DOMAIN]["entities"]["sensor"].append(self)
-
- @property
- def native_value(self):
- """Return the state."""
- state = None
- if self.capability == "humidity":
- if self.wink.state() is not None:
- state = round(self.wink.state())
- elif self.capability == "temperature":
- if self.wink.state() is not None:
- state = round(self.wink.state(), 1)
- elif self.capability == "balance":
- if self.wink.state() is not None:
- state = round(self.wink.state() / 100, 2)
- elif self.capability == "proximity":
- if self.wink.state() is not None:
- state = self.wink.state()
- else:
- state = self.wink.state()
- return state
-
- @property
- def native_unit_of_measurement(self):
- """Return the unit of measurement of this entity, if any."""
- return self._unit_of_measurement
-
- @property
- def extra_state_attributes(self):
- """Return the state attributes."""
- super_attrs = super().extra_state_attributes
-
- # Ignore error, this sensor isn't an eggminder
- with suppress(AttributeError):
- super_attrs["egg_times"] = self.wink.eggs()
-
- return super_attrs
diff --git a/homeassistant/components/wink/services.yaml b/homeassistant/components/wink/services.yaml
deleted file mode 100644
index 851f3bb9a43..00000000000
--- a/homeassistant/components/wink/services.yaml
+++ /dev/null
@@ -1,431 +0,0 @@
-# Describes the format for available Wink services
-pair_new_device:
- name: Pair new device
- description: Pair a new device to a Wink Hub.
- fields:
- hub_name:
- name: Hub name
- description: The name of the hub to pair a new device to.
- required: true
- example: "My hub"
- selector:
- text:
- pairing_mode:
- name: Pairing mode
- description: Mode.
- required: true
- selector:
- select:
- options:
- - 'bluetooth'
- - 'kidde'
- - 'lutron'
- - 'zigbee'
- - 'zwave'
- - 'zwave_exclusion'
- - 'zwave_network_rediscovery'
- kidde_radio_code:
- name: Kidde radio code
- description: "A string of 8 1s and 0s one for each dip switch on the kidde device left --> right = 1 --> 8. Down = 1 and Up = 0"
- example: "10101010"
- selector:
- text:
-
-rename_wink_device:
- name: Rename wink device
- description: Rename the provided device.
- target:
- entity:
- integration: wink
- fields:
- name:
- name: Name
- description: The name to change it to.
- required: true
- example: back_door
- selector:
- text:
-
-delete_wink_device:
- name: Delete wink device
- description: Remove/unpair device from Wink.
- target:
- entity:
- integration: wink
-
-pull_newly_added_devices_from_wink:
- name: Pull newly added devices from wink
- description: Pull newly paired devices from Wink.
-
-refresh_state_from_wink:
- name: Refresh state from wink
- description: Pull the latest states for every device.
-
-set_siren_volume:
- name: Set siren volume
- description: Set the volume of the siren for a Dome siren/chime.
- target:
- entity:
- integration: wink
- domain: switch
- fields:
- volume:
- name: Volume
- description: Volume level.
- required: true
- selector:
- select:
- options:
- - 'low'
- - 'medium'
- - 'high'
-
-enable_chime:
- name: Enable chime
- description: Enable the chime of a Dome siren with the provided sound.
- target:
- entity:
- integration: wink
- domain: switch
- fields:
- tone:
- name: Tone
- description: >-
- The tone to use for the chime.
- required: true
- selector:
- select:
- options:
- - 'alert'
- - 'beep'
- - 'beep_beep'
- - 'doorbell'
- - 'doorbell_extended'
- - 'evacuation'
- - 'fur_elise'
- - 'inactive'
- - 'police_siren'
- - 'rondo_alla_turca'
- - 'william_tell'
-
-set_siren_tone:
- name: Set siren tone
- description: Set the sound to use when the siren is enabled. (This doesn't enable the siren)
- target:
- entity:
- integration: wink
- domain: switch
- fields:
- tone:
- name: Tone
- description: >-
- The tone to use for the chime.
- required: true
- selector:
- select:
- options:
- - 'alert'
- - 'beep'
- - 'beep_beep'
- - 'doorbell'
- - 'doorbell_extended'
- - 'evacuation'
- - 'fur_elise'
- - 'inactive'
- - 'police_siren'
- - 'rondo_alla_turca'
- - 'william_tell'
-
-siren_set_auto_shutoff:
- name: Siren set auto shutoff
- description: How long to sound the siren before turning off.
- target:
- entity:
- integration: wink
- domain: switch
- fields:
- auto_shutoff:
- name: Auto shutoff
- description: >-
- The time in seconds to sound the siren. (None and -1 are forever. Use None for gocontrol, and -1 for Dome)
- required: true
- selector:
- select:
- options:
- - 'None'
- - '-1'
- - '30'
- - '60'
- - '120'
-
-set_siren_strobe_enabled:
- name: Set siren strobe enabled
- description: Enable or disable the strobe light when the siren is sounding.
- target:
- entity:
- integration: wink
- domain: switch
- fields:
- enabled:
- name: Enabled
- description: "True or False"
- required: true
- selector:
- boolean:
-
-set_chime_strobe_enabled:
- name: Set chime strobe enabled
- description: Enable or disable the strobe light when the chime is sounding.
- target:
- entity:
- integration: wink
- domain: switch
- fields:
- enabled:
- name: Enabled
- description: "True or False"
- required: true
- selector:
- boolean:
-
-enable_siren:
- name: Enable siren
- description: Enable/disable the siren.
- target:
- entity:
- integration: wink
- domain: switch
- fields:
- enabled:
- name: Enabled
- description: "true or false"
- required: true
- selector:
- boolean:
-
-set_chime_volume:
- name: Set chime volume
- description: Set the volume of the chime for a Dome siren/chime.
- target:
- entity:
- integration: wink
- domain: switch
- fields:
- volume:
- name: Volume
- description: Volume level.
- required: true
- selector:
- select:
- options:
- - 'low'
- - 'medium'
- - 'high'
-
-set_nimbus_dial_configuration:
- name: Set nimbus dial configuration
- description: Set the configuration of an individual nimbus dial
- target:
- entity:
- integration: wink
- domain: switch
- fields:
- rotation:
- name: Rotation
- description: Direction dial hand should spin.
- selector:
- select:
- options:
- - 'cw'
- - 'ccw'
- ticks:
- name: Ticks
- description: Number of times the hand should move
- selector:
- number:
- min: 0
- max: 3600
- scale:
- name: Scale
- description: How the dial should move in response to higher values.
- selector:
- select:
- options:
- - 'linear'
- - 'log'
- min_value:
- name: minimum value
- description: The minimum value allowed to be set
- example: 0
- selector:
- text:
- max_value:
- name: Maximum value
- description: The maximum value allowed to be set
- example: 500
- selector:
- text:
- min_position:
- name: Minimum position
- description: The minimum position the dial hand can rotate to generally.
- selector:
- number:
- min: 0
- max: 360
- max_position:
- name: Maximum position
- description: The maximum position the dial hand can rotate to generally.
- selector:
- number:
- min: 0
- max: 360
-
-set_nimbus_dial_state:
- name: Set nimbus dial state
- description: Set the value and labels of an individual nimbus dial
- target:
- entity:
- integration: wink
- fields:
- value:
- name: Value
- description: The value that should be set (Should be between min_value and max_value)
- required: true
- example: 250
- selector:
- text:
- labels:
- name: Labels
- description: >-
- The values shown on the dial labels ["Dial 1", "test"] the first value
- is what is shown by default the second value is shown when the nimbus is
- pressed.
- example: ["example", "test"]
- selector:
- object:
-
-set_lock_vacation_mode:
- name: Set lock vacation mode
- description: Set vacation mode for all or specified locks. Disables all user codes.
- fields:
- entity_id:
- name: Entity
- description: Name of lock to unlock.
- selector:
- entity:
- integration: wink
- domain: lock
- enabled:
- name: Enabled
- description: enable or disable. true or false.
- required: true
- selector:
- boolean:
-
-set_lock_alarm_mode:
- name: Set lock alarm mode
- description: Set alarm mode for all or specified locks.
- fields:
- entity_id:
- name: Entity
- description: Name of lock to unlock.
- selector:
- entity:
- integration: wink
- domain: lock
- mode:
- name: Mode
- description: Select mode.
- required: true
- selector:
- select:
- options:
- - 'activity'
- - 'forced_entry'
- - 'tamper'
-
-set_lock_alarm_sensitivity:
- name: Set lock alarm sensitivity
- description: Set alarm sensitivity for all or specified locks.
- fields:
- entity_id:
- name: Entity
- description: Name of lock to unlock.
- selector:
- entity:
- integration: wink
- domain: lock
- sensitivity:
- name: Sensitivity
- description: Choose the sensitivity.
- required: true
- selector:
- select:
- options:
- - 'low'
- - 'medium_low'
- - 'medium'
- - 'medium_high'
- - 'high'
-
-set_lock_alarm_state:
- name: Set lok alarm state
- description: Set alarm state.
- fields:
- entity_id:
- name: Entity
- description: Name of lock to unlock.
- selector:
- entity:
- integration: wink
- domain: lock
- enabled:
- name: Enabled
- description: enable or disable.
- required: true
- selector:
- boolean:
-
-set_lock_beeper_state:
- name: Set lock beeper state
- description: Set beeper state.
- fields:
- entity_id:
- name: Entity
- description: Name of lock to unlock.
- selector:
- entity:
- integration: wink
- domain: lock
- enabled:
- name: Enabled
- description: enable or disable.
- required: true
- selector:
- boolean:
-
-add_new_lock_key_code:
- name: Add new lock key code
- description: Add a new user key code.
- fields:
- entity_id:
- name: Entity
- description: Name of lock to unlock.
- selector:
- entity:
- integration: wink
- domain: lock
- name:
- name: Name
- description: name of the new key code.
- required: true
- example: Bob
- selector:
- text:
- code:
- name: Code
- description: new key code, length must match length of other codes. Default length is 4.
- required: true
- example: 1234
- selector:
- text:
diff --git a/homeassistant/components/wink/switch.py b/homeassistant/components/wink/switch.py
deleted file mode 100644
index d377ae0cddf..00000000000
--- a/homeassistant/components/wink/switch.py
+++ /dev/null
@@ -1,60 +0,0 @@
-"""Support for Wink switches."""
-import pywink
-
-from homeassistant.helpers.entity import ToggleEntity
-
-from . import DOMAIN, WinkDevice
-
-
-def setup_platform(hass, config, add_entities, discovery_info=None):
- """Set up the Wink platform."""
-
- for switch in pywink.get_switches():
- _id = switch.object_id() + switch.name()
- if _id not in hass.data[DOMAIN]["unique_ids"]:
- add_entities([WinkToggleDevice(switch, hass)])
- for switch in pywink.get_powerstrips():
- _id = switch.object_id() + switch.name()
- if _id not in hass.data[DOMAIN]["unique_ids"]:
- add_entities([WinkToggleDevice(switch, hass)])
- for sprinkler in pywink.get_sprinklers():
- _id = sprinkler.object_id() + sprinkler.name()
- if _id not in hass.data[DOMAIN]["unique_ids"]:
- add_entities([WinkToggleDevice(sprinkler, hass)])
- for switch in pywink.get_binary_switch_groups():
- _id = switch.object_id() + switch.name()
- if _id not in hass.data[DOMAIN]["unique_ids"]:
- add_entities([WinkToggleDevice(switch, hass)])
-
-
-class WinkToggleDevice(WinkDevice, ToggleEntity):
- """Representation of a Wink toggle device."""
-
- async def async_added_to_hass(self):
- """Call when entity is added to hass."""
- self.hass.data[DOMAIN]["entities"]["switch"].append(self)
-
- @property
- def is_on(self):
- """Return true if device is on."""
- return self.wink.state()
-
- def turn_on(self, **kwargs):
- """Turn the device on."""
- self.wink.set_state(True)
-
- def turn_off(self, **kwargs):
- """Turn the device off."""
- self.wink.set_state(False)
-
- @property
- def extra_state_attributes(self):
- """Return the state attributes."""
- attributes = super().extra_state_attributes
- try:
- event = self.wink.last_event()
- if event is not None:
- attributes["last_event"] = event
- except AttributeError:
- pass
- return attributes
diff --git a/homeassistant/components/wink/water_heater.py b/homeassistant/components/wink/water_heater.py
deleted file mode 100644
index bf5e8434746..00000000000
--- a/homeassistant/components/wink/water_heater.py
+++ /dev/null
@@ -1,143 +0,0 @@
-"""Support for Wink water heaters."""
-import logging
-
-import pywink
-
-from homeassistant.components.water_heater import (
- ATTR_TEMPERATURE,
- STATE_ECO,
- STATE_ELECTRIC,
- STATE_GAS,
- STATE_HEAT_PUMP,
- STATE_HIGH_DEMAND,
- STATE_PERFORMANCE,
- SUPPORT_AWAY_MODE,
- SUPPORT_OPERATION_MODE,
- SUPPORT_TARGET_TEMPERATURE,
- WaterHeaterEntity,
-)
-from homeassistant.const import STATE_OFF, STATE_UNKNOWN, TEMP_CELSIUS
-
-from . import DOMAIN, WinkDevice
-
-_LOGGER = logging.getLogger(__name__)
-
-SUPPORT_FLAGS_HEATER = (
- SUPPORT_TARGET_TEMPERATURE | SUPPORT_OPERATION_MODE | SUPPORT_AWAY_MODE
-)
-
-ATTR_RHEEM_TYPE = "rheem_type"
-ATTR_VACATION_MODE = "vacation_mode"
-
-HA_STATE_TO_WINK = {
- STATE_ECO: "eco",
- STATE_ELECTRIC: "electric_only",
- STATE_GAS: "gas",
- STATE_HEAT_PUMP: "heat_pump",
- STATE_HIGH_DEMAND: "high_demand",
- STATE_OFF: "off",
- STATE_PERFORMANCE: "performance",
-}
-
-WINK_STATE_TO_HA = {value: key for key, value in HA_STATE_TO_WINK.items()}
-
-
-def setup_platform(hass, config, add_entities, discovery_info=None):
- """Set up the Wink water heater devices."""
-
- for water_heater in pywink.get_water_heaters():
- _id = water_heater.object_id() + water_heater.name()
- if _id not in hass.data[DOMAIN]["unique_ids"]:
- add_entities([WinkWaterHeater(water_heater, hass)])
-
-
-class WinkWaterHeater(WinkDevice, WaterHeaterEntity):
- """Representation of a Wink water heater."""
-
- @property
- def supported_features(self):
- """Return the list of supported features."""
- return SUPPORT_FLAGS_HEATER
-
- @property
- def temperature_unit(self):
- """Return the unit of measurement."""
- # The Wink API always returns temp in Celsius
- return TEMP_CELSIUS
-
- @property
- def extra_state_attributes(self):
- """Return the optional device state attributes."""
- data = {}
- data[ATTR_VACATION_MODE] = self.wink.vacation_mode_enabled()
- data[ATTR_RHEEM_TYPE] = self.wink.rheem_type()
-
- return data
-
- @property
- def current_operation(self):
- """
- Return current operation one of the following.
-
- ["eco", "performance", "heat_pump",
- "high_demand", "electric_only", "gas]
- """
- if not self.wink.is_on():
- current_op = STATE_OFF
- else:
- current_op = WINK_STATE_TO_HA.get(self.wink.current_mode())
- if current_op is None:
- current_op = STATE_UNKNOWN
- return current_op
-
- @property
- def operation_list(self):
- """List of available operation modes."""
- op_list = ["off"]
- modes = self.wink.modes()
- for mode in modes:
- if mode == "aux":
- continue
- ha_mode = WINK_STATE_TO_HA.get(mode)
- if ha_mode is not None:
- op_list.append(ha_mode)
- else:
- error = (
- "Invalid operation mode mapping. "
- f"{mode} doesn't map. Please report this."
- )
- _LOGGER.error(error)
- return op_list
-
- def set_temperature(self, **kwargs):
- """Set new target temperature."""
- target_temp = kwargs.get(ATTR_TEMPERATURE)
- self.wink.set_temperature(target_temp)
-
- def set_operation_mode(self, operation_mode):
- """Set operation mode."""
- op_mode_to_set = HA_STATE_TO_WINK.get(operation_mode)
- self.wink.set_operation_mode(op_mode_to_set)
-
- @property
- def target_temperature(self):
- """Return the temperature we try to reach."""
- return self.wink.current_set_point()
-
- def turn_away_mode_on(self):
- """Turn away on."""
- self.wink.set_vacation_mode(True)
-
- def turn_away_mode_off(self):
- """Turn away off."""
- self.wink.set_vacation_mode(False)
-
- @property
- def min_temp(self):
- """Return the minimum temperature."""
- return self.wink.min_set_point()
-
- @property
- def max_temp(self):
- """Return the maximum temperature."""
- return self.wink.max_set_point()
diff --git a/requirements_all.txt b/requirements_all.txt
index dcc9efa042f..42577015a37 100644
--- a/requirements_all.txt
+++ b/requirements_all.txt
@@ -1259,9 +1259,6 @@ proxmoxer==1.1.1
# homeassistant.components.systemmonitor
psutil==5.8.0
-# homeassistant.components.wink
-pubnubsub-handler==1.0.9
-
# homeassistant.components.pulseaudio_loopback
pulsectl==20.2.4
@@ -1948,9 +1945,6 @@ python-vlc==1.1.2
# homeassistant.components.whois
python-whois==0.7.3
-# homeassistant.components.wink
-python-wink==1.10.5
-
# homeassistant.components.awair
python_awair==0.2.1
diff --git a/script/hassfest/coverage.py b/script/hassfest/coverage.py
index 1a8609bb4e8..1e91edee90e 100644
--- a/script/hassfest/coverage.py
+++ b/script/hassfest/coverage.py
@@ -62,7 +62,6 @@ ALLOWED_IGNORE_VIOLATIONS = {
("velux", "scene.py"),
("wemo", "config_flow.py"),
("wiffi", "config_flow.py"),
- ("wink", "scene.py"),
}