about summary refs log tree commit diff
path: root/nixpkgs/pkgs/servers/home-assistant
diff options
context:
space:
mode:
authorAlyssa Ross <hi@alyssa.is>2020-04-01 15:50:50 +0000
committerAlyssa Ross <hi@alyssa.is>2020-04-01 15:50:50 +0000
commit75eafe97f7df0d653bec67f3962214d7c357831f (patch)
tree09f2cc901e0e637876cbb78d192dfe2fcfef8156 /nixpkgs/pkgs/servers/home-assistant
parenta53b121bf4331497da63df3b1b7f1a7897dad146 (diff)
parenta2e06fc3423c4be53181b15c28dfbe0bcf67dd73 (diff)
downloadnixlib-75eafe97f7df0d653bec67f3962214d7c357831f.tar
nixlib-75eafe97f7df0d653bec67f3962214d7c357831f.tar.gz
nixlib-75eafe97f7df0d653bec67f3962214d7c357831f.tar.bz2
nixlib-75eafe97f7df0d653bec67f3962214d7c357831f.tar.lz
nixlib-75eafe97f7df0d653bec67f3962214d7c357831f.tar.xz
nixlib-75eafe97f7df0d653bec67f3962214d7c357831f.tar.zst
nixlib-75eafe97f7df0d653bec67f3962214d7c357831f.zip
Merge commit 'a2e06fc3423c4be53181b15c28dfbe0bcf67dd73'
Diffstat (limited to 'nixpkgs/pkgs/servers/home-assistant')
-rw-r--r--nixpkgs/pkgs/servers/home-assistant/appdaemon.nix27
-rw-r--r--nixpkgs/pkgs/servers/home-assistant/component-packages.nix1806
-rw-r--r--nixpkgs/pkgs/servers/home-assistant/default.nix20
-rw-r--r--nixpkgs/pkgs/servers/home-assistant/frontend.nix4
-rwxr-xr-xnixpkgs/pkgs/servers/home-assistant/parse-requirements.py177
-rw-r--r--nixpkgs/pkgs/servers/home-assistant/relax-importlib-metadata-pyaml.patch22
6 files changed, 1065 insertions, 991 deletions
diff --git a/nixpkgs/pkgs/servers/home-assistant/appdaemon.nix b/nixpkgs/pkgs/servers/home-assistant/appdaemon.nix
index 47d9e88999af..258e46db1990 100644
--- a/nixpkgs/pkgs/servers/home-assistant/appdaemon.nix
+++ b/nixpkgs/pkgs/servers/home-assistant/appdaemon.nix
@@ -1,18 +1,14 @@
-{ lib, python3 }:
+{ lib, python3, fetchFromGitHub }:
 
 let
   python = python3.override {
     packageOverrides = self: super: {
-
-      aiohttp = super.aiohttp.overridePythonAttrs (oldAttrs: rec {
-        version = "2.3.10";
+      bcrypt = super.bcrypt.overridePythonAttrs (oldAttrs: rec {
+        version = "3.1.4";
         src = oldAttrs.src.override {
           inherit version;
-          sha256 = "8adda6583ba438a4c70693374e10b60168663ffa6564c5c75d3c7a9055290964";
+          sha256 = "13cyrnqwkhc70rs6dg65z4yrrr3dc42fhk11804fqmci9hvimvb7";
         };
-        # TODO: remove after pinning aiohttp to a newer version
-        propagatedBuildInputs = with self; [ chardet multidict async-timeout yarl idna-ssl ];
-        doCheck = false;
       });
 
       yarl = super.yarl.overridePythonAttrs (oldAttrs: rec {
@@ -43,23 +39,26 @@ let
 
 in python.pkgs.buildPythonApplication rec {
   pname = "appdaemon";
-  version = "3.0.5";
+  version = "4.0.1";
 
-  src = python.pkgs.fetchPypi {
-    inherit pname version;
-    sha256 = "623897ce08dc2efe24d04380df36e4b7fb35c0e4007e882857d4047f0b60349d";
+  src = fetchFromGitHub {
+    owner = "home-assistant";
+    repo = "appdaemon";
+    rev = version;
+    sha256 = "13qzjv11b0c7s1c66j70qmc222a78805n10lv2svj9yyk1v4xhjv";
   };
 
   propagatedBuildInputs = with python.pkgs; [
-    daemonize astral requests sseclient websocket_client aiohttp yarl jinja2
+    daemonize astral requests websocket_client aiohttp yarl jinja2
     aiohttp-jinja2 pyyaml voluptuous feedparser iso8601 bcrypt paho-mqtt setuptools
+    deepdiff dateutil bcrypt python-socketio pid
   ];
 
   # no tests implemented
   doCheck = false;
 
   postPatch = ''
-    substituteInPlace setup.py --replace "pyyaml==5.1" "pyyaml"
+    substituteInPlace requirements.txt --replace "pyyaml==5.1" "pyyaml"
   '';
 
   meta = with lib; {
diff --git a/nixpkgs/pkgs/servers/home-assistant/component-packages.nix b/nixpkgs/pkgs/servers/home-assistant/component-packages.nix
index 275241fcd176..6b18dd30f308 100644
--- a/nixpkgs/pkgs/servers/home-assistant/component-packages.nix
+++ b/nixpkgs/pkgs/servers/home-assistant/component-packages.nix
@@ -2,900 +2,918 @@
 # Do not edit!
 
 {
-  version = "0.103.6";
+  version = "0.106.6";
   components = {
-    "abode" = ps: with ps; [  ];
-    "acer_projector" = ps: with ps; [ pyserial ];
-    "actiontec" = ps: with ps; [  ];
-    "adguard" = ps: with ps; [  ];
-    "ads" = ps: with ps; [  ];
-    "aftership" = ps: with ps; [  ];
-    "air_quality" = ps: with ps; [  ];
-    "airly" = ps: with ps; [  ];
-    "airvisual" = ps: with ps; [ pyairvisual ];
-    "aladdin_connect" = ps: with ps; [  ];
-    "alarm_control_panel" = ps: with ps; [  ];
-    "alarmdecoder" = ps: with ps; [  ];
-    "alarmdotcom" = ps: with ps; [  ];
-    "alert" = ps: with ps; [  ];
-    "alexa" = ps: with ps; [ aiohttp-cors ];
-    "almond" = ps: with ps; [ aiohttp-cors ];
-    "alpha_vantage" = ps: with ps; [  ];
-    "amazon_polly" = ps: with ps; [ boto3 ];
-    "ambiclimate" = ps: with ps; [  ];
-    "ambient_station" = ps: with ps; [  ];
-    "amcrest" = ps: with ps; [ ha-ffmpeg ];
-    "ampio" = ps: with ps; [  ];
-    "android_ip_webcam" = ps: with ps; [  ];
-    "androidtv" = ps: with ps; [  ];
-    "anel_pwrctrl" = ps: with ps; [  ];
-    "anthemav" = ps: with ps; [  ];
-    "apache_kafka" = ps: with ps; [ aiokafka ];
-    "apcupsd" = ps: with ps; [  ];
-    "api" = ps: with ps; [ aiohttp-cors ];
-    "apns" = ps: with ps; [  ];
-    "apple_tv" = ps: with ps; [ pyatv ];
-    "apprise" = ps: with ps; [ apprise ];
-    "aprs" = ps: with ps; [  ];
-    "aqualogic" = ps: with ps; [  ];
-    "aquostv" = ps: with ps; [  ];
-    "arcam_fmj" = ps: with ps; [  ];
-    "arduino" = ps: with ps; [  ];
-    "arest" = ps: with ps; [  ];
-    "arlo" = ps: with ps; [ ha-ffmpeg ];
-    "aruba" = ps: with ps; [ pexpect ];
-    "arwn" = ps: with ps; [ aiohttp-cors hbmqtt paho-mqtt ];
-    "asterisk_cdr" = ps: with ps; [  ];
-    "asterisk_mbox" = ps: with ps; [  ];
-    "asuswrt" = ps: with ps; [  ];
-    "aten_pe" = ps: with ps; [  ];
-    "atome" = ps: with ps; [  ];
-    "august" = ps: with ps; [  ];
-    "aurora" = ps: with ps; [  ];
-    "aurora_abb_powerone" = ps: with ps; [  ];
-    "auth" = ps: with ps; [ aiohttp-cors ];
-    "automatic" = ps: with ps; [ aiohttp-cors ];
-    "automation" = ps: with ps; [ aiohttp-cors ];
-    "avea" = ps: with ps; [  ];
-    "avion" = ps: with ps; [  ];
-    "awair" = ps: with ps; [  ];
-    "aws" = ps: with ps; [  ];
-    "axis" = ps: with ps; [  ];
-    "azure_event_hub" = ps: with ps; [  ];
-    "azure_service_bus" = ps: with ps; [ azure-servicebus ];
-    "baidu" = ps: with ps; [  ];
-    "bayesian" = ps: with ps; [  ];
-    "bbb_gpio" = ps: with ps; [  ];
-    "bbox" = ps: with ps; [  ];
-    "beewi_smartclim" = ps: with ps; [  ];
-    "bh1750" = ps: with ps; [  ];
-    "binary_sensor" = ps: with ps; [  ];
-    "bitcoin" = ps: with ps; [  ];
-    "bizkaibus" = ps: with ps; [  ];
-    "blackbird" = ps: with ps; [  ];
-    "blink" = ps: with ps; [  ];
-    "blinksticklight" = ps: with ps; [ BlinkStick ];
-    "blinkt" = ps: with ps; [  ];
-    "blockchain" = ps: with ps; [  ];
-    "bloomsky" = ps: with ps; [  ];
-    "bluesound" = ps: with ps; [ xmltodict ];
-    "bluetooth_le_tracker" = ps: with ps; [  ];
-    "bluetooth_tracker" = ps: with ps; [ bt_proximity ];
-    "bme280" = ps: with ps; [  ];
-    "bme680" = ps: with ps; [  ];
-    "bmw_connected_drive" = ps: with ps; [  ];
-    "bom" = ps: with ps; [  ];
-    "braviatv" = ps: with ps; [  ];
-    "broadlink" = ps: with ps; [ broadlink ];
-    "brottsplatskartan" = ps: with ps; [  ];
-    "browser" = ps: with ps; [  ];
-    "brunt" = ps: with ps; [  ];
-    "bt_home_hub_5" = ps: with ps; [  ];
-    "bt_smarthub" = ps: with ps; [  ];
-    "buienradar" = ps: with ps; [  ];
-    "caldav" = ps: with ps; [ caldav ];
-    "calendar" = ps: with ps; [ aiohttp-cors ];
-    "camera" = ps: with ps; [ aiohttp-cors ];
-    "canary" = ps: with ps; [ ha-ffmpeg ];
-    "cast" = ps: with ps; [ PyChromecast ];
-    "cert_expiry" = ps: with ps; [  ];
-    "channels" = ps: with ps; [  ];
-    "cisco_ios" = ps: with ps; [ pexpect ];
-    "cisco_mobility_express" = ps: with ps; [  ];
-    "cisco_webex_teams" = ps: with ps; [  ];
-    "ciscospark" = ps: with ps; [  ];
-    "citybikes" = ps: with ps; [  ];
-    "clementine" = ps: with ps; [  ];
-    "clickatell" = ps: with ps; [  ];
-    "clicksend" = ps: with ps; [  ];
-    "clicksend_tts" = ps: with ps; [  ];
-    "climate" = ps: with ps; [  ];
-    "cloud" = ps: with ps; [ aiohttp-cors hass-nabucasa ];
-    "cloudflare" = ps: with ps; [  ];
-    "cmus" = ps: with ps; [  ];
-    "co2signal" = ps: with ps; [  ];
-    "coinbase" = ps: with ps; [  ];
-    "coinmarketcap" = ps: with ps; [ coinmarketcap ];
-    "comed_hourly_pricing" = ps: with ps; [  ];
-    "comfoconnect" = ps: with ps; [  ];
-    "command_line" = ps: with ps; [  ];
-    "concord232" = ps: with ps; [  ];
-    "config" = ps: with ps; [ aiohttp-cors ];
-    "configurator" = ps: with ps; [  ];
-    "conversation" = ps: with ps; [ aiohttp-cors ];
-    "coolmaster" = ps: with ps; [  ];
-    "counter" = ps: with ps; [  ];
-    "cover" = ps: with ps; [  ];
-    "cppm_tracker" = ps: with ps; [  ];
-    "cpuspeed" = ps: with ps; [ py-cpuinfo ];
-    "crimereports" = ps: with ps; [  ];
-    "cups" = ps: with ps; [ pycups ];
-    "currencylayer" = ps: with ps; [  ];
-    "daikin" = ps: with ps; [  ];
-    "danfoss_air" = ps: with ps; [  ];
-    "darksky" = ps: with ps; [ python-forecastio ];
-    "datadog" = ps: with ps; [ datadog ];
-    "ddwrt" = ps: with ps; [  ];
-    "deconz" = ps: with ps; [  ];
-    "decora" = ps: with ps; [  ];
-    "decora_wifi" = ps: with ps; [  ];
-    "default_config" = ps: with ps; [ pynacl aiohttp-cors defusedxml distro hass-nabucasa netdisco sqlalchemy zeroconf ];
-    "delijn" = ps: with ps; [  ];
-    "deluge" = ps: with ps; [ deluge-client ];
-    "demo" = ps: with ps; [ aiohttp-cors ];
-    "denon" = ps: with ps; [  ];
-    "denonavr" = ps: with ps; [  ];
-    "deutsche_bahn" = ps: with ps; [  ];
-    "device_automation" = ps: with ps; [ aiohttp-cors ];
-    "device_sun_light_trigger" = ps: with ps; [  ];
-    "device_tracker" = ps: with ps; [  ];
-    "dht" = ps: with ps; [  ];
-    "dialogflow" = ps: with ps; [ aiohttp-cors ];
-    "digital_ocean" = ps: with ps; [ digital-ocean ];
-    "digitalloggers" = ps: with ps; [  ];
-    "directv" = ps: with ps; [  ];
-    "discogs" = ps: with ps; [ discogs_client ];
-    "discord" = ps: with ps; [ discordpy ];
-    "discovery" = ps: with ps; [ netdisco ];
-    "dlib_face_detect" = ps: with ps; [ face_recognition ];
-    "dlib_face_identify" = ps: with ps; [ face_recognition ];
-    "dlink" = ps: with ps; [  ];
-    "dlna_dmr" = ps: with ps; [  ];
-    "dnsip" = ps: with ps; [ aiodns ];
-    "dominos" = ps: with ps; [ aiohttp-cors ];
-    "doods" = ps: with ps; [ pillow ];
-    "doorbird" = ps: with ps; [  ];
-    "dovado" = ps: with ps; [  ];
-    "downloader" = ps: with ps; [  ];
-    "dsmr" = ps: with ps; [  ];
-    "dsmr_reader" = ps: with ps; [ aiohttp-cors hbmqtt paho-mqtt ];
-    "dte_energy_bridge" = ps: with ps; [  ];
-    "dublin_bus_transport" = ps: with ps; [  ];
-    "duckdns" = ps: with ps; [  ];
-    "duke_energy" = ps: with ps; [  ];
-    "dunehd" = ps: with ps; [  ];
-    "dwd_weather_warnings" = ps: with ps; [  ];
-    "dweet" = ps: with ps; [  ];
-    "dyson" = ps: with ps; [  ];
-    "ebox" = ps: with ps; [  ];
-    "ebusd" = ps: with ps; [  ];
-    "ecoal_boiler" = ps: with ps; [  ];
-    "ecobee" = ps: with ps; [  ];
-    "econet" = ps: with ps; [  ];
-    "ecovacs" = ps: with ps; [  ];
-    "eddystone_temperature" = ps: with ps; [ construct ];
-    "edimax" = ps: with ps; [  ];
-    "ee_brightbox" = ps: with ps; [  ];
-    "efergy" = ps: with ps; [  ];
-    "egardia" = ps: with ps; [  ];
-    "eight_sleep" = ps: with ps; [  ];
-    "eliqonline" = ps: with ps; [  ];
-    "elkm1" = ps: with ps; [  ];
-    "elv" = ps: with ps; [  ];
-    "emby" = ps: with ps; [  ];
-    "emoncms" = ps: with ps; [  ];
-    "emoncms_history" = ps: with ps; [  ];
-    "emulated_hue" = ps: with ps; [ aiohttp-cors ];
-    "emulated_roku" = ps: with ps; [  ];
-    "enigma2" = ps: with ps; [  ];
-    "enocean" = ps: with ps; [  ];
-    "enphase_envoy" = ps: with ps; [  ];
-    "entur_public_transport" = ps: with ps; [  ];
-    "environment_canada" = ps: with ps; [  ];
-    "envirophat" = ps: with ps; [  ];
-    "envisalink" = ps: with ps; [  ];
-    "ephember" = ps: with ps; [  ];
-    "epson" = ps: with ps; [  ];
-    "epsonworkforce" = ps: with ps; [  ];
-    "eq3btsmart" = ps: with ps; [ construct ];
-    "esphome" = ps: with ps; [ aioesphomeapi ];
-    "essent" = ps: with ps; [  ];
-    "etherscan" = ps: with ps; [  ];
-    "eufy" = ps: with ps; [  ];
-    "everlights" = ps: with ps; [  ];
-    "evohome" = ps: with ps; [  ];
-    "facebook" = ps: with ps; [  ];
-    "facebox" = ps: with ps; [  ];
-    "fail2ban" = ps: with ps; [  ];
-    "familyhub" = ps: with ps; [  ];
-    "fan" = ps: with ps; [  ];
-    "fastdotcom" = ps: with ps; [  ];
-    "feedreader" = ps: with ps; [  ];
-    "ffmpeg" = ps: with ps; [ ha-ffmpeg ];
-    "ffmpeg_motion" = ps: with ps; [ ha-ffmpeg ];
-    "ffmpeg_noise" = ps: with ps; [ ha-ffmpeg ];
-    "fibaro" = ps: with ps; [  ];
-    "fido" = ps: with ps; [  ];
-    "file" = ps: with ps; [  ];
-    "filesize" = ps: with ps; [  ];
-    "filter" = ps: with ps; [  ];
-    "fints" = ps: with ps; [ fints ];
-    "fitbit" = ps: with ps; [ aiohttp-cors fitbit ];
-    "fixer" = ps: with ps; [  ];
-    "fleetgo" = ps: with ps; [  ];
-    "flexit" = ps: with ps; [  ];
-    "flic" = ps: with ps; [  ];
-    "flock" = ps: with ps; [  ];
-    "flume" = ps: with ps; [  ];
-    "flunearyou" = ps: with ps; [  ];
-    "flux" = ps: with ps; [  ];
-    "flux_led" = ps: with ps; [  ];
-    "folder" = ps: with ps; [  ];
-    "folder_watcher" = ps: with ps; [ watchdog ];
-    "foobot" = ps: with ps; [  ];
-    "fortigate" = ps: with ps; [  ];
-    "fortios" = ps: with ps; [  ];
-    "foscam" = ps: with ps; [  ];
-    "foursquare" = ps: with ps; [ aiohttp-cors ];
-    "free_mobile" = ps: with ps; [  ];
-    "freebox" = ps: with ps; [  ];
-    "freedns" = ps: with ps; [  ];
-    "fritz" = ps: with ps; [ fritzconnection ];
-    "fritzbox" = ps: with ps; [  ];
-    "fritzbox_callmonitor" = ps: with ps; [ fritzconnection ];
-    "fritzbox_netmonitor" = ps: with ps; [ fritzconnection ];
-    "fritzdect" = ps: with ps; [  ];
-    "fronius" = ps: with ps; [  ];
-    "frontend" = ps: with ps; [ aiohttp-cors ];
-    "frontier_silicon" = ps: with ps; [  ];
-    "futurenow" = ps: with ps; [  ];
-    "garadget" = ps: with ps; [  ];
-    "gc100" = ps: with ps; [  ];
-    "gearbest" = ps: with ps; [  ];
-    "geizhals" = ps: with ps; [  ];
-    "generic" = ps: with ps; [  ];
-    "generic_thermostat" = ps: with ps; [  ];
-    "geniushub" = ps: with ps; [  ];
-    "geo_json_events" = ps: with ps; [  ];
-    "geo_location" = ps: with ps; [  ];
-    "geo_rss_events" = ps: with ps; [  ];
-    "geofency" = ps: with ps; [ aiohttp-cors ];
-    "geonetnz_quakes" = ps: with ps; [  ];
-    "geonetnz_volcano" = ps: with ps; [  ];
-    "github" = ps: with ps; [ PyGithub ];
-    "gitlab_ci" = ps: with ps; [ python-gitlab ];
-    "gitter" = ps: with ps; [  ];
-    "glances" = ps: with ps; [  ];
-    "gntp" = ps: with ps; [  ];
-    "goalfeed" = ps: with ps; [  ];
-    "gogogate2" = ps: with ps; [  ];
-    "google" = ps: with ps; [ google_api_python_client httplib2 oauth2client ];
-    "google_assistant" = ps: with ps; [ aiohttp-cors ];
-    "google_cloud" = ps: with ps; [ google_cloud_texttospeech ];
-    "google_domains" = ps: with ps; [  ];
-    "google_maps" = ps: with ps; [  ];
-    "google_pubsub" = ps: with ps; [ google_cloud_pubsub ];
-    "google_translate" = ps: with ps; [ gtts-token ];
-    "google_travel_time" = ps: with ps; [  ];
-    "google_wifi" = ps: with ps; [  ];
-    "gpmdp" = ps: with ps; [ websocket_client ];
-    "gpsd" = ps: with ps; [  ];
-    "gpslogger" = ps: with ps; [ aiohttp-cors ];
-    "graphite" = ps: with ps; [  ];
-    "greeneye_monitor" = ps: with ps; [  ];
-    "greenwave" = ps: with ps; [  ];
-    "group" = ps: with ps; [  ];
-    "growatt_server" = ps: with ps; [  ];
-    "gstreamer" = ps: with ps; [  ];
-    "gtfs" = ps: with ps; [  ];
-    "habitica" = ps: with ps; [  ];
-    "hangouts" = ps: with ps; [  ];
-    "harman_kardon_avr" = ps: with ps; [  ];
-    "harmony" = ps: with ps; [  ];
-    "hassio" = ps: with ps; [ aiohttp-cors ];
-    "haveibeenpwned" = ps: with ps; [  ];
-    "hddtemp" = ps: with ps; [  ];
-    "hdmi_cec" = ps: with ps; [  ];
-    "heatmiser" = ps: with ps; [  ];
-    "heos" = ps: with ps; [  ];
-    "here_travel_time" = ps: with ps; [  ];
-    "hikvision" = ps: with ps; [  ];
-    "hikvisioncam" = ps: with ps; [  ];
-    "hisense_aehw4a1" = ps: with ps; [  ];
-    "history" = ps: with ps; [ aiohttp-cors sqlalchemy ];
-    "history_graph" = ps: with ps; [ aiohttp-cors sqlalchemy ];
-    "history_stats" = ps: with ps; [ aiohttp-cors sqlalchemy ];
-    "hitron_coda" = ps: with ps; [  ];
-    "hive" = ps: with ps; [  ];
-    "hlk_sw16" = ps: with ps; [  ];
-    "homeassistant" = ps: with ps; [  ];
-    "homekit" = ps: with ps; [  ];
-    "homekit_controller" = ps: with ps; [  ];
-    "homematic" = ps: with ps; [ pyhomematic ];
-    "homematicip_cloud" = ps: with ps; [  ];
-    "homeworks" = ps: with ps; [  ];
-    "honeywell" = ps: with ps; [  ];
-    "hook" = ps: with ps; [  ];
-    "horizon" = ps: with ps; [  ];
-    "hp_ilo" = ps: with ps; [  ];
-    "html5" = ps: with ps; [ aiohttp-cors pywebpush ];
-    "http" = ps: with ps; [ aiohttp-cors ];
-    "htu21d" = ps: with ps; [  ];
-    "huawei_lte" = ps: with ps; [ stringcase ];
-    "huawei_router" = ps: with ps; [  ];
-    "hue" = ps: with ps; [ aiohue ];
-    "hunterdouglas_powerview" = ps: with ps; [  ];
-    "hydrawise" = ps: with ps; [  ];
-    "hyperion" = ps: with ps; [  ];
-    "ialarm" = ps: with ps; [  ];
-    "iaqualink" = ps: with ps; [  ];
-    "icloud" = ps: with ps; [ pyicloud ];
-    "idteck_prox" = ps: with ps; [  ];
-    "ifttt" = ps: with ps; [ aiohttp-cors pyfttt ];
-    "iglo" = ps: with ps; [  ];
-    "ign_sismologia" = ps: with ps; [  ];
-    "ihc" = ps: with ps; [ defusedxml ];
-    "image_processing" = ps: with ps; [ aiohttp-cors ];
-    "imap" = ps: with ps; [  ];
-    "imap_email_content" = ps: with ps; [  ];
-    "incomfort" = ps: with ps; [  ];
-    "influxdb" = ps: with ps; [ influxdb ];
-    "input_boolean" = ps: with ps; [  ];
-    "input_datetime" = ps: with ps; [  ];
-    "input_number" = ps: with ps; [  ];
-    "input_select" = ps: with ps; [  ];
-    "input_text" = ps: with ps; [  ];
-    "insteon" = ps: with ps; [  ];
-    "integration" = ps: with ps; [  ];
-    "intent" = ps: with ps; [ aiohttp-cors ];
-    "intent_script" = ps: with ps; [  ];
-    "ios" = ps: with ps; [ aiohttp-cors zeroconf ];
-    "iota" = ps: with ps; [  ];
-    "iperf3" = ps: with ps; [  ];
-    "ipma" = ps: with ps; [  ];
-    "iqvia" = ps: with ps; [ numpy ];
-    "irish_rail_transport" = ps: with ps; [  ];
-    "islamic_prayer_times" = ps: with ps; [  ];
-    "iss" = ps: with ps; [  ];
-    "isy994" = ps: with ps; [  ];
-    "itach" = ps: with ps; [  ];
-    "itunes" = ps: with ps; [  ];
-    "izone" = ps: with ps; [  ];
-    "jewish_calendar" = ps: with ps; [  ];
-    "joaoapps_join" = ps: with ps; [  ];
-    "juicenet" = ps: with ps; [  ];
-    "kaiterra" = ps: with ps; [  ];
-    "kankun" = ps: with ps; [  ];
-    "keba" = ps: with ps; [  ];
-    "keenetic_ndms2" = ps: with ps; [  ];
-    "keyboard" = ps: with ps; [  ];
-    "keyboard_remote" = ps: with ps; [ evdev ];
-    "kira" = ps: with ps; [  ];
-    "kiwi" = ps: with ps; [  ];
-    "knx" = ps: with ps; [  ];
-    "kodi" = ps: with ps; [ jsonrpc-async jsonrpc-websocket ];
-    "konnected" = ps: with ps; [ aiohttp-cors ];
-    "kwb" = ps: with ps; [  ];
-    "lacrosse" = ps: with ps; [  ];
-    "lametric" = ps: with ps; [  ];
-    "lannouncer" = ps: with ps; [  ];
-    "lastfm" = ps: with ps; [ pylast ];
-    "launch_library" = ps: with ps; [  ];
-    "lcn" = ps: with ps; [  ];
-    "lg_netcast" = ps: with ps; [  ];
-    "lg_soundbar" = ps: with ps; [  ];
-    "life360" = ps: with ps; [  ];
-    "lifx" = ps: with ps; [ aiolifx aiolifx-effects ];
-    "lifx_cloud" = ps: with ps; [  ];
-    "lifx_legacy" = ps: with ps; [  ];
-    "light" = ps: with ps; [  ];
-    "lightwave" = ps: with ps; [  ];
-    "limitlessled" = ps: with ps; [ limitlessled ];
-    "linksys_smart" = ps: with ps; [  ];
-    "linky" = ps: with ps; [  ];
-    "linode" = ps: with ps; [ linode-api ];
-    "linux_battery" = ps: with ps; [ batinfo ];
-    "lirc" = ps: with ps; [  ];
-    "litejet" = ps: with ps; [  ];
-    "liveboxplaytv" = ps: with ps; [  ];
-    "llamalab_automate" = ps: with ps; [  ];
-    "local_file" = ps: with ps; [  ];
-    "locative" = ps: with ps; [ aiohttp-cors ];
-    "lock" = ps: with ps; [  ];
-    "lockitron" = ps: with ps; [  ];
-    "logbook" = ps: with ps; [ aiohttp-cors sqlalchemy ];
-    "logentries" = ps: with ps; [  ];
-    "logger" = ps: with ps; [  ];
-    "logi_circle" = ps: with ps; [ ha-ffmpeg ];
-    "london_air" = ps: with ps; [  ];
-    "london_underground" = ps: with ps; [  ];
-    "loopenergy" = ps: with ps; [  ];
-    "lovelace" = ps: with ps; [  ];
-    "luci" = ps: with ps; [  ];
-    "luftdaten" = ps: with ps; [ luftdaten ];
-    "lupusec" = ps: with ps; [  ];
-    "lutron" = ps: with ps; [  ];
-    "lutron_caseta" = ps: with ps; [  ];
-    "lw12wifi" = ps: with ps; [  ];
-    "lyft" = ps: with ps; [  ];
-    "magicseaweed" = ps: with ps; [  ];
-    "mailbox" = ps: with ps; [ aiohttp-cors ];
-    "mailgun" = ps: with ps; [ aiohttp-cors ];
-    "manual" = ps: with ps; [  ];
-    "manual_mqtt" = ps: with ps; [ aiohttp-cors hbmqtt paho-mqtt ];
-    "map" = ps: with ps; [ aiohttp-cors ];
-    "marytts" = ps: with ps; [  ];
-    "mastodon" = ps: with ps; [  ];
-    "matrix" = ps: with ps; [ matrix-client ];
-    "maxcube" = ps: with ps; [  ];
-    "mcp23017" = ps: with ps; [  ];
-    "media_extractor" = ps: with ps; [ aiohttp-cors youtube-dl-light ];
-    "media_player" = ps: with ps; [ aiohttp-cors ];
-    "mediaroom" = ps: with ps; [  ];
-    "melissa" = ps: with ps; [  ];
-    "meraki" = ps: with ps; [ aiohttp-cors ];
-    "message_bird" = ps: with ps; [  ];
-    "met" = ps: with ps; [  ];
-    "meteo_france" = ps: with ps; [  ];
-    "meteoalarm" = ps: with ps; [  ];
-    "metoffice" = ps: with ps; [  ];
-    "mfi" = ps: with ps; [  ];
-    "mhz19" = ps: with ps; [  ];
-    "microsoft" = ps: with ps; [  ];
-    "microsoft_face" = ps: with ps; [ aiohttp-cors ];
-    "microsoft_face_detect" = ps: with ps; [ aiohttp-cors ];
-    "microsoft_face_identify" = ps: with ps; [ aiohttp-cors ];
-    "miflora" = ps: with ps; [  ];
-    "mikrotik" = ps: with ps; [  ];
-    "mill" = ps: with ps; [  ];
-    "min_max" = ps: with ps; [  ];
-    "minio" = ps: with ps; [ minio ];
-    "mitemp_bt" = ps: with ps; [  ];
-    "mjpeg" = ps: with ps; [  ];
-    "mobile_app" = ps: with ps; [ pynacl aiohttp-cors ];
-    "mochad" = ps: with ps; [  ];
-    "modbus" = ps: with ps; [  ];
-    "modem_callerid" = ps: with ps; [  ];
-    "mold_indicator" = ps: with ps; [  ];
-    "monoprice" = ps: with ps; [  ];
-    "moon" = ps: with ps; [  ];
-    "mopar" = ps: with ps; [  ];
-    "mpchc" = ps: with ps; [  ];
-    "mpd" = ps: with ps; [ mpd2 ];
-    "mqtt" = ps: with ps; [ aiohttp-cors hbmqtt paho-mqtt ];
-    "mqtt_eventstream" = ps: with ps; [ aiohttp-cors hbmqtt paho-mqtt ];
-    "mqtt_json" = ps: with ps; [ aiohttp-cors hbmqtt paho-mqtt ];
-    "mqtt_room" = ps: with ps; [ aiohttp-cors hbmqtt paho-mqtt ];
-    "mqtt_statestream" = ps: with ps; [ aiohttp-cors hbmqtt paho-mqtt ];
-    "msteams" = ps: with ps; [  ];
-    "mvglive" = ps: with ps; [ PyMVGLive ];
-    "mychevy" = ps: with ps; [  ];
-    "mycroft" = ps: with ps; [  ];
-    "myq" = ps: with ps; [  ];
-    "mysensors" = ps: with ps; [  ];
-    "mystrom" = ps: with ps; [ aiohttp-cors ];
-    "mythicbeastsdns" = ps: with ps; [  ];
-    "n26" = ps: with ps; [  ];
-    "nad" = ps: with ps; [  ];
-    "namecheapdns" = ps: with ps; [ defusedxml ];
-    "nanoleaf" = ps: with ps; [  ];
-    "neato" = ps: with ps; [ pybotvac ];
-    "nederlandse_spoorwegen" = ps: with ps; [  ];
-    "nello" = ps: with ps; [  ];
-    "ness_alarm" = ps: with ps; [  ];
-    "nest" = ps: with ps; [  ];
-    "netatmo" = ps: with ps; [ aiohttp-cors pyatmo ];
-    "netdata" = ps: with ps; [  ];
-    "netgear" = ps: with ps; [  ];
-    "netgear_lte" = ps: with ps; [  ];
-    "netio" = ps: with ps; [ aiohttp-cors ];
-    "neurio_energy" = ps: with ps; [  ];
-    "nextbus" = ps: with ps; [  ];
-    "nfandroidtv" = ps: with ps; [  ];
-    "niko_home_control" = ps: with ps; [  ];
-    "nilu" = ps: with ps; [  ];
-    "nissan_leaf" = ps: with ps; [  ];
-    "nmap_tracker" = ps: with ps; [  ];
-    "nmbs" = ps: with ps; [  ];
-    "no_ip" = ps: with ps; [  ];
-    "noaa_tides" = ps: with ps; [  ];
-    "norway_air" = ps: with ps; [  ];
-    "notify" = ps: with ps; [  ];
-    "notion" = ps: with ps; [  ];
-    "nsw_fuel_station" = ps: with ps; [  ];
-    "nsw_rural_fire_service_feed" = ps: with ps; [  ];
-    "nuheat" = ps: with ps; [  ];
-    "nuimo_controller" = ps: with ps; [  ];
-    "nuki" = ps: with ps; [  ];
-    "nut" = ps: with ps; [  ];
-    "nws" = ps: with ps; [  ];
-    "nx584" = ps: with ps; [  ];
-    "nzbget" = ps: with ps; [  ];
-    "oasa_telematics" = ps: with ps; [  ];
-    "obihai" = ps: with ps; [  ];
-    "octoprint" = ps: with ps; [  ];
-    "oem" = ps: with ps; [  ];
-    "ohmconnect" = ps: with ps; [ defusedxml ];
-    "ombi" = ps: with ps; [  ];
-    "onboarding" = ps: with ps; [ aiohttp-cors ];
-    "onewire" = ps: with ps; [  ];
-    "onkyo" = ps: with ps; [ onkyo-eiscp ];
-    "onvif" = ps: with ps; [ ha-ffmpeg ];
-    "openalpr_cloud" = ps: with ps; [  ];
-    "openalpr_local" = ps: with ps; [  ];
-    "opencv" = ps: with ps; [ numpy ];
-    "openevse" = ps: with ps; [  ];
-    "openexchangerates" = ps: with ps; [  ];
-    "opengarage" = ps: with ps; [  ];
-    "openhardwaremonitor" = ps: with ps; [  ];
-    "openhome" = ps: with ps; [  ];
-    "opensensemap" = ps: with ps; [  ];
-    "opensky" = ps: with ps; [  ];
-    "opentherm_gw" = ps: with ps; [  ];
-    "openuv" = ps: with ps; [  ];
-    "openweathermap" = ps: with ps; [ pyowm ];
-    "opple" = ps: with ps; [  ];
-    "orangepi_gpio" = ps: with ps; [  ];
-    "oru" = ps: with ps; [  ];
-    "orvibo" = ps: with ps; [  ];
-    "osramlightify" = ps: with ps; [  ];
-    "otp" = ps: with ps; [ pyotp ];
-    "owlet" = ps: with ps; [  ];
-    "owntracks" = ps: with ps; [ pynacl aiohttp-cors ];
-    "panasonic_bluray" = ps: with ps; [  ];
-    "panasonic_viera" = ps: with ps; [ wakeonlan ];
-    "pandora" = ps: with ps; [ pexpect ];
-    "panel_custom" = ps: with ps; [ aiohttp-cors ];
-    "panel_iframe" = ps: with ps; [ aiohttp-cors ];
-    "pcal9535a" = ps: with ps; [  ];
-    "pencom" = ps: with ps; [  ];
-    "persistent_notification" = ps: with ps; [  ];
-    "person" = ps: with ps; [  ];
-    "philips_js" = ps: with ps; [  ];
-    "pi_hole" = ps: with ps; [  ];
-    "picotts" = ps: with ps; [  ];
-    "piglow" = ps: with ps; [  ];
-    "pilight" = ps: with ps; [  ];
-    "ping" = ps: with ps; [  ];
-    "pioneer" = ps: with ps; [  ];
-    "pjlink" = ps: with ps; [  ];
-    "plaato" = ps: with ps; [ aiohttp-cors ];
-    "plant" = ps: with ps; [  ];
-    "plex" = ps: with ps; [ aiohttp-cors ];
-    "plugwise" = ps: with ps; [  ];
-    "plum_lightpad" = ps: with ps; [  ];
-    "pocketcasts" = ps: with ps; [  ];
-    "point" = ps: with ps; [ aiohttp-cors ];
-    "postnl" = ps: with ps; [  ];
-    "prezzibenzina" = ps: with ps; [  ];
-    "proliphix" = ps: with ps; [  ];
-    "prometheus" = ps: with ps; [ aiohttp-cors prometheus_client ];
-    "prowl" = ps: with ps; [  ];
-    "proximity" = ps: with ps; [  ];
-    "proxmoxve" = ps: with ps; [  ];
-    "proxy" = ps: with ps; [ pillow ];
-    "ps4" = ps: with ps; [  ];
-    "ptvsd" = ps: with ps; [  ];
-    "pulseaudio_loopback" = ps: with ps; [  ];
-    "push" = ps: with ps; [ aiohttp-cors ];
-    "pushbullet" = ps: with ps; [ pushbullet ];
-    "pushetta" = ps: with ps; [  ];
-    "pushover" = ps: with ps; [ python-pushover ];
-    "pushsafer" = ps: with ps; [  ];
-    "pvoutput" = ps: with ps; [  ];
-    "pyload" = ps: with ps; [  ];
-    "python_script" = ps: with ps; [ restrictedpython ];
-    "qbittorrent" = ps: with ps; [  ];
-    "qld_bushfire" = ps: with ps; [  ];
-    "qnap" = ps: with ps; [  ];
-    "qrcode" = ps: with ps; [ pillow ];
-    "quantum_gateway" = ps: with ps; [  ];
-    "qwikswitch" = ps: with ps; [  ];
-    "rachio" = ps: with ps; [  ];
-    "radarr" = ps: with ps; [  ];
-    "radiotherm" = ps: with ps; [  ];
-    "rainbird" = ps: with ps; [  ];
-    "raincloud" = ps: with ps; [  ];
-    "rainforest_eagle" = ps: with ps; [  ];
-    "rainmachine" = ps: with ps; [  ];
-    "random" = ps: with ps; [  ];
-    "raspihats" = ps: with ps; [  ];
-    "raspyrfm" = ps: with ps; [  ];
-    "recollect_waste" = ps: with ps; [  ];
-    "recorder" = ps: with ps; [ sqlalchemy ];
-    "recswitch" = ps: with ps; [  ];
-    "reddit" = ps: with ps; [ praw ];
-    "rejseplanen" = ps: with ps; [  ];
-    "remember_the_milk" = ps: with ps; [ httplib2 ];
-    "remote" = ps: with ps; [  ];
-    "remote_rpi_gpio" = ps: with ps; [  ];
-    "repetier" = ps: with ps; [  ];
-    "rest" = ps: with ps; [  ];
-    "rest_command" = ps: with ps; [  ];
-    "rflink" = ps: with ps; [  ];
-    "rfxtrx" = ps: with ps; [  ];
-    "ring" = ps: with ps; [ ha-ffmpeg ];
-    "ripple" = ps: with ps; [  ];
-    "rmvtransport" = ps: with ps; [  ];
-    "rocketchat" = ps: with ps; [  ];
-    "roku" = ps: with ps; [  ];
-    "roomba" = ps: with ps; [  ];
-    "route53" = ps: with ps; [ boto3 ];
-    "rova" = ps: with ps; [  ];
-    "rpi_camera" = ps: with ps; [  ];
-    "rpi_gpio" = ps: with ps; [  ];
-    "rpi_gpio_pwm" = ps: with ps; [  ];
-    "rpi_pfio" = ps: with ps; [  ];
-    "rpi_rf" = ps: with ps; [  ];
-    "rss_feed_template" = ps: with ps; [ aiohttp-cors ];
-    "rtorrent" = ps: with ps; [  ];
-    "russound_rio" = ps: with ps; [  ];
-    "russound_rnet" = ps: with ps; [  ];
-    "sabnzbd" = ps: with ps; [  ];
-    "saj" = ps: with ps; [  ];
-    "samsungtv" = ps: with ps; [ wakeonlan ];
-    "satel_integra" = ps: with ps; [  ];
-    "scene" = ps: with ps; [  ];
-    "scrape" = ps: with ps; [ beautifulsoup4 ];
-    "script" = ps: with ps; [  ];
-    "scsgate" = ps: with ps; [  ];
-    "season" = ps: with ps; [ ephem ];
-    "sendgrid" = ps: with ps; [  ];
-    "sense" = ps: with ps; [  ];
-    "sensehat" = ps: with ps; [  ];
-    "sensibo" = ps: with ps; [  ];
-    "sensor" = ps: with ps; [  ];
-    "serial" = ps: with ps; [ pyserial-asyncio ];
-    "serial_pm" = ps: with ps; [  ];
-    "sesame" = ps: with ps; [  ];
-    "seven_segments" = ps: with ps; [ pillow ];
-    "seventeentrack" = ps: with ps; [  ];
-    "shell_command" = ps: with ps; [  ];
-    "shiftr" = ps: with ps; [ paho-mqtt ];
-    "shodan" = ps: with ps; [ shodan ];
-    "shopping_list" = ps: with ps; [ aiohttp-cors ];
-    "sht31" = ps: with ps; [  ];
-    "sigfox" = ps: with ps; [  ];
-    "simplepush" = ps: with ps; [  ];
-    "simplisafe" = ps: with ps; [  ];
-    "simulated" = ps: with ps; [  ];
-    "sinch" = ps: with ps; [  ];
-    "sisyphus" = ps: with ps; [  ];
-    "sky_hub" = ps: with ps; [  ];
-    "skybeacon" = ps: with ps; [  ];
-    "skybell" = ps: with ps; [  ];
-    "slack" = ps: with ps; [  ];
-    "sleepiq" = ps: with ps; [  ];
-    "slide" = ps: with ps; [  ];
-    "sma" = ps: with ps; [  ];
-    "smappee" = ps: with ps; [  ];
-    "smarthab" = ps: with ps; [  ];
-    "smartthings" = ps: with ps; [ aiohttp-cors ];
-    "smarty" = ps: with ps; [  ];
-    "smhi" = ps: with ps; [  ];
-    "smtp" = ps: with ps; [  ];
-    "snapcast" = ps: with ps; [ snapcast ];
-    "snips" = ps: with ps; [ aiohttp-cors hbmqtt paho-mqtt ];
-    "snmp" = ps: with ps; [ pysnmp ];
-    "sochain" = ps: with ps; [  ];
-    "socialblade" = ps: with ps; [  ];
-    "solaredge" = ps: with ps; [ stringcase ];
-    "solaredge_local" = ps: with ps; [  ];
-    "solarlog" = ps: with ps; [  ];
-    "solax" = ps: with ps; [  ];
-    "soma" = ps: with ps; [  ];
-    "somfy" = ps: with ps; [ aiohttp-cors ];
-    "somfy_mylink" = ps: with ps; [  ];
-    "sonarr" = ps: with ps; [  ];
-    "songpal" = ps: with ps; [  ];
-    "sonos" = ps: with ps; [ pysonos ];
-    "sony_projector" = ps: with ps; [  ];
-    "soundtouch" = ps: with ps; [ libsoundtouch ];
-    "spaceapi" = ps: with ps; [ aiohttp-cors ];
-    "spc" = ps: with ps; [  ];
-    "speedtestdotnet" = ps: with ps; [ speedtest-cli ];
-    "spider" = ps: with ps; [  ];
-    "splunk" = ps: with ps; [  ];
-    "spotcrime" = ps: with ps; [  ];
-    "spotify" = ps: with ps; [ aiohttp-cors ];
-    "sql" = ps: with ps; [ sqlalchemy ];
-    "squeezebox" = ps: with ps; [  ];
-    "ssdp" = ps: with ps; [ defusedxml netdisco ];
-    "starline" = ps: with ps; [  ];
-    "starlingbank" = ps: with ps; [  ];
-    "startca" = ps: with ps; [ xmltodict ];
-    "statistics" = ps: with ps; [  ];
-    "statsd" = ps: with ps; [ statsd ];
-    "steam_online" = ps: with ps; [  ];
-    "stiebel_eltron" = ps: with ps; [  ];
-    "stream" = ps: with ps; [ aiohttp-cors av ];
-    "streamlabswater" = ps: with ps; [  ];
-    "stt" = ps: with ps; [ aiohttp-cors ];
-    "suez_water" = ps: with ps; [  ];
-    "sun" = ps: with ps; [  ];
-    "supervisord" = ps: with ps; [  ];
-    "supla" = ps: with ps; [  ];
-    "swiss_hydrological_data" = ps: with ps; [  ];
-    "swiss_public_transport" = ps: with ps; [  ];
-    "swisscom" = ps: with ps; [  ];
-    "switch" = ps: with ps; [  ];
-    "switchbot" = ps: with ps; [  ];
-    "switcher_kis" = ps: with ps; [  ];
-    "switchmate" = ps: with ps; [  ];
-    "syncthru" = ps: with ps; [  ];
-    "synology" = ps: with ps; [  ];
-    "synology_chat" = ps: with ps; [  ];
-    "synology_srm" = ps: with ps; [  ];
-    "synologydsm" = ps: with ps; [  ];
-    "syslog" = ps: with ps; [  ];
-    "system_health" = ps: with ps; [ aiohttp-cors ];
-    "system_log" = ps: with ps; [ aiohttp-cors ];
-    "systemmonitor" = ps: with ps; [ psutil ];
-    "tado" = ps: with ps; [  ];
-    "tahoma" = ps: with ps; [  ];
-    "tank_utility" = ps: with ps; [  ];
-    "tapsaff" = ps: with ps; [  ];
-    "tautulli" = ps: with ps; [  ];
-    "tcp" = ps: with ps; [  ];
-    "ted5000" = ps: with ps; [ xmltodict ];
-    "teksavvy" = ps: with ps; [  ];
-    "telegram" = ps: with ps; [ pysocks aiohttp-cors python-telegram-bot ];
-    "telegram_bot" = ps: with ps; [ pysocks aiohttp-cors python-telegram-bot ];
-    "tellduslive" = ps: with ps; [  ];
-    "tellstick" = ps: with ps; [  ];
-    "telnet" = ps: with ps; [  ];
-    "temper" = ps: with ps; [  ];
-    "template" = ps: with ps; [  ];
-    "tensorflow" = ps: with ps; [ numpy pillow protobuf tensorflow ];
-    "tesla" = ps: with ps; [  ];
-    "tfiac" = ps: with ps; [  ];
-    "thermoworks_smoke" = ps: with ps; [ stringcase ];
-    "thethingsnetwork" = ps: with ps; [  ];
-    "thingspeak" = ps: with ps; [  ];
-    "thinkingcleaner" = ps: with ps; [  ];
-    "thomson" = ps: with ps; [  ];
-    "threshold" = ps: with ps; [  ];
-    "tibber" = ps: with ps; [  ];
-    "tikteck" = ps: with ps; [  ];
-    "tile" = ps: with ps; [  ];
-    "time_date" = ps: with ps; [  ];
-    "timer" = ps: with ps; [  ];
-    "tod" = ps: with ps; [  ];
-    "todoist" = ps: with ps; [ todoist ];
-    "tof" = ps: with ps; [  ];
-    "tomato" = ps: with ps; [  ];
-    "toon" = ps: with ps; [  ];
-    "torque" = ps: with ps; [ aiohttp-cors ];
-    "totalconnect" = ps: with ps; [  ];
-    "touchline" = ps: with ps; [  ];
-    "tplink" = ps: with ps; [  ];
-    "tplink_lte" = ps: with ps; [  ];
-    "traccar" = ps: with ps; [ aiohttp-cors stringcase ];
-    "trackr" = ps: with ps; [  ];
-    "tradfri" = ps: with ps; [  ];
-    "trafikverket_train" = ps: with ps; [  ];
-    "trafikverket_weatherstation" = ps: with ps; [  ];
-    "transmission" = ps: with ps; [ transmissionrpc ];
-    "transport_nsw" = ps: with ps; [  ];
-    "travisci" = ps: with ps; [  ];
-    "trend" = ps: with ps; [ numpy ];
-    "tts" = ps: with ps; [ aiohttp-cors mutagen ];
-    "tuya" = ps: with ps; [  ];
-    "twentemilieu" = ps: with ps; [  ];
-    "twilio" = ps: with ps; [ aiohttp-cors twilio ];
-    "twilio_call" = ps: with ps; [ aiohttp-cors twilio ];
-    "twilio_sms" = ps: with ps; [ aiohttp-cors twilio ];
-    "twitch" = ps: with ps; [  ];
-    "twitter" = ps: with ps; [  ];
-    "ubee" = ps: with ps; [  ];
-    "ubus" = ps: with ps; [  ];
-    "ue_smart_radio" = ps: with ps; [  ];
-    "uk_transport" = ps: with ps; [  ];
-    "unifi" = ps: with ps; [ aiounifi ];
-    "unifi_direct" = ps: with ps; [ pexpect ];
-    "unifiled" = ps: with ps; [  ];
-    "universal" = ps: with ps; [  ];
-    "upc_connect" = ps: with ps; [  ];
-    "upcloud" = ps: with ps; [  ];
-    "updater" = ps: with ps; [ distro ];
-    "upnp" = ps: with ps; [  ];
-    "uptime" = ps: with ps; [  ];
-    "uptimerobot" = ps: with ps; [  ];
-    "uscis" = ps: with ps; [  ];
-    "usgs_earthquakes_feed" = ps: with ps; [  ];
-    "utility_meter" = ps: with ps; [  ];
-    "uvc" = ps: with ps; [  ];
-    "vacuum" = ps: with ps; [  ];
-    "vallox" = ps: with ps; [  ];
-    "vasttrafik" = ps: with ps; [  ];
-    "velbus" = ps: with ps; [  ];
-    "velux" = ps: with ps; [  ];
-    "venstar" = ps: with ps; [  ];
-    "vera" = ps: with ps; [  ];
-    "verisure" = ps: with ps; [  ];
-    "versasense" = ps: with ps; [  ];
-    "version" = ps: with ps; [ pyhaversion ];
-    "vesync" = ps: with ps; [  ];
-    "viaggiatreno" = ps: with ps; [  ];
-    "vicare" = ps: with ps; [  ];
-    "vivotek" = ps: with ps; [  ];
-    "vizio" = ps: with ps; [  ];
-    "vlc" = ps: with ps; [ python-vlc ];
-    "vlc_telnet" = ps: with ps; [  ];
-    "voicerss" = ps: with ps; [  ];
-    "volkszaehler" = ps: with ps; [  ];
-    "volumio" = ps: with ps; [  ];
-    "volvooncall" = ps: with ps; [  ];
-    "vultr" = ps: with ps; [ vultr ];
-    "w800rf32" = ps: with ps; [  ];
-    "wake_on_lan" = ps: with ps; [ wakeonlan ];
-    "waqi" = ps: with ps; [  ];
-    "water_heater" = ps: with ps; [  ];
-    "waterfurnace" = ps: with ps; [  ];
-    "watson_iot" = ps: with ps; [  ];
-    "watson_tts" = ps: with ps; [  ];
-    "waze_travel_time" = ps: with ps; [ WazeRouteCalculator ];
-    "weather" = ps: with ps; [  ];
-    "webhook" = ps: with ps; [ aiohttp-cors ];
-    "weblink" = ps: with ps; [  ];
-    "webostv" = ps: with ps; [ websockets ];
-    "websocket_api" = ps: with ps; [ aiohttp-cors ];
-    "wemo" = ps: with ps; [  ];
-    "whois" = ps: with ps; [  ];
-    "wink" = ps: with ps; [  ];
-    "wirelesstag" = ps: with ps; [  ];
-    "withings" = ps: with ps; [ aiohttp-cors ];
-    "wled" = ps: with ps; [  ];
-    "workday" = ps: with ps; [ holidays ];
-    "worldclock" = ps: with ps; [  ];
-    "worldtidesinfo" = ps: with ps; [  ];
-    "worxlandroid" = ps: with ps; [  ];
-    "wsdot" = ps: with ps; [  ];
-    "wunderground" = ps: with ps; [  ];
-    "wunderlist" = ps: with ps; [  ];
-    "wwlln" = ps: with ps; [  ];
-    "x10" = ps: with ps; [  ];
-    "xbox_live" = ps: with ps; [  ];
-    "xeoma" = ps: with ps; [  ];
-    "xfinity" = ps: with ps; [  ];
-    "xiaomi" = ps: with ps; [ ha-ffmpeg ];
-    "xiaomi_aqara" = ps: with ps; [  ];
-    "xiaomi_miio" = ps: with ps; [ construct ];
-    "xiaomi_tv" = ps: with ps; [  ];
-    "xmpp" = ps: with ps; [ slixmpp ];
-    "xs1" = ps: with ps; [  ];
-    "yale_smart_alarm" = ps: with ps; [  ];
-    "yamaha" = ps: with ps; [  ];
-    "yamaha_musiccast" = ps: with ps; [  ];
-    "yandex_transport" = ps: with ps; [  ];
-    "yandextts" = ps: with ps; [  ];
-    "yeelight" = ps: with ps; [  ];
-    "yeelightsunflower" = ps: with ps; [  ];
-    "yessssms" = ps: with ps; [  ];
-    "yi" = ps: with ps; [ aioftp ha-ffmpeg ];
-    "yr" = ps: with ps; [ xmltodict ];
-    "yweather" = ps: with ps; [ yahooweather ];
-    "zabbix" = ps: with ps; [  ];
-    "zamg" = ps: with ps; [  ];
-    "zengge" = ps: with ps; [  ];
-    "zeroconf" = ps: with ps; [ aiohttp-cors zeroconf ];
-    "zestimate" = ps: with ps; [ xmltodict ];
-    "zha" = ps: with ps; [ zha-quirks zigpy-deconz zigpy ];
-    "zhong_hong" = ps: with ps; [  ];
-    "zigbee" = ps: with ps; [  ];
-    "ziggo_mediabox_xl" = ps: with ps; [  ];
-    "zone" = ps: with ps; [  ];
-    "zoneminder" = ps: with ps; [ zm-py ];
-    "zwave" = ps: with ps; [ homeassistant-pyozw pydispatcher ];
+    "abode" = ps: with ps; [ ]; # missing inputs: abodepy
+    "acer_projector" = ps: with ps; [ pyserial];
+    "actiontec" = ps: with ps; [ ];
+    "adguard" = ps: with ps; [ ]; # missing inputs: adguardhome
+    "ads" = ps: with ps; [ ]; # missing inputs: pyads
+    "aftership" = ps: with ps; [ ]; # missing inputs: pyaftership
+    "air_quality" = ps: with ps; [ ];
+    "airly" = ps: with ps; [ ]; # missing inputs: airly
+    "airvisual" = ps: with ps; [ pyairvisual];
+    "aladdin_connect" = ps: with ps; [ ]; # missing inputs: aladdin_connect
+    "alarm_control_panel" = ps: with ps; [ ];
+    "alarmdecoder" = ps: with ps; [ ]; # missing inputs: alarmdecoder
+    "alarmdotcom" = ps: with ps; [ ]; # missing inputs: pyalarmdotcom
+    "alert" = ps: with ps; [ ];
+    "alexa" = ps: with ps; [ aiohttp-cors];
+    "almond" = ps: with ps; [ aiohttp-cors]; # missing inputs: pyalmond
+    "alpha_vantage" = ps: with ps; [ ]; # missing inputs: alpha_vantage
+    "amazon_polly" = ps: with ps; [ boto3];
+    "ambiclimate" = ps: with ps; [ aiohttp-cors]; # missing inputs: ambiclimate
+    "ambient_station" = ps: with ps; [ ]; # missing inputs: aioambient
+    "amcrest" = ps: with ps; [ ha-ffmpeg]; # missing inputs: amcrest
+    "ampio" = ps: with ps; [ ]; # missing inputs: asmog
+    "android_ip_webcam" = ps: with ps; [ ]; # missing inputs: pydroid-ipcam
+    "androidtv" = ps: with ps; [ ]; # missing inputs: adb-shell androidtv pure-python-adb
+    "anel_pwrctrl" = ps: with ps; [ ]; # missing inputs: anel_pwrctrl-homeassistant
+    "anthemav" = ps: with ps; [ ]; # missing inputs: anthemav
+    "apache_kafka" = ps: with ps; [ aiokafka];
+    "apcupsd" = ps: with ps; [ ]; # missing inputs: apcaccess
+    "api" = ps: with ps; [ aiohttp-cors];
+    "apns" = ps: with ps; [ ]; # missing inputs: apns2
+    "apple_tv" = ps: with ps; [ pyatv];
+    "apprise" = ps: with ps; [ apprise];
+    "aprs" = ps: with ps; [ ]; # missing inputs: aprslib geopy
+    "aqualogic" = ps: with ps; [ ]; # missing inputs: aqualogic
+    "aquostv" = ps: with ps; [ ]; # missing inputs: sharp_aquos_rc
+    "arcam_fmj" = ps: with ps; [ ]; # missing inputs: arcam-fmj
+    "arduino" = ps: with ps; [ ]; # missing inputs: PyMata
+    "arest" = ps: with ps; [ ];
+    "arlo" = ps: with ps; [ ha-ffmpeg]; # missing inputs: pyarlo
+    "aruba" = ps: with ps; [ pexpect];
+    "arwn" = ps: with ps; [ aiohttp-cors hbmqtt paho-mqtt];
+    "asterisk_cdr" = ps: with ps; [ ]; # missing inputs: asterisk_mbox
+    "asterisk_mbox" = ps: with ps; [ ]; # missing inputs: asterisk_mbox
+    "asuswrt" = ps: with ps; [ ]; # missing inputs: aioasuswrt
+    "aten_pe" = ps: with ps; [ ]; # missing inputs: atenpdu
+    "atome" = ps: with ps; [ ]; # missing inputs: pyatome
+    "august" = ps: with ps; [ ]; # missing inputs: py-august
+    "aurora" = ps: with ps; [ ];
+    "aurora_abb_powerone" = ps: with ps; [ ]; # missing inputs: aurorapy
+    "auth" = ps: with ps; [ aiohttp-cors];
+    "automatic" = ps: with ps; [ aiohttp-cors]; # missing inputs: aioautomatic
+    "automation" = ps: with ps; [ aiohttp-cors];
+    "avea" = ps: with ps; [ ]; # missing inputs: avea
+    "avion" = ps: with ps; [ ]; # missing inputs: avion
+    "awair" = ps: with ps; [ ]; # missing inputs: python_awair
+    "aws" = ps: with ps; [ ]; # missing inputs: aiobotocore
+    "axis" = ps: with ps; [ ]; # missing inputs: axis
+    "azure_event_hub" = ps: with ps; [ ]; # missing inputs: azure-eventhub
+    "azure_service_bus" = ps: with ps; [ azure-servicebus];
+    "baidu" = ps: with ps; [ ]; # missing inputs: baidu-aip
+    "bayesian" = ps: with ps; [ ];
+    "bbb_gpio" = ps: with ps; [ ]; # missing inputs: Adafruit_BBIO
+    "bbox" = ps: with ps; [ ]; # missing inputs: pybbox
+    "beewi_smartclim" = ps: with ps; [ ]; # missing inputs: beewi_smartclim
+    "bh1750" = ps: with ps; [ ]; # missing inputs: i2csense smbus-cffi
+    "binary_sensor" = ps: with ps; [ ];
+    "bitcoin" = ps: with ps; [ ]; # missing inputs: blockchain
+    "bizkaibus" = ps: with ps; [ ]; # missing inputs: bizkaibus
+    "blackbird" = ps: with ps; [ ]; # missing inputs: pyblackbird
+    "blink" = ps: with ps; [ ]; # missing inputs: blinkpy
+    "blinksticklight" = ps: with ps; [ BlinkStick];
+    "blinkt" = ps: with ps; [ ]; # missing inputs: blinkt
+    "blockchain" = ps: with ps; [ ]; # missing inputs: python-blockchain-api
+    "bloomsky" = ps: with ps; [ ];
+    "bluesound" = ps: with ps; [ xmltodict];
+    "bluetooth_le_tracker" = ps: with ps; [ ]; # missing inputs: pygatt[GATTTOOL]
+    "bluetooth_tracker" = ps: with ps; [ bt_proximity]; # missing inputs: pybluez
+    "bme280" = ps: with ps; [ ]; # missing inputs: i2csense smbus-cffi
+    "bme680" = ps: with ps; [ ]; # missing inputs: bme680 smbus-cffi
+    "bmw_connected_drive" = ps: with ps; [ ]; # missing inputs: bimmer_connected
+    "bom" = ps: with ps; [ ]; # missing inputs: bomradarloop
+    "braviatv" = ps: with ps; [ getmac]; # missing inputs: bravia-tv
+    "broadlink" = ps: with ps; [ broadlink];
+    "brother" = ps: with ps; [ ]; # missing inputs: brother
+    "brottsplatskartan" = ps: with ps; [ ]; # missing inputs: brottsplatskartan
+    "browser" = ps: with ps; [ ];
+    "brunt" = ps: with ps; [ ]; # missing inputs: brunt
+    "bt_home_hub_5" = ps: with ps; [ ]; # missing inputs: bthomehub5-devicelist
+    "bt_smarthub" = ps: with ps; [ ]; # missing inputs: btsmarthub_devicelist
+    "buienradar" = ps: with ps; [ ]; # missing inputs: buienradar
+    "caldav" = ps: with ps; [ caldav];
+    "calendar" = ps: with ps; [ aiohttp-cors];
+    "camera" = ps: with ps; [ aiohttp-cors];
+    "canary" = ps: with ps; [ ha-ffmpeg]; # missing inputs: py-canary
+    "cast" = ps: with ps; [ PyChromecast];
+    "cert_expiry" = ps: with ps; [ ];
+    "channels" = ps: with ps; [ ]; # missing inputs: pychannels
+    "cisco_ios" = ps: with ps; [ pexpect];
+    "cisco_mobility_express" = ps: with ps; [ ]; # missing inputs: ciscomobilityexpress
+    "cisco_webex_teams" = ps: with ps; [ ]; # missing inputs: webexteamssdk
+    "citybikes" = ps: with ps; [ ];
+    "clementine" = ps: with ps; [ ]; # missing inputs: python-clementine-remote
+    "clickatell" = ps: with ps; [ ];
+    "clicksend" = ps: with ps; [ ];
+    "clicksend_tts" = ps: with ps; [ ];
+    "climate" = ps: with ps; [ ];
+    "cloud" = ps: with ps; [ aiohttp-cors hass-nabucasa];
+    "cloudflare" = ps: with ps; [ ]; # missing inputs: pycfdns
+    "cmus" = ps: with ps; [ ]; # missing inputs: pycmus
+    "co2signal" = ps: with ps; [ ]; # missing inputs: co2signal
+    "coinbase" = ps: with ps; [ ]; # missing inputs: coinbase
+    "coinmarketcap" = ps: with ps; [ coinmarketcap];
+    "comed_hourly_pricing" = ps: with ps; [ ];
+    "comfoconnect" = ps: with ps; [ ]; # missing inputs: pycomfoconnect
+    "command_line" = ps: with ps; [ ];
+    "concord232" = ps: with ps; [ ]; # missing inputs: concord232
+    "config" = ps: with ps; [ aiohttp-cors];
+    "configurator" = ps: with ps; [ ];
+    "conversation" = ps: with ps; [ aiohttp-cors];
+    "coolmaster" = ps: with ps; [ ]; # missing inputs: pycoolmasternet
+    "coronavirus" = ps: with ps; [ ]; # missing inputs: coronavirus
+    "counter" = ps: with ps; [ ];
+    "cover" = ps: with ps; [ ];
+    "cppm_tracker" = ps: with ps; [ ]; # missing inputs: clearpasspy
+    "cpuspeed" = ps: with ps; [ py-cpuinfo];
+    "crimereports" = ps: with ps; [ ]; # missing inputs: crimereports
+    "cups" = ps: with ps; [ pycups];
+    "currencylayer" = ps: with ps; [ ];
+    "daikin" = ps: with ps; [ ]; # missing inputs: pydaikin
+    "danfoss_air" = ps: with ps; [ ]; # missing inputs: pydanfossair
+    "darksky" = ps: with ps; [ python-forecastio];
+    "datadog" = ps: with ps; [ datadog];
+    "ddwrt" = ps: with ps; [ ];
+    "deconz" = ps: with ps; [ ]; # missing inputs: pydeconz
+    "decora" = ps: with ps; [ ]; # missing inputs: bluepy decora
+    "decora_wifi" = ps: with ps; [ ]; # missing inputs: decora_wifi
+    "default_config" = ps: with ps; [ pynacl aiohttp-cors defusedxml distro hass-nabucasa netdisco sqlalchemy zeroconf]; # missing inputs: home-assistant-frontend
+    "delijn" = ps: with ps; [ ]; # missing inputs: pydelijn
+    "deluge" = ps: with ps; [ deluge-client];
+    "demo" = ps: with ps; [ aiohttp-cors];
+    "denon" = ps: with ps; [ ];
+    "denonavr" = ps: with ps; [ denonavr];
+    "derivative" = ps: with ps; [ ];
+    "deutsche_bahn" = ps: with ps; [ ]; # missing inputs: schiene
+    "device_automation" = ps: with ps; [ aiohttp-cors];
+    "device_sun_light_trigger" = ps: with ps; [ ];
+    "device_tracker" = ps: with ps; [ ];
+    "dht" = ps: with ps; [ ]; # missing inputs: Adafruit-DHT
+    "dialogflow" = ps: with ps; [ aiohttp-cors];
+    "digital_ocean" = ps: with ps; [ digital-ocean];
+    "digitalloggers" = ps: with ps; [ ]; # missing inputs: dlipower
+    "directv" = ps: with ps; [ ]; # missing inputs: directpy
+    "discogs" = ps: with ps; [ discogs_client];
+    "discord" = ps: with ps; [ discordpy];
+    "discovery" = ps: with ps; [ netdisco];
+    "dlib_face_detect" = ps: with ps; [ face_recognition];
+    "dlib_face_identify" = ps: with ps; [ face_recognition];
+    "dlink" = ps: with ps; [ ]; # missing inputs: pyW215
+    "dlna_dmr" = ps: with ps; [ ]; # missing inputs: async-upnp-client
+    "dnsip" = ps: with ps; [ aiodns];
+    "dominos" = ps: with ps; [ aiohttp-cors]; # missing inputs: pizzapi
+    "doods" = ps: with ps; [ pillow]; # missing inputs: pydoods
+    "doorbird" = ps: with ps; [ aiohttp-cors sqlalchemy]; # missing inputs: doorbirdpy home-assistant-frontend
+    "dovado" = ps: with ps; [ ]; # missing inputs: dovado
+    "downloader" = ps: with ps; [ ];
+    "dsmr" = ps: with ps; [ ]; # missing inputs: dsmr_parser
+    "dsmr_reader" = ps: with ps; [ aiohttp-cors hbmqtt paho-mqtt];
+    "dte_energy_bridge" = ps: with ps; [ ];
+    "dublin_bus_transport" = ps: with ps; [ ];
+    "duckdns" = ps: with ps; [ ];
+    "dunehd" = ps: with ps; [ ]; # missing inputs: pdunehd
+    "dwd_weather_warnings" = ps: with ps; [ ];
+    "dweet" = ps: with ps; [ ]; # missing inputs: dweepy
+    "dynalite" = ps: with ps; [ ]; # missing inputs: dynalite_devices
+    "dyson" = ps: with ps; [ ]; # missing inputs: libpurecool
+    "ebox" = ps: with ps; [ ]; # missing inputs: pyebox
+    "ebusd" = ps: with ps; [ ]; # missing inputs: ebusdpy
+    "ecoal_boiler" = ps: with ps; [ ]; # missing inputs: ecoaliface
+    "ecobee" = ps: with ps; [ ]; # missing inputs: python-ecobee-api
+    "econet" = ps: with ps; [ ]; # missing inputs: pyeconet
+    "ecovacs" = ps: with ps; [ ]; # missing inputs: sucks
+    "eddystone_temperature" = ps: with ps; [ construct]; # missing inputs: beacontools[scan]
+    "edimax" = ps: with ps; [ ]; # missing inputs: pyedimax
+    "ee_brightbox" = ps: with ps; [ ]; # missing inputs: eebrightbox
+    "efergy" = ps: with ps; [ ];
+    "egardia" = ps: with ps; [ ]; # missing inputs: pythonegardia
+    "eight_sleep" = ps: with ps; [ ]; # missing inputs: pyeight
+    "elgato" = ps: with ps; [ ]; # missing inputs: elgato
+    "eliqonline" = ps: with ps; [ ]; # missing inputs: eliqonline
+    "elkm1" = ps: with ps; [ ]; # missing inputs: elkm1-lib
+    "elv" = ps: with ps; [ ]; # missing inputs: pypca
+    "emby" = ps: with ps; [ ]; # missing inputs: pyemby
+    "emoncms" = ps: with ps; [ ];
+    "emoncms_history" = ps: with ps; [ ];
+    "emulated_hue" = ps: with ps; [ aiohttp-cors];
+    "emulated_roku" = ps: with ps; [ ]; # missing inputs: emulated_roku
+    "enigma2" = ps: with ps; [ ]; # missing inputs: openwebifpy
+    "enocean" = ps: with ps; [ ]; # missing inputs: enocean
+    "enphase_envoy" = ps: with ps; [ ]; # missing inputs: envoy_reader
+    "entur_public_transport" = ps: with ps; [ ]; # missing inputs: enturclient
+    "environment_canada" = ps: with ps; [ ]; # missing inputs: env_canada
+    "envirophat" = ps: with ps; [ ]; # missing inputs: envirophat smbus-cffi
+    "envisalink" = ps: with ps; [ ]; # missing inputs: pyenvisalink
+    "ephember" = ps: with ps; [ ]; # missing inputs: pyephember
+    "epson" = ps: with ps; [ ]; # missing inputs: epson-projector
+    "epsonworkforce" = ps: with ps; [ ]; # missing inputs: epsonprinter
+    "eq3btsmart" = ps: with ps; [ construct]; # missing inputs: python-eq3bt
+    "esphome" = ps: with ps; [ aioesphomeapi];
+    "essent" = ps: with ps; [ ]; # missing inputs: PyEssent
+    "etherscan" = ps: with ps; [ ]; # missing inputs: python-etherscan-api
+    "eufy" = ps: with ps; [ ]; # missing inputs: lakeside
+    "everlights" = ps: with ps; [ ]; # missing inputs: pyeverlights
+    "evohome" = ps: with ps; [ ]; # missing inputs: evohome-async
+    "facebook" = ps: with ps; [ ];
+    "facebox" = ps: with ps; [ ];
+    "fail2ban" = ps: with ps; [ ];
+    "familyhub" = ps: with ps; [ ]; # missing inputs: python-family-hub-local
+    "fan" = ps: with ps; [ ];
+    "fastdotcom" = ps: with ps; [ ]; # missing inputs: fastdotcom
+    "feedreader" = ps: with ps; [ ]; # missing inputs: feedparser-homeassistant
+    "ffmpeg" = ps: with ps; [ ha-ffmpeg];
+    "ffmpeg_motion" = ps: with ps; [ ha-ffmpeg];
+    "ffmpeg_noise" = ps: with ps; [ ha-ffmpeg];
+    "fibaro" = ps: with ps; [ ]; # missing inputs: fiblary3
+    "fido" = ps: with ps; [ ]; # missing inputs: pyfido
+    "file" = ps: with ps; [ ];
+    "filesize" = ps: with ps; [ ];
+    "filter" = ps: with ps; [ aiohttp-cors sqlalchemy];
+    "fints" = ps: with ps; [ fints];
+    "fitbit" = ps: with ps; [ aiohttp-cors fitbit];
+    "fixer" = ps: with ps; [ ]; # missing inputs: fixerio
+    "fleetgo" = ps: with ps; [ ]; # missing inputs: ritassist
+    "flexit" = ps: with ps; [ ]; # missing inputs: pyflexit pymodbus
+    "flic" = ps: with ps; [ ]; # missing inputs: pyflic-homeassistant
+    "flock" = ps: with ps; [ ];
+    "flume" = ps: with ps; [ ]; # missing inputs: pyflume
+    "flunearyou" = ps: with ps; [ ]; # missing inputs: pyflunearyou
+    "flux" = ps: with ps; [ ];
+    "flux_led" = ps: with ps; [ flux-led];
+    "folder" = ps: with ps; [ ];
+    "folder_watcher" = ps: with ps; [ watchdog];
+    "foobot" = ps: with ps; [ ]; # missing inputs: foobot_async
+    "fortigate" = ps: with ps; [ ]; # missing inputs: pyfgt
+    "fortios" = ps: with ps; [ ]; # missing inputs: fortiosapi
+    "foscam" = ps: with ps; [ ]; # missing inputs: libpyfoscam
+    "foursquare" = ps: with ps; [ aiohttp-cors];
+    "free_mobile" = ps: with ps; [ ]; # missing inputs: freesms
+    "freebox" = ps: with ps; [ ]; # missing inputs: aiofreepybox
+    "freedns" = ps: with ps; [ ];
+    "fritz" = ps: with ps; [ fritzconnection];
+    "fritzbox" = ps: with ps; [ ]; # missing inputs: pyfritzhome
+    "fritzbox_callmonitor" = ps: with ps; [ fritzconnection];
+    "fritzbox_netmonitor" = ps: with ps; [ fritzconnection];
+    "fronius" = ps: with ps; [ ]; # missing inputs: pyfronius
+    "frontend" = ps: with ps; [ aiohttp-cors]; # missing inputs: home-assistant-frontend
+    "frontier_silicon" = ps: with ps; [ ]; # missing inputs: afsapi
+    "futurenow" = ps: with ps; [ ]; # missing inputs: pyfnip
+    "garadget" = ps: with ps; [ ];
+    "garmin_connect" = ps: with ps; [ ]; # missing inputs: garminconnect
+    "gc100" = ps: with ps; [ ]; # missing inputs: python-gc100
+    "gdacs" = ps: with ps; [ ]; # missing inputs: aio_georss_gdacs
+    "gearbest" = ps: with ps; [ ]; # missing inputs: gearbest_parser
+    "geizhals" = ps: with ps; [ ]; # missing inputs: geizhals
+    "generic" = ps: with ps; [ ];
+    "generic_thermostat" = ps: with ps; [ ];
+    "geniushub" = ps: with ps; [ ]; # missing inputs: geniushub-client
+    "geo_json_events" = ps: with ps; [ ]; # missing inputs: geojson_client
+    "geo_location" = ps: with ps; [ ];
+    "geo_rss_events" = ps: with ps; [ ]; # missing inputs: georss_generic_client
+    "geofency" = ps: with ps; [ aiohttp-cors];
+    "geonetnz_quakes" = ps: with ps; [ ]; # missing inputs: aio_geojson_geonetnz_quakes
+    "geonetnz_volcano" = ps: with ps; [ ]; # missing inputs: aio_geojson_geonetnz_volcano
+    "gios" = ps: with ps; [ ]; # missing inputs: gios
+    "github" = ps: with ps; [ PyGithub];
+    "gitlab_ci" = ps: with ps; [ python-gitlab];
+    "gitter" = ps: with ps; [ ]; # missing inputs: gitterpy
+    "glances" = ps: with ps; [ ]; # missing inputs: glances_api
+    "gntp" = ps: with ps; [ ]; # missing inputs: gntp
+    "goalfeed" = ps: with ps; [ ]; # missing inputs: pysher
+    "gogogate2" = ps: with ps; [ ]; # missing inputs: pygogogate2
+    "google" = ps: with ps; [ google_api_python_client httplib2 oauth2client];
+    "google_assistant" = ps: with ps; [ aiohttp-cors];
+    "google_cloud" = ps: with ps; [ google_cloud_texttospeech];
+    "google_domains" = ps: with ps; [ ];
+    "google_maps" = ps: with ps; [ ]; # missing inputs: locationsharinglib
+    "google_pubsub" = ps: with ps; [ google_cloud_pubsub];
+    "google_translate" = ps: with ps; [ gtts-token];
+    "google_travel_time" = ps: with ps; [ ]; # missing inputs: googlemaps
+    "google_wifi" = ps: with ps; [ ];
+    "gpmdp" = ps: with ps; [ websocket_client];
+    "gpsd" = ps: with ps; [ ]; # missing inputs: gps3
+    "gpslogger" = ps: with ps; [ aiohttp-cors];
+    "graphite" = ps: with ps; [ ];
+    "greeneye_monitor" = ps: with ps; [ ]; # missing inputs: greeneye_monitor
+    "greenwave" = ps: with ps; [ ]; # missing inputs: greenwavereality
+    "group" = ps: with ps; [ ];
+    "growatt_server" = ps: with ps; [ ]; # missing inputs: growattServer
+    "gstreamer" = ps: with ps; [ ]; # missing inputs: gstreamer-player
+    "gtfs" = ps: with ps; [ ]; # missing inputs: pygtfs
+    "habitica" = ps: with ps; [ ]; # missing inputs: habitipy
+    "hangouts" = ps: with ps; [ ]; # missing inputs: hangups
+    "harman_kardon_avr" = ps: with ps; [ ]; # missing inputs: hkavr
+    "harmony" = ps: with ps; [ ]; # missing inputs: aioharmony
+    "hassio" = ps: with ps; [ aiohttp-cors]; # missing inputs: home-assistant-frontend
+    "haveibeenpwned" = ps: with ps; [ ];
+    "hddtemp" = ps: with ps; [ ];
+    "hdmi_cec" = ps: with ps; [ ]; # missing inputs: pyCEC
+    "heatmiser" = ps: with ps; [ ]; # missing inputs: heatmiserV3
+    "heos" = ps: with ps; [ ]; # missing inputs: pyheos
+    "here_travel_time" = ps: with ps; [ ]; # missing inputs: herepy
+    "hikvision" = ps: with ps; [ ]; # missing inputs: pyhik
+    "hikvisioncam" = ps: with ps; [ ]; # missing inputs: hikvision
+    "hisense_aehw4a1" = ps: with ps; [ ]; # missing inputs: pyaehw4a1
+    "history" = ps: with ps; [ aiohttp-cors sqlalchemy];
+    "history_graph" = ps: with ps; [ aiohttp-cors sqlalchemy];
+    "history_stats" = ps: with ps; [ aiohttp-cors sqlalchemy];
+    "hitron_coda" = ps: with ps; [ ];
+    "hive" = ps: with ps; [ ]; # missing inputs: pyhiveapi
+    "hlk_sw16" = ps: with ps; [ ]; # missing inputs: hlk-sw16
+    "homeassistant" = ps: with ps; [ ];
+    "homekit" = ps: with ps; [ ]; # missing inputs: HAP-python
+    "homekit_controller" = ps: with ps; [ ]; # missing inputs: homekit[IP]
+    "homematic" = ps: with ps; [ pyhomematic];
+    "homematicip_cloud" = ps: with ps; [ ]; # missing inputs: homematicip
+    "homeworks" = ps: with ps; [ ]; # missing inputs: pyhomeworks
+    "honeywell" = ps: with ps; [ ]; # missing inputs: somecomfort
+    "horizon" = ps: with ps; [ ]; # missing inputs: horimote
+    "hp_ilo" = ps: with ps; [ ]; # missing inputs: python-hpilo
+    "html5" = ps: with ps; [ aiohttp-cors pywebpush];
+    "http" = ps: with ps; [ aiohttp-cors];
+    "htu21d" = ps: with ps; [ ]; # missing inputs: i2csense smbus-cffi
+    "huawei_lte" = ps: with ps; [ getmac stringcase]; # missing inputs: huawei-lte-api url-normalize
+    "huawei_router" = ps: with ps; [ ];
+    "hue" = ps: with ps; [ aiohue];
+    "hunterdouglas_powerview" = ps: with ps; [ ]; # missing inputs: aiopvapi
+    "hydrawise" = ps: with ps; [ ]; # missing inputs: hydrawiser
+    "hyperion" = ps: with ps; [ ];
+    "ialarm" = ps: with ps; [ ]; # missing inputs: pyialarm
+    "iaqualink" = ps: with ps; [ ]; # missing inputs: iaqualink
+    "icloud" = ps: with ps; [ pyicloud];
+    "idteck_prox" = ps: with ps; [ ]; # missing inputs: rfk101py
+    "ifttt" = ps: with ps; [ aiohttp-cors pyfttt];
+    "iglo" = ps: with ps; [ ]; # missing inputs: iglo
+    "ign_sismologia" = ps: with ps; [ ]; # missing inputs: georss_ign_sismologia_client
+    "ihc" = ps: with ps; [ defusedxml]; # missing inputs: ihcsdk
+    "image_processing" = ps: with ps; [ aiohttp-cors];
+    "imap" = ps: with ps; [ ]; # missing inputs: aioimaplib
+    "imap_email_content" = ps: with ps; [ ];
+    "incomfort" = ps: with ps; [ ]; # missing inputs: incomfort-client
+    "influxdb" = ps: with ps; [ influxdb];
+    "input_boolean" = ps: with ps; [ ];
+    "input_datetime" = ps: with ps; [ ];
+    "input_number" = ps: with ps; [ ];
+    "input_select" = ps: with ps; [ ];
+    "input_text" = ps: with ps; [ ];
+    "insteon" = ps: with ps; [ ]; # missing inputs: insteonplm
+    "integration" = ps: with ps; [ ];
+    "intent" = ps: with ps; [ aiohttp-cors];
+    "intent_script" = ps: with ps; [ ];
+    "intesishome" = ps: with ps; [ ]; # missing inputs: pyintesishome
+    "ios" = ps: with ps; [ aiohttp-cors zeroconf];
+    "iota" = ps: with ps; [ ]; # missing inputs: pyota
+    "iperf3" = ps: with ps; [ ]; # missing inputs: iperf3
+    "ipma" = ps: with ps; [ ]; # missing inputs: pyipma
+    "iqvia" = ps: with ps; [ numpy]; # missing inputs: pyiqvia
+    "irish_rail_transport" = ps: with ps; [ ]; # missing inputs: pyirishrail
+    "islamic_prayer_times" = ps: with ps; [ ]; # missing inputs: prayer_times_calculator
+    "iss" = ps: with ps; [ ]; # missing inputs: pyiss
+    "isy994" = ps: with ps; [ ]; # missing inputs: PyISY
+    "itach" = ps: with ps; [ ]; # missing inputs: pyitachip2ir
+    "itunes" = ps: with ps; [ ];
+    "izone" = ps: with ps; [ ]; # missing inputs: python-izone
+    "jewish_calendar" = ps: with ps; [ ]; # missing inputs: hdate
+    "joaoapps_join" = ps: with ps; [ ]; # missing inputs: python-join-api
+    "juicenet" = ps: with ps; [ ]; # missing inputs: python-juicenet
+    "kaiterra" = ps: with ps; [ ]; # missing inputs: kaiterra-async-client
+    "kankun" = ps: with ps; [ ];
+    "keba" = ps: with ps; [ ]; # missing inputs: keba-kecontact
+    "keenetic_ndms2" = ps: with ps; [ ]; # missing inputs: ndms2_client
+    "kef" = ps: with ps; [ getmac]; # missing inputs: aiokef
+    "keyboard" = ps: with ps; [ ]; # missing inputs: pyuserinput
+    "keyboard_remote" = ps: with ps; [ evdev]; # missing inputs: aionotify
+    "kira" = ps: with ps; [ ]; # missing inputs: pykira
+    "kiwi" = ps: with ps; [ ]; # missing inputs: kiwiki-client
+    "knx" = ps: with ps; [ ]; # missing inputs: xknx
+    "kodi" = ps: with ps; [ jsonrpc-async jsonrpc-websocket];
+    "konnected" = ps: with ps; [ aiohttp-cors]; # missing inputs: konnected
+    "kwb" = ps: with ps; [ ]; # missing inputs: pykwb
+    "lacrosse" = ps: with ps; [ ]; # missing inputs: pylacrosse
+    "lametric" = ps: with ps; [ ]; # missing inputs: lmnotify
+    "lannouncer" = ps: with ps; [ ];
+    "lastfm" = ps: with ps; [ pylast];
+    "launch_library" = ps: with ps; [ ]; # missing inputs: pylaunches
+    "lcn" = ps: with ps; [ ]; # missing inputs: pypck
+    "lg_netcast" = ps: with ps; [ ]; # missing inputs: pylgnetcast-homeassistant
+    "lg_soundbar" = ps: with ps; [ ]; # missing inputs: temescal
+    "life360" = ps: with ps; [ ]; # missing inputs: life360
+    "lifx" = ps: with ps; [ aiolifx aiolifx-effects];
+    "lifx_cloud" = ps: with ps; [ ];
+    "lifx_legacy" = ps: with ps; [ ]; # missing inputs: liffylights
+    "light" = ps: with ps; [ ];
+    "lightwave" = ps: with ps; [ ]; # missing inputs: lightwave
+    "limitlessled" = ps: with ps; [ limitlessled];
+    "linksys_smart" = ps: with ps; [ ];
+    "linky" = ps: with ps; [ ]; # missing inputs: pylinky
+    "linode" = ps: with ps; [ linode-api];
+    "linux_battery" = ps: with ps; [ batinfo];
+    "lirc" = ps: with ps; [ ]; # missing inputs: python-lirc
+    "litejet" = ps: with ps; [ ]; # missing inputs: pylitejet
+    "llamalab_automate" = ps: with ps; [ ];
+    "local_file" = ps: with ps; [ ];
+    "local_ip" = ps: with ps; [ ];
+    "locative" = ps: with ps; [ aiohttp-cors];
+    "lock" = ps: with ps; [ ];
+    "lockitron" = ps: with ps; [ ];
+    "logbook" = ps: with ps; [ aiohttp-cors sqlalchemy]; # missing inputs: home-assistant-frontend
+    "logentries" = ps: with ps; [ ];
+    "logger" = ps: with ps; [ ];
+    "logi_circle" = ps: with ps; [ aiohttp-cors ha-ffmpeg]; # missing inputs: logi_circle
+    "london_air" = ps: with ps; [ ];
+    "london_underground" = ps: with ps; [ ]; # missing inputs: london-tube-status
+    "loopenergy" = ps: with ps; [ ]; # missing inputs: pyloopenergy
+    "lovelace" = ps: with ps; [ ];
+    "luci" = ps: with ps; [ ]; # missing inputs: openwrt-luci-rpc
+    "luftdaten" = ps: with ps; [ luftdaten];
+    "lupusec" = ps: with ps; [ ]; # missing inputs: lupupy
+    "lutron" = ps: with ps; [ ]; # missing inputs: pylutron
+    "lutron_caseta" = ps: with ps; [ ]; # missing inputs: pylutron-caseta
+    "lw12wifi" = ps: with ps; [ ]; # missing inputs: lw12
+    "lyft" = ps: with ps; [ ]; # missing inputs: lyft_rides
+    "magicseaweed" = ps: with ps; [ ]; # missing inputs: magicseaweed
+    "mailbox" = ps: with ps; [ aiohttp-cors];
+    "mailgun" = ps: with ps; [ aiohttp-cors]; # missing inputs: pymailgunner
+    "manual" = ps: with ps; [ ];
+    "manual_mqtt" = ps: with ps; [ aiohttp-cors hbmqtt paho-mqtt];
+    "map" = ps: with ps; [ aiohttp-cors]; # missing inputs: home-assistant-frontend
+    "marytts" = ps: with ps; [ ]; # missing inputs: speak2mary
+    "mastodon" = ps: with ps; [ ]; # missing inputs: Mastodon.py
+    "matrix" = ps: with ps; [ matrix-client];
+    "maxcube" = ps: with ps; [ ]; # missing inputs: maxcube-api
+    "mcp23017" = ps: with ps; [ ]; # missing inputs: RPi.GPIO adafruit-blinka adafruit-circuitpython-mcp230xx
+    "media_extractor" = ps: with ps; [ aiohttp-cors youtube-dl-light];
+    "media_player" = ps: with ps; [ aiohttp-cors];
+    "mediaroom" = ps: with ps; [ ]; # missing inputs: pymediaroom
+    "melcloud" = ps: with ps; [ ]; # missing inputs: pymelcloud
+    "melissa" = ps: with ps; [ ]; # missing inputs: py-melissa-climate
+    "meraki" = ps: with ps; [ aiohttp-cors];
+    "message_bird" = ps: with ps; [ ]; # missing inputs: messagebird
+    "met" = ps: with ps; [ ]; # missing inputs: pyMetno
+    "meteo_france" = ps: with ps; [ ]; # missing inputs: meteofrance vigilancemeteo
+    "meteoalarm" = ps: with ps; [ ]; # missing inputs: meteoalertapi
+    "metoffice" = ps: with ps; [ ]; # missing inputs: datapoint
+    "mfi" = ps: with ps; [ ]; # missing inputs: mficlient
+    "mhz19" = ps: with ps; [ ]; # missing inputs: pmsensor
+    "microsoft" = ps: with ps; [ ]; # missing inputs: pycsspeechtts
+    "microsoft_face" = ps: with ps; [ aiohttp-cors];
+    "microsoft_face_detect" = ps: with ps; [ aiohttp-cors];
+    "microsoft_face_identify" = ps: with ps; [ aiohttp-cors];
+    "miflora" = ps: with ps; [ ]; # missing inputs: bluepy miflora
+    "mikrotik" = ps: with ps; [ ]; # missing inputs: librouteros
+    "mill" = ps: with ps; [ ]; # missing inputs: millheater
+    "min_max" = ps: with ps; [ ];
+    "minecraft_server" = ps: with ps; [ getmac]; # missing inputs: mcstatus
+    "minio" = ps: with ps; [ minio];
+    "mitemp_bt" = ps: with ps; [ ]; # missing inputs: mitemp_bt
+    "mjpeg" = ps: with ps; [ ];
+    "mobile_app" = ps: with ps; [ pynacl aiohttp-cors];
+    "mochad" = ps: with ps; [ ]; # missing inputs: pymochad
+    "modbus" = ps: with ps; [ ]; # missing inputs: pymodbus
+    "modem_callerid" = ps: with ps; [ ]; # missing inputs: basicmodem
+    "mold_indicator" = ps: with ps; [ ];
+    "monoprice" = ps: with ps; [ ]; # missing inputs: pymonoprice
+    "moon" = ps: with ps; [ ];
+    "mopar" = ps: with ps; [ ]; # missing inputs: motorparts
+    "mpchc" = ps: with ps; [ ];
+    "mpd" = ps: with ps; [ mpd2];
+    "mqtt" = ps: with ps; [ aiohttp-cors hbmqtt paho-mqtt];
+    "mqtt_eventstream" = ps: with ps; [ aiohttp-cors hbmqtt paho-mqtt];
+    "mqtt_json" = ps: with ps; [ aiohttp-cors hbmqtt paho-mqtt];
+    "mqtt_room" = ps: with ps; [ aiohttp-cors hbmqtt paho-mqtt];
+    "mqtt_statestream" = ps: with ps; [ aiohttp-cors hbmqtt paho-mqtt];
+    "msteams" = ps: with ps; [ ]; # missing inputs: pymsteams
+    "mvglive" = ps: with ps; [ PyMVGLive];
+    "mychevy" = ps: with ps; [ ]; # missing inputs: mychevy
+    "mycroft" = ps: with ps; [ ]; # missing inputs: mycroftapi
+    "myq" = ps: with ps; [ ]; # missing inputs: pymyq
+    "mysensors" = ps: with ps; [ ]; # missing inputs: pymysensors
+    "mystrom" = ps: with ps; [ aiohttp-cors]; # missing inputs: python-mystrom
+    "mythicbeastsdns" = ps: with ps; [ ]; # missing inputs: mbddns
+    "n26" = ps: with ps; [ ]; # missing inputs: n26
+    "nad" = ps: with ps; [ ]; # missing inputs: nad_receiver
+    "namecheapdns" = ps: with ps; [ defusedxml];
+    "nanoleaf" = ps: with ps; [ ]; # missing inputs: pynanoleaf
+    "neato" = ps: with ps; [ pybotvac];
+    "nederlandse_spoorwegen" = ps: with ps; [ ]; # missing inputs: nsapi
+    "nello" = ps: with ps; [ ]; # missing inputs: pynello
+    "ness_alarm" = ps: with ps; [ ]; # missing inputs: nessclient
+    "nest" = ps: with ps; [ ]; # missing inputs: python-nest
+    "netatmo" = ps: with ps; [ aiohttp-cors pyatmo];
+    "netdata" = ps: with ps; [ ]; # missing inputs: netdata
+    "netgear" = ps: with ps; [ ]; # missing inputs: pynetgear
+    "netgear_lte" = ps: with ps; [ ]; # missing inputs: eternalegypt
+    "netio" = ps: with ps; [ aiohttp-cors]; # missing inputs: pynetio
+    "neurio_energy" = ps: with ps; [ ]; # missing inputs: neurio
+    "nextbus" = ps: with ps; [ ]; # missing inputs: py_nextbusnext
+    "nfandroidtv" = ps: with ps; [ ];
+    "niko_home_control" = ps: with ps; [ ]; # missing inputs: niko-home-control
+    "nilu" = ps: with ps; [ ]; # missing inputs: niluclient
+    "nissan_leaf" = ps: with ps; [ ]; # missing inputs: pycarwings2
+    "nmap_tracker" = ps: with ps; [ getmac]; # missing inputs: python-nmap
+    "nmbs" = ps: with ps; [ ]; # missing inputs: pyrail
+    "no_ip" = ps: with ps; [ ];
+    "noaa_tides" = ps: with ps; [ ]; # missing inputs: py_noaa
+    "norway_air" = ps: with ps; [ ]; # missing inputs: pyMetno
+    "notify" = ps: with ps; [ ];
+    "notion" = ps: with ps; [ ]; # missing inputs: aionotion
+    "nsw_fuel_station" = ps: with ps; [ ]; # missing inputs: nsw-fuel-api-client
+    "nsw_rural_fire_service_feed" = ps: with ps; [ ]; # missing inputs: aio_geojson_nsw_rfs_incidents
+    "nuheat" = ps: with ps; [ ]; # missing inputs: nuheat
+    "nuimo_controller" = ps: with ps; [ ]; # missing inputs: --only-binary=all nuimo
+    "nuki" = ps: with ps; [ ]; # missing inputs: pynuki
+    "nut" = ps: with ps; [ ]; # missing inputs: pynut2
+    "nws" = ps: with ps; [ ]; # missing inputs: pynws
+    "nx584" = ps: with ps; [ ]; # missing inputs: pynx584
+    "nzbget" = ps: with ps; [ ]; # missing inputs: pynzbgetapi
+    "oasa_telematics" = ps: with ps; [ ]; # missing inputs: oasatelematics
+    "obihai" = ps: with ps; [ ]; # missing inputs: pyobihai
+    "octoprint" = ps: with ps; [ ];
+    "oem" = ps: with ps; [ ]; # missing inputs: oemthermostat
+    "ohmconnect" = ps: with ps; [ defusedxml];
+    "ombi" = ps: with ps; [ ]; # missing inputs: pyombi
+    "onboarding" = ps: with ps; [ aiohttp-cors];
+    "onewire" = ps: with ps; [ ]; # missing inputs: pyownet
+    "onkyo" = ps: with ps; [ onkyo-eiscp];
+    "onvif" = ps: with ps; [ ha-ffmpeg]; # missing inputs: onvif-zeep-async
+    "openalpr_cloud" = ps: with ps; [ ];
+    "openalpr_local" = ps: with ps; [ ];
+    "opencv" = ps: with ps; [ numpy]; # missing inputs: opencv-python-headless
+    "openevse" = ps: with ps; [ ]; # missing inputs: openevsewifi
+    "openexchangerates" = ps: with ps; [ ];
+    "opengarage" = ps: with ps; [ ];
+    "openhardwaremonitor" = ps: with ps; [ ];
+    "openhome" = ps: with ps; [ ]; # missing inputs: openhomedevice
+    "opensensemap" = ps: with ps; [ ]; # missing inputs: opensensemap-api
+    "opensky" = ps: with ps; [ ];
+    "opentherm_gw" = ps: with ps; [ ]; # missing inputs: pyotgw
+    "openuv" = ps: with ps; [ ]; # missing inputs: pyopenuv
+    "openweathermap" = ps: with ps; [ pyowm];
+    "opnsense" = ps: with ps; [ ]; # missing inputs: pyopnsense
+    "opple" = ps: with ps; [ ]; # missing inputs: pyoppleio
+    "orangepi_gpio" = ps: with ps; [ ]; # missing inputs: OPi.GPIO
+    "oru" = ps: with ps; [ ]; # missing inputs: oru
+    "orvibo" = ps: with ps; [ ]; # missing inputs: orvibo
+    "osramlightify" = ps: with ps; [ ]; # missing inputs: lightify
+    "otp" = ps: with ps; [ pyotp];
+    "owntracks" = ps: with ps; [ pynacl aiohttp-cors];
+    "panasonic_bluray" = ps: with ps; [ ]; # missing inputs: panacotta
+    "panasonic_viera" = ps: with ps; [ wakeonlan]; # missing inputs: panasonic_viera
+    "pandora" = ps: with ps; [ pexpect];
+    "panel_custom" = ps: with ps; [ aiohttp-cors]; # missing inputs: home-assistant-frontend
+    "panel_iframe" = ps: with ps; [ aiohttp-cors]; # missing inputs: home-assistant-frontend
+    "pcal9535a" = ps: with ps; [ ]; # missing inputs: pcal9535a
+    "pencom" = ps: with ps; [ ]; # missing inputs: pencompy
+    "persistent_notification" = ps: with ps; [ ];
+    "person" = ps: with ps; [ ];
+    "philips_js" = ps: with ps; [ ]; # missing inputs: ha-philipsjs
+    "pi_hole" = ps: with ps; [ ]; # missing inputs: hole
+    "picotts" = ps: with ps; [ ];
+    "piglow" = ps: with ps; [ ]; # missing inputs: piglow
+    "pilight" = ps: with ps; [ ]; # missing inputs: pilight
+    "ping" = ps: with ps; [ ];
+    "pioneer" = ps: with ps; [ ];
+    "pjlink" = ps: with ps; [ ]; # missing inputs: pypjlink2
+    "plaato" = ps: with ps; [ aiohttp-cors];
+    "plant" = ps: with ps; [ ];
+    "plex" = ps: with ps; [ aiohttp-cors plexapi plexauth plexwebsocket];
+    "plugwise" = ps: with ps; [ ]; # missing inputs: haanna
+    "plum_lightpad" = ps: with ps; [ ]; # missing inputs: plumlightpad
+    "pocketcasts" = ps: with ps; [ ]; # missing inputs: pocketcasts
+    "point" = ps: with ps; [ aiohttp-cors]; # missing inputs: pypoint
+    "prezzibenzina" = ps: with ps; [ ]; # missing inputs: prezzibenzina-py
+    "proliphix" = ps: with ps; [ ]; # missing inputs: proliphix
+    "prometheus" = ps: with ps; [ aiohttp-cors prometheus_client];
+    "prowl" = ps: with ps; [ ];
+    "proximity" = ps: with ps; [ ];
+    "proxmoxve" = ps: with ps; [ ]; # missing inputs: proxmoxer
+    "proxy" = ps: with ps; [ pillow];
+    "ps4" = ps: with ps; [ ]; # missing inputs: pyps4-2ndscreen
+    "ptvsd" = ps: with ps; [ ]; # missing inputs: ptvsd
+    "pulseaudio_loopback" = ps: with ps; [ ];
+    "push" = ps: with ps; [ aiohttp-cors];
+    "pushbullet" = ps: with ps; [ pushbullet];
+    "pushetta" = ps: with ps; [ ]; # missing inputs: pushetta
+    "pushover" = ps: with ps; [ pushover-complete];
+    "pushsafer" = ps: with ps; [ ];
+    "pvoutput" = ps: with ps; [ ];
+    "pyload" = ps: with ps; [ ];
+    "python_script" = ps: with ps; [ restrictedpython];
+    "qbittorrent" = ps: with ps; [ ]; # missing inputs: python-qbittorrent
+    "qld_bushfire" = ps: with ps; [ ]; # missing inputs: georss_qld_bushfire_alert_client
+    "qnap" = ps: with ps; [ ]; # missing inputs: qnapstats
+    "qrcode" = ps: with ps; [ pillow]; # missing inputs: pyzbar
+    "quantum_gateway" = ps: with ps; [ ]; # missing inputs: quantum-gateway
+    "qwikswitch" = ps: with ps; [ ]; # missing inputs: pyqwikswitch
+    "rachio" = ps: with ps; [ aiohttp-cors]; # missing inputs: rachiopy
+    "radarr" = ps: with ps; [ ];
+    "radiotherm" = ps: with ps; [ ]; # missing inputs: radiotherm
+    "rainbird" = ps: with ps; [ ]; # missing inputs: pyrainbird
+    "raincloud" = ps: with ps; [ ]; # missing inputs: raincloudy
+    "rainforest_eagle" = ps: with ps; [ ]; # missing inputs: eagle200_reader uEagle
+    "rainmachine" = ps: with ps; [ ]; # missing inputs: regenmaschine
+    "random" = ps: with ps; [ ];
+    "raspihats" = ps: with ps; [ ]; # missing inputs: raspihats smbus-cffi
+    "raspyrfm" = ps: with ps; [ ]; # missing inputs: raspyrfm-client
+    "recollect_waste" = ps: with ps; [ ]; # missing inputs: recollect-waste
+    "recorder" = ps: with ps; [ sqlalchemy];
+    "recswitch" = ps: with ps; [ ]; # missing inputs: pyrecswitch
+    "reddit" = ps: with ps; [ praw];
+    "rejseplanen" = ps: with ps; [ ]; # missing inputs: rjpl
+    "remember_the_milk" = ps: with ps; [ httplib2]; # missing inputs: RtmAPI
+    "remote" = ps: with ps; [ ];
+    "remote_rpi_gpio" = ps: with ps; [ ]; # missing inputs: gpiozero
+    "repetier" = ps: with ps; [ ]; # missing inputs: pyrepetier
+    "rest" = ps: with ps; [ jsonpath xmltodict];
+    "rest_command" = ps: with ps; [ ];
+    "rflink" = ps: with ps; [ ]; # missing inputs: rflink
+    "rfxtrx" = ps: with ps; [ ]; # missing inputs: pyRFXtrx
+    "ring" = ps: with ps; [ ha-ffmpeg]; # missing inputs: ring_doorbell
+    "ripple" = ps: with ps; [ ]; # missing inputs: python-ripple-api
+    "rmvtransport" = ps: with ps; [ ]; # missing inputs: PyRMVtransport
+    "rocketchat" = ps: with ps; [ ]; # missing inputs: rocketchat-API
+    "roku" = ps: with ps; [ ]; # missing inputs: roku
+    "roomba" = ps: with ps; [ ]; # missing inputs: roombapy
+    "route53" = ps: with ps; [ boto3]; # missing inputs: ipify
+    "rova" = ps: with ps; [ ]; # missing inputs: rova
+    "rpi_camera" = ps: with ps; [ ];
+    "rpi_gpio" = ps: with ps; [ ]; # missing inputs: RPi.GPIO
+    "rpi_gpio_pwm" = ps: with ps; [ ]; # missing inputs: pwmled
+    "rpi_pfio" = ps: with ps; [ ]; # missing inputs: pifacecommon pifacedigitalio
+    "rpi_rf" = ps: with ps; [ ]; # missing inputs: rpi-rf
+    "rss_feed_template" = ps: with ps; [ aiohttp-cors];
+    "rtorrent" = ps: with ps; [ ];
+    "russound_rio" = ps: with ps; [ ]; # missing inputs: russound_rio
+    "russound_rnet" = ps: with ps; [ ]; # missing inputs: russound
+    "sabnzbd" = ps: with ps; [ ]; # missing inputs: pysabnzbd
+    "safe_mode" = ps: with ps; [ aiohttp-cors hass-nabucasa]; # missing inputs: home-assistant-frontend
+    "saj" = ps: with ps; [ ]; # missing inputs: pysaj
+    "salt" = ps: with ps; [ ]; # missing inputs: saltbox
+    "samsungtv" = ps: with ps; [ ]; # missing inputs: samsungctl[websocket]
+    "satel_integra" = ps: with ps; [ ]; # missing inputs: satel_integra
+    "scene" = ps: with ps; [ ];
+    "scrape" = ps: with ps; [ beautifulsoup4];
+    "script" = ps: with ps; [ ];
+    "scsgate" = ps: with ps; [ ]; # missing inputs: scsgate
+    "search" = ps: with ps; [ aiohttp-cors];
+    "season" = ps: with ps; [ ephem];
+    "sendgrid" = ps: with ps; [ ]; # missing inputs: sendgrid
+    "sense" = ps: with ps; [ ]; # missing inputs: sense_energy
+    "sensehat" = ps: with ps; [ ]; # missing inputs: sense-hat
+    "sensibo" = ps: with ps; [ ]; # missing inputs: pysensibo
+    "sensor" = ps: with ps; [ ];
+    "sentry" = ps: with ps; [ sentry-sdk];
+    "serial" = ps: with ps; [ pyserial-asyncio];
+    "serial_pm" = ps: with ps; [ ]; # missing inputs: pmsensor
+    "sesame" = ps: with ps; [ ]; # missing inputs: pysesame2
+    "seven_segments" = ps: with ps; [ pillow];
+    "seventeentrack" = ps: with ps; [ ]; # missing inputs: py17track
+    "shell_command" = ps: with ps; [ ];
+    "shiftr" = ps: with ps; [ paho-mqtt];
+    "shodan" = ps: with ps; [ shodan];
+    "shopping_list" = ps: with ps; [ aiohttp-cors];
+    "sht31" = ps: with ps; [ ]; # missing inputs: Adafruit-GPIO Adafruit-SHT31
+    "sigfox" = ps: with ps; [ ];
+    "sighthound" = ps: with ps; [ ]; # missing inputs: simplehound
+    "signal_messenger" = ps: with ps; [ ]; # missing inputs: pysignalclirestapi
+    "simplepush" = ps: with ps; [ ]; # missing inputs: simplepush
+    "simplisafe" = ps: with ps; [ ]; # missing inputs: simplisafe-python
+    "simulated" = ps: with ps; [ ];
+    "sinch" = ps: with ps; [ ]; # missing inputs: clx-sdk-xms
+    "sisyphus" = ps: with ps; [ ]; # missing inputs: sisyphus-control
+    "sky_hub" = ps: with ps; [ ];
+    "skybeacon" = ps: with ps; [ ]; # missing inputs: pygatt[GATTTOOL]
+    "skybell" = ps: with ps; [ ]; # missing inputs: skybellpy
+    "slack" = ps: with ps; [ ]; # missing inputs: slacker
+    "sleepiq" = ps: with ps; [ ]; # missing inputs: sleepyq
+    "slide" = ps: with ps; [ ]; # missing inputs: goslide-api
+    "sma" = ps: with ps; [ ]; # missing inputs: pysma
+    "smappee" = ps: with ps; [ ]; # missing inputs: smappy
+    "smarthab" = ps: with ps; [ ]; # missing inputs: smarthab
+    "smartthings" = ps: with ps; [ aiohttp-cors]; # missing inputs: pysmartapp pysmartthings
+    "smarty" = ps: with ps; [ ]; # missing inputs: pysmarty
+    "smhi" = ps: with ps; [ ]; # missing inputs: smhi-pkg
+    "sms" = ps: with ps; [ ]; # missing inputs: python-gammu
+    "smtp" = ps: with ps; [ ];
+    "snapcast" = ps: with ps; [ snapcast];
+    "snips" = ps: with ps; [ aiohttp-cors hbmqtt paho-mqtt];
+    "snmp" = ps: with ps; [ pysnmp];
+    "sochain" = ps: with ps; [ ]; # missing inputs: python-sochain-api
+    "socialblade" = ps: with ps; [ ]; # missing inputs: socialbladeclient
+    "solaredge" = ps: with ps; [ stringcase]; # missing inputs: solaredge
+    "solaredge_local" = ps: with ps; [ ]; # missing inputs: solaredge-local
+    "solarlog" = ps: with ps; [ ]; # missing inputs: sunwatcher
+    "solax" = ps: with ps; [ ]; # missing inputs: solax
+    "soma" = ps: with ps; [ ]; # missing inputs: pysoma
+    "somfy" = ps: with ps; [ aiohttp-cors]; # missing inputs: pymfy
+    "somfy_mylink" = ps: with ps; [ ]; # missing inputs: somfy-mylink-synergy
+    "sonarr" = ps: with ps; [ ];
+    "songpal" = ps: with ps; [ ]; # missing inputs: python-songpal
+    "sonos" = ps: with ps; [ pysonos];
+    "sony_projector" = ps: with ps; [ ]; # missing inputs: pysdcp
+    "soundtouch" = ps: with ps; [ libsoundtouch];
+    "spaceapi" = ps: with ps; [ aiohttp-cors];
+    "spc" = ps: with ps; [ ]; # missing inputs: pyspcwebgw
+    "speedtestdotnet" = ps: with ps; [ speedtest-cli];
+    "spider" = ps: with ps; [ ]; # missing inputs: spiderpy
+    "splunk" = ps: with ps; [ ];
+    "spotcrime" = ps: with ps; [ ]; # missing inputs: spotcrime
+    "spotify" = ps: with ps; [ aiohttp-cors spotipy];
+    "sql" = ps: with ps; [ sqlalchemy];
+    "squeezebox" = ps: with ps; [ ];
+    "ssdp" = ps: with ps; [ defusedxml netdisco];
+    "starline" = ps: with ps; [ ]; # missing inputs: starline
+    "starlingbank" = ps: with ps; [ ]; # missing inputs: starlingbank
+    "startca" = ps: with ps; [ xmltodict];
+    "statistics" = ps: with ps; [ ];
+    "statsd" = ps: with ps; [ statsd];
+    "steam_online" = ps: with ps; [ ]; # missing inputs: steamodd
+    "stiebel_eltron" = ps: with ps; [ ]; # missing inputs: pymodbus pystiebeleltron
+    "stookalert" = ps: with ps; [ ]; # missing inputs: stookalert
+    "stream" = ps: with ps; [ aiohttp-cors av];
+    "streamlabswater" = ps: with ps; [ ]; # missing inputs: streamlabswater
+    "stt" = ps: with ps; [ aiohttp-cors];
+    "suez_water" = ps: with ps; [ ]; # missing inputs: pysuez
+    "sun" = ps: with ps; [ ];
+    "supervisord" = ps: with ps; [ ];
+    "supla" = ps: with ps; [ ]; # missing inputs: pysupla
+    "surepetcare" = ps: with ps; [ ]; # missing inputs: surepy
+    "swiss_hydrological_data" = ps: with ps; [ ]; # missing inputs: swisshydrodata
+    "swiss_public_transport" = ps: with ps; [ ]; # missing inputs: python_opendata_transport
+    "swisscom" = ps: with ps; [ ];
+    "switch" = ps: with ps; [ ];
+    "switchbot" = ps: with ps; [ ]; # missing inputs: PySwitchbot
+    "switcher_kis" = ps: with ps; [ ]; # missing inputs: aioswitcher
+    "switchmate" = ps: with ps; [ ]; # missing inputs: pySwitchmate
+    "syncthru" = ps: with ps; [ ]; # missing inputs: pysyncthru
+    "synology" = ps: with ps; [ ]; # missing inputs: py-synology
+    "synology_chat" = ps: with ps; [ ];
+    "synology_srm" = ps: with ps; [ ]; # missing inputs: synology-srm
+    "synologydsm" = ps: with ps; [ ]; # missing inputs: python-synology
+    "syslog" = ps: with ps; [ ];
+    "system_health" = ps: with ps; [ aiohttp-cors];
+    "system_log" = ps: with ps; [ aiohttp-cors];
+    "systemmonitor" = ps: with ps; [ psutil];
+    "tado" = ps: with ps; [ ]; # missing inputs: python-tado
+    "tahoma" = ps: with ps; [ ]; # missing inputs: tahoma-api
+    "tank_utility" = ps: with ps; [ ]; # missing inputs: tank_utility
+    "tapsaff" = ps: with ps; [ ]; # missing inputs: tapsaff
+    "tautulli" = ps: with ps; [ ]; # missing inputs: pytautulli
+    "tcp" = ps: with ps; [ ];
+    "ted5000" = ps: with ps; [ xmltodict];
+    "teksavvy" = ps: with ps; [ ];
+    "telegram" = ps: with ps; [ pysocks aiohttp-cors python-telegram-bot];
+    "telegram_bot" = ps: with ps; [ pysocks aiohttp-cors python-telegram-bot];
+    "tellduslive" = ps: with ps; [ ]; # missing inputs: tellduslive
+    "tellstick" = ps: with ps; [ ]; # missing inputs: tellcore-net tellcore-py
+    "telnet" = ps: with ps; [ ];
+    "temper" = ps: with ps; [ ]; # missing inputs: temperusb
+    "template" = ps: with ps; [ ];
+    "tensorflow" = ps: with ps; [ numpy pillow protobuf tensorflow];
+    "tesla" = ps: with ps; [ ]; # missing inputs: teslajsonpy
+    "tfiac" = ps: with ps; [ ]; # missing inputs: pytfiac
+    "thermoworks_smoke" = ps: with ps; [ stringcase]; # missing inputs: thermoworks_smoke
+    "thethingsnetwork" = ps: with ps; [ ];
+    "thingspeak" = ps: with ps; [ ]; # missing inputs: thingspeak
+    "thinkingcleaner" = ps: with ps; [ ]; # missing inputs: pythinkingcleaner
+    "thomson" = ps: with ps; [ ];
+    "threshold" = ps: with ps; [ ];
+    "tibber" = ps: with ps; [ ]; # missing inputs: pyTibber
+    "tikteck" = ps: with ps; [ ]; # missing inputs: tikteck
+    "tile" = ps: with ps; [ ]; # missing inputs: pytile
+    "time_date" = ps: with ps; [ ];
+    "timer" = ps: with ps; [ ];
+    "tmb" = ps: with ps; [ ]; # missing inputs: tmb
+    "tod" = ps: with ps; [ ];
+    "todoist" = ps: with ps; [ todoist];
+    "tof" = ps: with ps; [ ]; # missing inputs: RPi.GPIO VL53L1X2
+    "tomato" = ps: with ps; [ ];
+    "toon" = ps: with ps; [ ]; # missing inputs: toonapilib
+    "torque" = ps: with ps; [ aiohttp-cors];
+    "totalconnect" = ps: with ps; [ ]; # missing inputs: total_connect_client
+    "touchline" = ps: with ps; [ ]; # missing inputs: pytouchline
+    "tplink" = ps: with ps; [ ]; # missing inputs: pyHS100
+    "tplink_lte" = ps: with ps; [ ]; # missing inputs: tp-connected
+    "traccar" = ps: with ps; [ aiohttp-cors stringcase]; # missing inputs: pytraccar
+    "trackr" = ps: with ps; [ ]; # missing inputs: pytrackr
+    "tradfri" = ps: with ps; [ ]; # missing inputs: pytradfri[async]
+    "trafikverket_train" = ps: with ps; [ ]; # missing inputs: pytrafikverket
+    "trafikverket_weatherstation" = ps: with ps; [ ]; # missing inputs: pytrafikverket
+    "transmission" = ps: with ps; [ transmissionrpc];
+    "transport_nsw" = ps: with ps; [ ]; # missing inputs: PyTransportNSW
+    "travisci" = ps: with ps; [ ]; # missing inputs: TravisPy
+    "trend" = ps: with ps; [ numpy];
+    "tts" = ps: with ps; [ aiohttp-cors mutagen];
+    "tuya" = ps: with ps; [ ]; # missing inputs: tuyaha
+    "twentemilieu" = ps: with ps; [ ]; # missing inputs: twentemilieu
+    "twilio" = ps: with ps; [ aiohttp-cors twilio];
+    "twilio_call" = ps: with ps; [ aiohttp-cors twilio];
+    "twilio_sms" = ps: with ps; [ aiohttp-cors twilio];
+    "twitch" = ps: with ps; [ ]; # missing inputs: python-twitch-client
+    "twitter" = ps: with ps; [ ]; # missing inputs: TwitterAPI
+    "ubee" = ps: with ps; [ ]; # missing inputs: pyubee
+    "ubus" = ps: with ps; [ ];
+    "ue_smart_radio" = ps: with ps; [ ];
+    "uk_transport" = ps: with ps; [ ];
+    "unifi" = ps: with ps; [ aiounifi];
+    "unifi_direct" = ps: with ps; [ pexpect];
+    "unifiled" = ps: with ps; [ ]; # missing inputs: unifiled
+    "universal" = ps: with ps; [ ];
+    "upc_connect" = ps: with ps; [ ]; # missing inputs: connect-box
+    "upcloud" = ps: with ps; [ ]; # missing inputs: upcloud-api
+    "updater" = ps: with ps; [ distro];
+    "upnp" = ps: with ps; [ ]; # missing inputs: async-upnp-client
+    "uptime" = ps: with ps; [ ];
+    "uptimerobot" = ps: with ps; [ ]; # missing inputs: pyuptimerobot
+    "uscis" = ps: with ps; [ ]; # missing inputs: uscisstatus
+    "usgs_earthquakes_feed" = ps: with ps; [ ]; # missing inputs: geojson_client
+    "utility_meter" = ps: with ps; [ ];
+    "uvc" = ps: with ps; [ ]; # missing inputs: uvcclient
+    "vacuum" = ps: with ps; [ ];
+    "vallox" = ps: with ps; [ ]; # missing inputs: vallox-websocket-api
+    "vasttrafik" = ps: with ps; [ ]; # missing inputs: vtjp
+    "velbus" = ps: with ps; [ ]; # missing inputs: python-velbus
+    "velux" = ps: with ps; [ ]; # missing inputs: pyvlx
+    "venstar" = ps: with ps; [ ]; # missing inputs: venstarcolortouch
+    "vera" = ps: with ps; [ ]; # missing inputs: pyvera
+    "verisure" = ps: with ps; [ jsonpath]; # missing inputs: vsure
+    "versasense" = ps: with ps; [ ]; # missing inputs: pyversasense
+    "version" = ps: with ps; [ pyhaversion];
+    "vesync" = ps: with ps; [ ]; # missing inputs: pyvesync
+    "viaggiatreno" = ps: with ps; [ ];
+    "vicare" = ps: with ps; [ ]; # missing inputs: PyViCare
+    "vilfo" = ps: with ps; [ ]; # missing inputs: vilfo-api-client
+    "vivotek" = ps: with ps; [ ]; # missing inputs: libpyvivotek
+    "vizio" = ps: with ps; [ ]; # missing inputs: pyvizio
+    "vlc" = ps: with ps; [ python-vlc];
+    "vlc_telnet" = ps: with ps; [ ]; # missing inputs: python-telnet-vlc
+    "voicerss" = ps: with ps; [ ];
+    "volkszaehler" = ps: with ps; [ ]; # missing inputs: volkszaehler
+    "volumio" = ps: with ps; [ ];
+    "volvooncall" = ps: with ps; [ ]; # missing inputs: volvooncall
+    "vultr" = ps: with ps; [ vultr];
+    "w800rf32" = ps: with ps; [ ]; # missing inputs: pyW800rf32
+    "wake_on_lan" = ps: with ps; [ wakeonlan];
+    "waqi" = ps: with ps; [ ]; # missing inputs: waqiasync
+    "water_heater" = ps: with ps; [ ];
+    "waterfurnace" = ps: with ps; [ ]; # missing inputs: waterfurnace
+    "watson_iot" = ps: with ps; [ ]; # missing inputs: ibmiotf
+    "watson_tts" = ps: with ps; [ ]; # missing inputs: ibm-watson
+    "waze_travel_time" = ps: with ps; [ WazeRouteCalculator];
+    "weather" = ps: with ps; [ ];
+    "webhook" = ps: with ps; [ aiohttp-cors];
+    "weblink" = ps: with ps; [ ];
+    "webostv" = ps: with ps; [ ]; # missing inputs: aiopylgtv
+    "websocket_api" = ps: with ps; [ aiohttp-cors];
+    "wemo" = ps: with ps; [ ]; # missing inputs: pywemo
+    "whois" = ps: with ps; [ ]; # missing inputs: python-whois
+    "wink" = ps: with ps; [ aiohttp-cors]; # missing inputs: pubnubsub-handler python-wink
+    "wirelesstag" = ps: with ps; [ ]; # missing inputs: wirelesstagpy
+    "withings" = ps: with ps; [ aiohttp-cors]; # missing inputs: withings-api
+    "wled" = ps: with ps; [ ]; # missing inputs: wled
+    "workday" = ps: with ps; [ holidays];
+    "worldclock" = ps: with ps; [ ];
+    "worldtidesinfo" = ps: with ps; [ ];
+    "worxlandroid" = ps: with ps; [ ];
+    "wsdot" = ps: with ps; [ ];
+    "wunderground" = ps: with ps; [ ];
+    "wunderlist" = ps: with ps; [ ]; # missing inputs: wunderpy2
+    "wwlln" = ps: with ps; [ ]; # missing inputs: aiowwlln
+    "x10" = ps: with ps; [ ];
+    "xbox_live" = ps: with ps; [ ]; # missing inputs: xboxapi
+    "xeoma" = ps: with ps; [ ]; # missing inputs: pyxeoma
+    "xfinity" = ps: with ps; [ ]; # missing inputs: xfinity-gateway
+    "xiaomi" = ps: with ps; [ ha-ffmpeg];
+    "xiaomi_aqara" = ps: with ps; [ ]; # missing inputs: PyXiaomiGateway
+    "xiaomi_miio" = ps: with ps; [ construct python-miio];
+    "xiaomi_tv" = ps: with ps; [ ]; # missing inputs: pymitv
+    "xmpp" = ps: with ps; [ slixmpp];
+    "xs1" = ps: with ps; [ ]; # missing inputs: xs1-api-client
+    "yale_smart_alarm" = ps: with ps; [ ]; # missing inputs: yalesmartalarmclient
+    "yamaha" = ps: with ps; [ rxv];
+    "yamaha_musiccast" = ps: with ps; [ ]; # missing inputs: pymusiccast
+    "yandex_transport" = ps: with ps; [ ]; # missing inputs: ya_ma
+    "yandextts" = ps: with ps; [ ];
+    "yeelight" = ps: with ps; [ ]; # missing inputs: yeelight
+    "yeelightsunflower" = ps: with ps; [ ]; # missing inputs: yeelightsunflower
+    "yessssms" = ps: with ps; [ ]; # missing inputs: YesssSMS
+    "yi" = ps: with ps; [ aioftp ha-ffmpeg];
+    "yr" = ps: with ps; [ xmltodict];
+    "yweather" = ps: with ps; [ yahooweather];
+    "zabbix" = ps: with ps; [ ]; # missing inputs: pyzabbix
+    "zamg" = ps: with ps; [ ];
+    "zengge" = ps: with ps; [ ]; # missing inputs: zengge
+    "zeroconf" = ps: with ps; [ aiohttp-cors zeroconf];
+    "zestimate" = ps: with ps; [ xmltodict];
+    "zha" = ps: with ps; [ zha-quirks zigpy-deconz zigpy]; # missing inputs: bellows-homeassistant zigpy-cc zigpy-xbee-homeassistant zigpy-zigate
+    "zhong_hong" = ps: with ps; [ ]; # missing inputs: zhong_hong_hvac
+    "zigbee" = ps: with ps; [ ]; # missing inputs: xbee-helper
+    "ziggo_mediabox_xl" = ps: with ps; [ ]; # missing inputs: ziggo-mediabox-xl
+    "zone" = ps: with ps; [ ];
+    "zoneminder" = ps: with ps; [ zm-py];
+    "zwave" = ps: with ps; [ homeassistant-pyozw pydispatcher];
   };
 }
diff --git a/nixpkgs/pkgs/servers/home-assistant/default.nix b/nixpkgs/pkgs/servers/home-assistant/default.nix
index 8e83d7f15da4..2b571fe96bfc 100644
--- a/nixpkgs/pkgs/servers/home-assistant/default.nix
+++ b/nixpkgs/pkgs/servers/home-assistant/default.nix
@@ -27,9 +27,6 @@ let
     (mkOverride "colorlog" "4.0.2"
       "3cf31b25cbc8f86ec01fef582ef3b840950dea414084ed19ab922c8b493f9b42")
 
-    (mkOverride "pyyaml" "5.1.2"
-      "1r5faspz73477hlbjgilw05xsms0glmsa371yqdd26znqsvg1b81")
-
     # required by aioesphomeapi
     (self: super: {
       protobuf = super.protobuf.override {
@@ -70,7 +67,7 @@ let
   extraBuildInputs = extraPackages py.pkgs;
 
   # Don't forget to run parse-requirements.py after updating
-  hassVersion = "0.103.6";
+  hassVersion = "0.106.6";
 
 in with py.pkgs; buildPythonApplication rec {
   pname = "homeassistant";
@@ -78,6 +75,8 @@ in with py.pkgs; buildPythonApplication rec {
 
   disabled = pythonOlder "3.5";
 
+  patches = [ ./relax-importlib-metadata-pyaml.patch ];
+
   inherit availableComponents;
 
   # PyPI tarball is missing tests/ directory
@@ -85,7 +84,7 @@ in with py.pkgs; buildPythonApplication rec {
     owner = "home-assistant";
     repo = "home-assistant";
     rev = version;
-    sha256 = "1492q4icyhvz30fw5ysrwlnsls4iy5pv62ay3vq1ygcfnlapkqhl";
+    sha256 = "11kv5lmm8nxp7yv3w43mzmgzkafddy0z6wl2878p96iyil1w7qhb";
   };
 
   propagatedBuildInputs = [
@@ -98,15 +97,8 @@ in with py.pkgs; buildPythonApplication rec {
   ] ++ componentBuildInputs ++ extraBuildInputs;
 
   checkInputs = [
-    asynctest pytest pytest-aiohttp requests-mock pydispatcher aiohue netdisco hass-nabucasa
-  ];
-
-  patches = [
-    # newer importlib-metadata version
-    (fetchpatch {
-      url = "https://github.com/home-assistant/home-assistant/commit/63c6b803dc2d835d57b97ed833ee5cd8318bf7ae.patch";
-      sha256 = "16q3qdnmgsw5415f70zvsv1z63dljp3c9glv06cyj4s6qsl13xdc";
-    })
+    asynctest pytest pytest-aiohttp requests-mock pydispatcher aiohue netdisco
+    hass-nabucasa defusedxml
   ];
 
   postPatch = ''
diff --git a/nixpkgs/pkgs/servers/home-assistant/frontend.nix b/nixpkgs/pkgs/servers/home-assistant/frontend.nix
index 75d02ed06351..1446518fbc5c 100644
--- a/nixpkgs/pkgs/servers/home-assistant/frontend.nix
+++ b/nixpkgs/pkgs/servers/home-assistant/frontend.nix
@@ -4,11 +4,11 @@ buildPythonPackage rec {
   # the frontend version corresponding to a specific home-assistant version can be found here
   # https://github.com/home-assistant/home-assistant/blob/master/homeassistant/components/frontend/manifest.json
   pname = "home-assistant-frontend";
-  version = "20200108.0";
+  version = "20200220.5";
 
   src = fetchPypi {
     inherit pname version;
-    sha256 = "1h6fgkx8fffzs829893gjbh0wbjgxjzz2ca64v8r5sb938bfayg8";
+    sha256 = "0nc44r5ybq0prsz2yid622i0xr7q0qrc4ymbk69bqg6jrmjpbdl1";
   };
 
   # no Python tests implemented
diff --git a/nixpkgs/pkgs/servers/home-assistant/parse-requirements.py b/nixpkgs/pkgs/servers/home-assistant/parse-requirements.py
index 96cf1d86050e..a5c6e9d09614 100755
--- a/nixpkgs/pkgs/servers/home-assistant/parse-requirements.py
+++ b/nixpkgs/pkgs/servers/home-assistant/parse-requirements.py
@@ -1,5 +1,5 @@
 #! /usr/bin/env nix-shell
-#! nix-shell -i python3 -p "python3.withPackages (ps: with ps; [ attrs ])
+#! nix-shell -i python3 -p "python3.withPackages (ps: with ps; [ mypy attrs ])
 #
 # This script downloads Home Assistant's source tarball.
 # Inside the homeassistant/components directory, each integration has an associated manifest.json,
@@ -15,125 +15,168 @@
 # nixpkgs' python3Packages are searched for appropriate names.
 # Then, a Nix attribute set mapping integration name to dependencies is created.
 
-from io import BytesIO
 import json
-import pathlib
 import os
+import pathlib
 import re
 import subprocess
 import sys
-import tempfile
 import tarfile
+import tempfile
+from io import BytesIO
+from typing import Dict, Optional
 from urllib.request import urlopen
 
-COMPONENT_PREFIX = 'homeassistant.components'
-PKG_SET = 'python3Packages'
+COMPONENT_PREFIX = "homeassistant.components"
+PKG_SET = "python3Packages"
 
 # If some requirements are matched by multiple python packages,
 # the following can be used to choose one of them
 PKG_PREFERENCES = {
     # Use python3Packages.youtube-dl-light instead of python3Packages.youtube-dl
-    'youtube-dl': 'youtube-dl-light',
-    'tensorflow-bin': 'tensorflow',
-    'tensorflowWithoutCuda': 'tensorflow'
+    "youtube-dl": "youtube-dl-light",
+    "tensorflow-bin": "tensorflow",
+    "tensorflowWithoutCuda": "tensorflow",
 }
 
+
+def run_mypy() -> None:
+    cmd = ["mypy", "--ignore-missing-imports", __file__]
+    print(f"$ {' '.join(cmd)}")
+    subprocess.run(cmd, check=True)
+
+
 def get_version():
-    with open(os.path.dirname(sys.argv[0]) + '/default.nix') as f:
+    with open(os.path.dirname(sys.argv[0]) + "/default.nix") as f:
         # A version consists of digits, dots, and possibly a "b" (for beta)
         m = re.search('hassVersion = "([\\d\\.b]+)";', f.read())
         return m.group(1)
 
-def parse_components(version='master'):
+
+def parse_components(version: str = "master"):
     components = {}
     with tempfile.TemporaryDirectory() as tmp:
-        with urlopen(f'https://github.com/home-assistant/home-assistant/archive/{version}.tar.gz') as response:
+        with urlopen(
+            f"https://github.com/home-assistant/home-assistant/archive/{version}.tar.gz"
+        ) as response:
             tarfile.open(fileobj=BytesIO(response.read())).extractall(tmp)
         # Use part of a script from the Home Assistant codebase
-        sys.path.append(os.path.join(tmp, f'home-assistant-{version}'))
+        core_path = os.path.join(tmp, f"core-{version}")
+        sys.path.append(core_path)
         from script.hassfest.model import Integration
-        integrations = Integration.load_dir(pathlib.Path(
-            os.path.join(tmp, f'home-assistant-{version}', 'homeassistant/components')
-        ))
+
+        integrations = Integration.load_dir(
+            pathlib.Path(
+                os.path.join(core_path, "homeassistant/components")
+            )
+        )
         for domain in sorted(integrations):
             integration = integrations[domain]
             components[domain] = integration.manifest
     return components
 
+
 # Recursively get the requirements of a component and its dependencies
 def get_reqs(components, component):
-    requirements = set(components[component]['requirements'])
-    for dependency in components[component]['dependencies']:
+    requirements = set(components[component]["requirements"])
+    for dependency in components[component]["dependencies"]:
         requirements.update(get_reqs(components, dependency))
     return requirements
 
-# Store a JSON dump of Nixpkgs' python3Packages
-output = subprocess.check_output(['nix-env', '-f', os.path.dirname(sys.argv[0]) + '/../../..', '-qa', '-A', PKG_SET, '--json'])
-packages = json.loads(output)
 
-def name_to_attr_path(req):
+def dump_packages() -> Dict[str, Dict[str, str]]:
+    # Store a JSON dump of Nixpkgs' python3Packages
+    output = subprocess.check_output(
+        [
+            "nix-env",
+            "-f",
+            os.path.dirname(sys.argv[0]) + "/../../..",
+            "-qa",
+            "-A",
+            PKG_SET,
+            "--json",
+        ]
+    )
+    return json.loads(output)
+
+
+def name_to_attr_path(req: str, packages: Dict[str, Dict[str, str]]) -> Optional[str]:
     attr_paths = set()
     names = [req]
     # E.g. python-mpd2 is actually called python3.6-mpd2
     # instead of python-3.6-python-mpd2 inside Nixpkgs
-    if req.startswith('python-') or req.startswith('python_'):
-        names.append(req[len('python-'):])
+    if req.startswith("python-") or req.startswith("python_"):
+        names.append(req[len("python-") :])
     for name in names:
         # treat "-" and "_" equally
-        name = re.sub('[-_]', '[-_]', name)
-        pattern = re.compile('^python\\d\\.\\d-{}-\\d'.format(name), re.I)
+        name = re.sub("[-_]", "[-_]", name)
+        pattern = re.compile("^python\\d\\.\\d-{}-\\d".format(name), re.I)
         for attr_path, package in packages.items():
-            if pattern.match(package['name']):
+            if pattern.match(package["name"]):
                 attr_paths.add(attr_path)
     if len(attr_paths) > 1:
         for to_replace, replacement in PKG_PREFERENCES.items():
             try:
-                attr_paths.remove(PKG_SET + '.' + to_replace)
-                attr_paths.add(PKG_SET + '.' + replacement)
+                attr_paths.remove(PKG_SET + "." + to_replace)
+                attr_paths.add(PKG_SET + "." + replacement)
             except KeyError:
                 pass
     # Let's hope there's only one derivation with a matching name
-    assert len(attr_paths) <= 1, "{} matches more than one derivation: {}".format(req, attr_paths)
+    assert len(attr_paths) <= 1, "{} matches more than one derivation: {}".format(
+        req, attr_paths
+    )
     if len(attr_paths) == 1:
         return attr_paths.pop()
     else:
         return None
 
-version = get_version()
-print('Generating component-packages.nix for version {}'.format(version))
-components = parse_components(version=version)
-build_inputs = {}
-for component in sorted(components.keys()):
-    attr_paths = []
-    missing_reqs = []
-    reqs = sorted(get_reqs(components, component))
-    for req in reqs:
-        # Some requirements are specified by url, e.g. https://example.org/foobar#xyz==1.0.0
-        # Therefore, if there's a "#" in the line, only take the part after it
-        req = req[req.find('#') + 1:]
-        name = req.split('==')[0]
-        attr_path = name_to_attr_path(name)
-        if attr_path is not None:
-            # Add attribute path without "python3Packages." prefix
-            attr_paths.append(attr_path[len(PKG_SET + '.'):])
+
+def main() -> None:
+    packages = dump_packages()
+    version = get_version()
+    print("Generating component-packages.nix for version {}".format(version))
+    components = parse_components(version=version)
+    build_inputs = {}
+    for component in sorted(components.keys()):
+        attr_paths = []
+        missing_reqs = []
+        reqs = sorted(get_reqs(components, component))
+        for req in reqs:
+            # Some requirements are specified by url, e.g. https://example.org/foobar#xyz==1.0.0
+            # Therefore, if there's a "#" in the line, only take the part after it
+            req = req[req.find("#") + 1 :]
+            name = req.split("==")[0]
+            attr_path = name_to_attr_path(name, packages)
+            if attr_path is not None:
+                # Add attribute path without "python3Packages." prefix
+                attr_paths.append(attr_path[len(PKG_SET + ".") :])
+            else:
+                missing_reqs.append(name)
         else:
-            missing_reqs.append(name)
-    else:
-        build_inputs[component] = attr_paths
-    n_diff = len(reqs) > len(build_inputs[component])
-    if n_diff > 0:
-        print("Component {} is missing {} dependencies".format(component, n_diff))
-        print("missing requirements: {}".format(missing_reqs))
-
-with open(os.path.dirname(sys.argv[0]) + '/component-packages.nix', 'w') as f:
-    f.write('# Generated by parse-requirements.py\n')
-    f.write('# Do not edit!\n\n')
-    f.write('{\n')
-    f.write('  version = "{}";\n'.format(version))
-    f.write('  components = {\n')
-    for component, attr_paths in build_inputs.items():
-        f.write('    "{}" = ps: with ps; [ '.format(component))
-        f.write(' '.join(attr_paths))
-        f.write(' ];\n')
-    f.write('  };\n')
-    f.write('}\n')
+            build_inputs[component] = (attr_paths, missing_reqs)
+        n_diff = len(reqs) > len(build_inputs[component])
+        if n_diff > 0:
+            print("Component {} is missing {} dependencies".format(component, n_diff))
+            print("missing requirements: {}".format(missing_reqs))
+
+    with open(os.path.dirname(sys.argv[0]) + "/component-packages.nix", "w") as f:
+        f.write("# Generated by parse-requirements.py\n")
+        f.write("# Do not edit!\n\n")
+        f.write("{\n")
+        f.write(f'  version = "{version}";\n')
+        f.write("  components = {\n")
+        for component, deps in build_inputs.items():
+            available, missing = deps
+            f.write(f'    "{component}" = ps: with ps; [ ')
+            f.write(" ".join(available))
+            f.write("];")
+            if len(missing) > 0:
+                f.write(f" # missing inputs: {' '.join(missing)}")
+            f.write("\n")
+        f.write("  };\n")
+        f.write("}\n")
+
+
+if __name__ == "__main__":
+    run_mypy()
+    main()
diff --git a/nixpkgs/pkgs/servers/home-assistant/relax-importlib-metadata-pyaml.patch b/nixpkgs/pkgs/servers/home-assistant/relax-importlib-metadata-pyaml.patch
new file mode 100644
index 000000000000..d35e05c6cd78
--- /dev/null
+++ b/nixpkgs/pkgs/servers/home-assistant/relax-importlib-metadata-pyaml.patch
@@ -0,0 +1,22 @@
+diff --git a/setup.py b/setup.py
+index 7f9155d9a..f90a0d965 100755
+--- a/setup.py
++++ b/setup.py
+@@ -38,7 +38,7 @@ REQUIRES = [
+     "attrs==19.3.0",
+     "bcrypt==3.1.7",
+     "certifi>=2019.11.28",
+-    "importlib-metadata==1.5.0",
++    "importlib-metadata>=1.3.0",
+     "jinja2>=2.10.3",
+     "PyJWT==1.7.1",
+     # PyJWT has loose dependency. We want the latest one.
+@@ -46,7 +46,7 @@ REQUIRES = [
+     "pip>=8.0.3",
+     "python-slugify==4.0.0",
+     "pytz>=2019.03",
+-    "pyyaml==5.3",
++    "pyyaml>=5.2",
+     "requests==2.22.0",
+     "ruamel.yaml==0.15.100",
+     "voluptuous==0.11.7",