diff --git a/homeassistant/components/ambiclimate/manifest.json b/homeassistant/components/ambiclimate/manifest.json
index 3d175165abd1fc963469612c193150c880cf9c5e..151b761dff8656a48782ba9c69399febf891c365 100644
--- a/homeassistant/components/ambiclimate/manifest.json
+++ b/homeassistant/components/ambiclimate/manifest.json
@@ -3,11 +3,7 @@
   "name": "Ambiclimate",
   "config_flow": true,
   "documentation": "https://www.home-assistant.io/integrations/ambiclimate",
-  "requirements": [
-    "ambiclimate==0.2.1"
-  ],
-  "dependencies": [],
-  "codeowners": [
-    "@danielhiversen"
-  ]
+  "requirements": ["ambiclimate==0.2.1"],
+  "dependencies": ["http"],
+  "codeowners": ["@danielhiversen"]
 }
diff --git a/homeassistant/components/apns/manifest.json b/homeassistant/components/apns/manifest.json
index 4845c45a963dce92461f4312f793710819e556c7..3c38238f7ebf61a0e584f37d65076e15b9da6fc3 100644
--- a/homeassistant/components/apns/manifest.json
+++ b/homeassistant/components/apns/manifest.json
@@ -2,9 +2,8 @@
   "domain": "apns",
   "name": "Apns",
   "documentation": "https://www.home-assistant.io/integrations/apns",
-  "requirements": [
-    "apns2==0.3.0"
-  ],
+  "requirements": ["apns2==0.3.0"],
   "dependencies": [],
+  "after_dependencies": ["device_tracker"],
   "codeowners": []
 }
diff --git a/homeassistant/components/camera/manifest.json b/homeassistant/components/camera/manifest.json
index 1bd4bb7caeb065ced7449e428ba2ad8bcb2411b7..32cd7c3fe47138d14febbd87eb51807ef71d90d0 100644
--- a/homeassistant/components/camera/manifest.json
+++ b/homeassistant/components/camera/manifest.json
@@ -4,5 +4,6 @@
   "documentation": "https://www.home-assistant.io/integrations/camera",
   "requirements": [],
   "dependencies": ["http"],
+  "after_dependencies": ["stream", "media_player"],
   "codeowners": []
 }
diff --git a/homeassistant/components/cloud/manifest.json b/homeassistant/components/cloud/manifest.json
index ec9a556af0ac5ca87df42a301b787f6f182fb90b..accc4a0c0f9971cd29091dfba849adb93179aad0 100644
--- a/homeassistant/components/cloud/manifest.json
+++ b/homeassistant/components/cloud/manifest.json
@@ -4,5 +4,6 @@
   "documentation": "https://www.home-assistant.io/integrations/cloud",
   "requirements": ["hass-nabucasa==0.30"],
   "dependencies": ["http", "webhook"],
+  "after_dependencies": ["alexa", "google_assistant"],
   "codeowners": ["@home-assistant/cloud"]
 }
diff --git a/homeassistant/components/doorbird/manifest.json b/homeassistant/components/doorbird/manifest.json
index c9cdb32e18af318f0d2ad69d32c577763ebaf7c6..61225b86a445c7a04fc9bee9f8e47fd71ab714d6 100644
--- a/homeassistant/components/doorbird/manifest.json
+++ b/homeassistant/components/doorbird/manifest.json
@@ -2,11 +2,7 @@
   "domain": "doorbird",
   "name": "Doorbird",
   "documentation": "https://www.home-assistant.io/integrations/doorbird",
-  "requirements": [
-    "doorbirdpy==2.0.8"
-  ],
-  "dependencies": [],
-  "codeowners": [
-    "@oblogic7"
-  ]
+  "requirements": ["doorbirdpy==2.0.8"],
+  "dependencies": ["http"],
+  "codeowners": ["@oblogic7"]
 }
diff --git a/homeassistant/components/hikvisioncam/switch.py b/homeassistant/components/hikvisioncam/switch.py
index 020b894c0f76bd0d0c3fff09755975e21b89acaa..f86853a5468ae3247e0cdd52a4cbea201aa9db54 100644
--- a/homeassistant/components/hikvisioncam/switch.py
+++ b/homeassistant/components/hikvisioncam/switch.py
@@ -5,7 +5,7 @@ import hikvision.api
 from hikvision.error import HikvisionError, MissingParamError
 import voluptuous as vol
 
-from homeassistant.components.sensor import PLATFORM_SCHEMA
+from homeassistant.components.switch import PLATFORM_SCHEMA, SwitchDevice
 from homeassistant.const import (
     CONF_HOST,
     CONF_NAME,
@@ -16,7 +16,6 @@ from homeassistant.const import (
     STATE_ON,
 )
 import homeassistant.helpers.config_validation as cv
-from homeassistant.helpers.entity import ToggleEntity
 
 # This is the last working version, please test before updating
 
@@ -60,7 +59,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
     add_entities([HikvisionMotionSwitch(name, hikvision_cam)])
 
 
-class HikvisionMotionSwitch(ToggleEntity):
+class HikvisionMotionSwitch(SwitchDevice):
     """Representation of a switch to toggle on/off motion detection."""
 
     def __init__(self, name, hikvision_cam):
diff --git a/homeassistant/components/html5/manifest.json b/homeassistant/components/html5/manifest.json
index 667a57891821a7617f6768a744a4f2df17bbfb9c..dd794ae03866b7092367cb5c4796fd2532efaa50 100644
--- a/homeassistant/components/html5/manifest.json
+++ b/homeassistant/components/html5/manifest.json
@@ -2,11 +2,7 @@
   "domain": "html5",
   "name": "HTML5 Notifications",
   "documentation": "https://www.home-assistant.io/integrations/html5",
-  "requirements": [
-    "pywebpush==1.9.2"
-  ],
-  "dependencies": ["frontend"],
-  "codeowners": [
-    "@robbiet480"
-  ]
+  "requirements": ["pywebpush==1.9.2"],
+  "dependencies": ["http"],
+  "codeowners": ["@robbiet480"]
 }
diff --git a/homeassistant/components/logbook/manifest.json b/homeassistant/components/logbook/manifest.json
index e8e3ad8ac2e580c803316a587a26e0891e3079f6..08083ea40245792f2c3661789f22b52440d4ce31 100644
--- a/homeassistant/components/logbook/manifest.json
+++ b/homeassistant/components/logbook/manifest.json
@@ -3,9 +3,6 @@
   "name": "Logbook",
   "documentation": "https://www.home-assistant.io/integrations/logbook",
   "requirements": [],
-  "dependencies": [
-    "frontend",
-    "recorder"
-  ],
+  "dependencies": ["frontend", "http", "recorder"],
   "codeowners": []
 }
diff --git a/homeassistant/components/logi_circle/manifest.json b/homeassistant/components/logi_circle/manifest.json
index 22502956e06aa52f383e85d98444f1779b3f5413..bd6dc8a8d27bc26b7eb554f0b1f433a13f479ff6 100644
--- a/homeassistant/components/logi_circle/manifest.json
+++ b/homeassistant/components/logi_circle/manifest.json
@@ -4,6 +4,6 @@
   "config_flow": true,
   "documentation": "https://www.home-assistant.io/integrations/logi_circle",
   "requirements": ["logi_circle==0.2.2"],
-  "dependencies": ["ffmpeg"],
+  "dependencies": ["ffmpeg", "http"],
   "codeowners": ["@evanjd"]
 }
diff --git a/homeassistant/components/melissa/climate.py b/homeassistant/components/melissa/climate.py
index 38f4977c96abc5cab7ccd31ac74c4dc088e7cc0e..c09203c3e333e61cdafe1cf5e94560ffe98b2318 100644
--- a/homeassistant/components/melissa/climate.py
+++ b/homeassistant/components/melissa/climate.py
@@ -11,8 +11,11 @@ from homeassistant.components.climate.const import (
     HVAC_MODE_OFF,
     SUPPORT_FAN_MODE,
     SUPPORT_TARGET_TEMPERATURE,
+    FAN_AUTO,
+    FAN_HIGH,
+    FAN_MEDIUM,
+    FAN_LOW,
 )
-from homeassistant.components.fan import SPEED_HIGH, SPEED_LOW, SPEED_MEDIUM
 from homeassistant.const import ATTR_TEMPERATURE, PRECISION_WHOLE, TEMP_CELSIUS
 
 from . import DATA_MELISSA
@@ -29,7 +32,7 @@ OP_MODES = [
     HVAC_MODE_OFF,
 ]
 
-FAN_MODES = [HVAC_MODE_AUTO, SPEED_HIGH, SPEED_MEDIUM, SPEED_LOW]
+FAN_MODES = [FAN_AUTO, FAN_HIGH, FAN_MEDIUM, FAN_LOW]
 
 
 async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
@@ -200,11 +203,11 @@ class MelissaClimate(ClimateDevice):
         if fan == self._api.FAN_AUTO:
             return HVAC_MODE_AUTO
         if fan == self._api.FAN_LOW:
-            return SPEED_LOW
+            return FAN_LOW
         if fan == self._api.FAN_MEDIUM:
-            return SPEED_MEDIUM
+            return FAN_MEDIUM
         if fan == self._api.FAN_HIGH:
-            return SPEED_HIGH
+            return FAN_HIGH
         _LOGGER.warning("Fan mode %s could not be mapped to hass", fan)
         return None
 
@@ -224,10 +227,10 @@ class MelissaClimate(ClimateDevice):
         """Translate hass fan modes to melissa modes."""
         if fan == HVAC_MODE_AUTO:
             return self._api.FAN_AUTO
-        if fan == SPEED_LOW:
+        if fan == FAN_LOW:
             return self._api.FAN_LOW
-        if fan == SPEED_MEDIUM:
+        if fan == FAN_MEDIUM:
             return self._api.FAN_MEDIUM
-        if fan == SPEED_HIGH:
+        if fan == FAN_HIGH:
             return self._api.FAN_HIGH
         _LOGGER.warning("Melissa have no setting for %s fan mode", fan)
diff --git a/homeassistant/components/nsw_fuel_station/sensor.py b/homeassistant/components/nsw_fuel_station/sensor.py
index a84aa554be910c88fcba985d10f47105cdd86c23..3c900b46be039e6c01b27dee754e3582aa871168 100644
--- a/homeassistant/components/nsw_fuel_station/sensor.py
+++ b/homeassistant/components/nsw_fuel_station/sensor.py
@@ -6,7 +6,7 @@ from typing import Optional
 import voluptuous as vol
 
 import homeassistant.helpers.config_validation as cv
-from homeassistant.components.light import PLATFORM_SCHEMA
+from homeassistant.components.sensor import PLATFORM_SCHEMA
 from homeassistant.const import ATTR_ATTRIBUTION
 from homeassistant.helpers.entity import Entity
 from homeassistant.util import Throttle
diff --git a/homeassistant/components/person/manifest.json b/homeassistant/components/person/manifest.json
index cf50b8029c2e91ba5e6f98e2d5d35ed59fd783fe..afcd428d6afd76e71a8d7b26d8548740b7a9155e 100644
--- a/homeassistant/components/person/manifest.json
+++ b/homeassistant/components/person/manifest.json
@@ -4,5 +4,6 @@
   "documentation": "https://www.home-assistant.io/integrations/person",
   "requirements": [],
   "dependencies": [],
+  "after_dependencies": ["device_tracker"],
   "codeowners": []
 }
diff --git a/homeassistant/components/plant/manifest.json b/homeassistant/components/plant/manifest.json
index 721a57e782248ae845f32c5025a4da3e903b48b8..c1e009ccec3a4b795d444258508901aa964f8acc 100644
--- a/homeassistant/components/plant/manifest.json
+++ b/homeassistant/components/plant/manifest.json
@@ -3,11 +3,7 @@
   "name": "Plant",
   "documentation": "https://www.home-assistant.io/integrations/plant",
   "requirements": [],
-  "dependencies": [
-    "group",
-    "zone"
-  ],
-  "codeowners": [
-    "@ChristianKuehnel"
-  ]
+  "dependencies": ["group", "zone"],
+  "after_dependencies": ["recorder"],
+  "codeowners": ["@ChristianKuehnel"]
 }
diff --git a/homeassistant/components/point/manifest.json b/homeassistant/components/point/manifest.json
index 4c29f37e67cf72644ad246b43cb2d449007921bc..1c74052ee7e2789e6914e01983947f4ccb42f6b4 100644
--- a/homeassistant/components/point/manifest.json
+++ b/homeassistant/components/point/manifest.json
@@ -3,13 +3,7 @@
   "name": "Point",
   "config_flow": true,
   "documentation": "https://www.home-assistant.io/integrations/point",
-  "requirements": [
-    "pypoint==1.1.2"
-  ],
-  "dependencies": [
-    "webhook"
-  ],
-  "codeowners": [
-    "@fredrike"
-  ]
+  "requirements": ["pypoint==1.1.2"],
+  "dependencies": ["webhook", "http"],
+  "codeowners": ["@fredrike"]
 }
diff --git a/homeassistant/components/rachio/manifest.json b/homeassistant/components/rachio/manifest.json
index 79e3677d65e82154b056772b9a1c7be3fc2bc479..fae640f926268bfae359f4e324073a54f90ffc15 100644
--- a/homeassistant/components/rachio/manifest.json
+++ b/homeassistant/components/rachio/manifest.json
@@ -2,9 +2,7 @@
   "domain": "rachio",
   "name": "Rachio",
   "documentation": "https://www.home-assistant.io/integrations/rachio",
-  "requirements": [
-    "rachiopy==0.1.3"
-  ],
-  "dependencies": [],
+  "requirements": ["rachiopy==0.1.3"],
+  "dependencies": ["http"],
   "codeowners": []
 }
diff --git a/homeassistant/components/statistics/manifest.json b/homeassistant/components/statistics/manifest.json
index 3dab05942b947b21420c4d0e102dae64efe3b2be..17ade1283ceb7e7628e4484db2e24822b4a362d4 100644
--- a/homeassistant/components/statistics/manifest.json
+++ b/homeassistant/components/statistics/manifest.json
@@ -4,7 +4,6 @@
   "documentation": "https://www.home-assistant.io/integrations/statistics",
   "requirements": [],
   "dependencies": [],
-  "codeowners": [
-    "@fabaff"
-  ]
+  "after_dependencies": ["recorder"],
+  "codeowners": ["@fabaff"]
 }
diff --git a/homeassistant/components/telegram_bot/__init__.py b/homeassistant/components/telegram_bot/__init__.py
index d365060e20470507710559d52bfd4a4d9312d3f5..12bde6c72d849679241edf9c1b88608e1e7e8df5 100644
--- a/homeassistant/components/telegram_bot/__init__.py
+++ b/homeassistant/components/telegram_bot/__init__.py
@@ -19,7 +19,6 @@ from telegram.parsemode import ParseMode
 from telegram.utils.request import Request
 import voluptuous as vol
 
-from homeassistant.components.notify import ATTR_DATA, ATTR_MESSAGE, ATTR_TITLE
 from homeassistant.const import (
     ATTR_COMMAND,
     ATTR_LATITUDE,
@@ -35,6 +34,10 @@ from homeassistant.exceptions import TemplateError
 
 _LOGGER = logging.getLogger(__name__)
 
+ATTR_DATA = "data"
+ATTR_MESSAGE = "message"
+ATTR_TITLE = "title"
+
 ATTR_ARGS = "args"
 ATTR_AUTHENTICATION = "authentication"
 ATTR_CALLBACK_QUERY = "callback_query"
diff --git a/homeassistant/components/tts/manifest.json b/homeassistant/components/tts/manifest.json
index cb7805239777246992299cf5089d5b2a025f0715..b57d5c36112d3832f608712e2279ef13a79589df 100644
--- a/homeassistant/components/tts/manifest.json
+++ b/homeassistant/components/tts/manifest.json
@@ -2,13 +2,8 @@
   "domain": "tts",
   "name": "Tts",
   "documentation": "https://www.home-assistant.io/integrations/tts",
-  "requirements": [
-    "mutagen==1.43.0"
-  ],
-  "dependencies": [
-    "http"
-  ],
-  "codeowners": [
-    "@robbiet480"
-  ]
+  "requirements": ["mutagen==1.43.0"],
+  "dependencies": ["http"],
+  "after_dependencies": ["media_player"],
+  "codeowners": ["@robbiet480"]
 }
diff --git a/homeassistant/components/wink/manifest.json b/homeassistant/components/wink/manifest.json
index acf9c38e6322c1a343be825f93fd19c2fe7d8a16..a1bae6482927d2b8830640545a17ffbf2d169135 100644
--- a/homeassistant/components/wink/manifest.json
+++ b/homeassistant/components/wink/manifest.json
@@ -2,10 +2,7 @@
   "domain": "wink",
   "name": "Wink",
   "documentation": "https://www.home-assistant.io/integrations/wink",
-  "requirements": [
-    "pubnubsub-handler==1.0.8",
-    "python-wink==1.10.5"
-  ],
-  "dependencies": ["configurator"],
+  "requirements": ["pubnubsub-handler==1.0.8", "python-wink==1.10.5"],
+  "dependencies": ["configurator", "http"],
   "codeowners": []
 }
diff --git a/homeassistant/components/workday/binary_sensor.py b/homeassistant/components/workday/binary_sensor.py
index f95447c1e72f709e9730480e3be0092ed7599b5d..efa8b6ad77b487d50f8189712cdf57f50ce5a593 100644
--- a/homeassistant/components/workday/binary_sensor.py
+++ b/homeassistant/components/workday/binary_sensor.py
@@ -5,9 +5,8 @@ from datetime import datetime, timedelta
 import holidays
 import voluptuous as vol
 
-from homeassistant.components.sensor import PLATFORM_SCHEMA
 from homeassistant.const import CONF_NAME, WEEKDAYS
-from homeassistant.components.binary_sensor import BinarySensorDevice
+from homeassistant.components.binary_sensor import BinarySensorDevice, PLATFORM_SCHEMA
 import homeassistant.helpers.config_validation as cv
 
 _LOGGER = logging.getLogger(__name__)
diff --git a/homeassistant/components/worxlandroid/sensor.py b/homeassistant/components/worxlandroid/sensor.py
index 4e9bf0a6a4a913a4127b5f779336108e63cb51c5..ad583d6d943dbc7d694a763dfc4a2311caabeb54 100644
--- a/homeassistant/components/worxlandroid/sensor.py
+++ b/homeassistant/components/worxlandroid/sensor.py
@@ -10,7 +10,7 @@ import voluptuous as vol
 import homeassistant.helpers.config_validation as cv
 
 from homeassistant.helpers.entity import Entity
-from homeassistant.components.switch import PLATFORM_SCHEMA
+from homeassistant.components.sensor import PLATFORM_SCHEMA
 from homeassistant.const import CONF_HOST, CONF_PIN, CONF_TIMEOUT
 from homeassistant.helpers.aiohttp_client import async_get_clientsession
 
diff --git a/script/hassfest/dependencies.py b/script/hassfest/dependencies.py
index e47deb76ad5f7e15700e3398695971812f175648..42a31f206105c277986186bb63c1b853e2eb285e 100644
--- a/script/hassfest/dependencies.py
+++ b/script/hassfest/dependencies.py
@@ -16,7 +16,19 @@ def grep_dir(path: pathlib.Path, glob_pattern: str, search_pattern: str) -> Set[
             continue
 
         for match in pattern.finditer(fil.read_text()):
-            found.add(match.groups()[0])
+            integration = match.groups()[1]
+
+            if (
+                # If it's importing something from itself
+                integration == path.name
+                # Platform file
+                or (path / f"{integration}.py").exists()
+                # Dir for platform
+                or (path / integration).exists()
+            ):
+                continue
+
+            found.add(match.groups()[1])
 
     return found
 
@@ -30,19 +42,65 @@ ALLOWED_USED_COMPONENTS = {
     "hassio",
     "system_health",
     "websocket_api",
+    "automation",
+    "device_automation",
+    "zone",
+    "homeassistant",
+    "system_log",
+    "person",
+    # Discovery
+    "ssdp",
+    "discovery",
+    # Other
+    "mjpeg",  # base class, has no reqs or component to load.
 }
 
+IGNORE_VIOLATIONS = [
+    # Has same requirement, gets defaults.
+    ("sql", "recorder"),
+    # Sharing a base class
+    ("openalpr_cloud", "openalpr_local"),
+    ("lutron_caseta", "lutron"),
+    ("ffmpeg_noise", "ffmpeg_motion"),
+    # Demo
+    ("demo", "manual"),
+    ("demo", "openalpr_local"),
+    # This should become a helper method that integrations can submit data to
+    ("websocket_api", "lovelace"),
+    # Expose HA to external systems
+    "homekit",
+    "alexa",
+    "google_assistant",
+    "emulated_hue",
+    "prometheus",
+    "conversation",
+    "logbook",
+    # These should be extracted to external package
+    "pvoutput",
+    "dwd_weather_warnings",
+    # Should be rewritten to use own data fetcher
+    "scrape",
+]
+
 
 def validate_dependencies(integration: Integration):
     """Validate all dependencies."""
     # Find usage of hass.components
-    referenced = grep_dir(integration.path, "**/*.py", r"hass\.components\.(\w+)")
+    referenced = grep_dir(
+        integration.path, "**/*.py", r"(hass|homeassistant)\.components\.(\w+)"
+    )
     referenced -= ALLOWED_USED_COMPONENTS
     referenced -= set(integration.manifest["dependencies"])
     referenced -= set(integration.manifest.get("after_dependencies", []))
 
     if referenced:
         for domain in sorted(referenced):
+            if (
+                integration.domain in IGNORE_VIOLATIONS
+                or (integration.domain, domain) in IGNORE_VIOLATIONS
+            ):
+                continue
+
             integration.add_error(
                 "dependencies",
                 "Using component {} but it's not in 'dependencies' or 'after_dependencies'".format(