diff --git a/homeassistant/components/adguard/manifest.json b/homeassistant/components/adguard/manifest.json index cf1210b0884..91e1393c734 100644 --- a/homeassistant/components/adguard/manifest.json +++ b/homeassistant/components/adguard/manifest.json @@ -6,5 +6,6 @@ "requirements": ["adguardhome==0.5.1"], "codeowners": ["@frenck"], "iot_class": "local_polling", + "integration_type": "service", "loggers": ["adguardhome"] } diff --git a/homeassistant/components/config/config_entries.py b/homeassistant/components/config/config_entries.py index 6f2320a2e93..50bcad45db7 100644 --- a/homeassistant/components/config/config_entries.py +++ b/homeassistant/components/config/config_entries.py @@ -15,6 +15,7 @@ from homeassistant.components import websocket_api from homeassistant.components.http import HomeAssistantView from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import DependencyError, Unauthorized +import homeassistant.helpers.config_validation as cv from homeassistant.helpers.data_entry_flow import ( FlowManagerIndexView, FlowManagerResourceView, @@ -64,7 +65,7 @@ class ConfigManagerEntryIndexView(HomeAssistantView): domain = request.query["domain"] type_filter = None if "type" in request.query: - type_filter = request.query["type"] + type_filter = [request.query["type"]] return self.json(await async_matching_config_entries(hass, type_filter, domain)) @@ -405,7 +406,7 @@ async def ignore_config_flow( @websocket_api.websocket_command( { vol.Required("type"): "config_entries/get", - vol.Optional("type_filter"): str, + vol.Optional("type_filter"): vol.All(cv.ensure_list, [str]), vol.Optional("domain"): str, } ) @@ -427,7 +428,7 @@ async def config_entries_get( @websocket_api.websocket_command( { vol.Required("type"): "config_entries/subscribe", - vol.Optional("type_filter"): str, + vol.Optional("type_filter"): vol.All(cv.ensure_list, [str]), } ) @websocket_api.async_response @@ -445,7 +446,7 @@ async def config_entries_subscribe( """Forward config entry state events to websocket.""" if type_filter: integration = await async_get_integration(hass, entry.domain) - if integration.integration_type != type_filter: + if integration.integration_type not in type_filter: return connection.send_message( @@ -475,7 +476,7 @@ async def config_entries_subscribe( async def async_matching_config_entries( - hass: HomeAssistant, type_filter: str | None, domain: str | None + hass: HomeAssistant, type_filter: list[str] | None, domain: str | None ) -> list[dict[str, Any]]: """Return matching config entries by type and/or domain.""" kwargs = {} @@ -483,7 +484,7 @@ async def async_matching_config_entries( kwargs["domain"] = domain entries = hass.config_entries.async_entries(**kwargs) - if type_filter is None: + if not type_filter: return [entry_json(entry) for entry in entries] integrations = {} @@ -499,13 +500,17 @@ async def async_matching_config_entries( elif not isinstance(integration_or_exc, IntegrationNotFound): raise integration_or_exc + # Filter out entries that don't match the type filter + # when only helpers are requested, also filter out entries + # from unknown integrations. This prevent them from showing + # up in the helpers UI. entries = [ entry for entry in entries - if (type_filter != "helper" and entry.domain not in integrations) + if (type_filter != ["helper"] and entry.domain not in integrations) or ( entry.domain in integrations - and integrations[entry.domain].integration_type == type_filter + and integrations[entry.domain].integration_type in type_filter ) ] diff --git a/homeassistant/components/esphome/manifest.json b/homeassistant/components/esphome/manifest.json index 3ffceaae971..75aad44894f 100644 --- a/homeassistant/components/esphome/manifest.json +++ b/homeassistant/components/esphome/manifest.json @@ -9,5 +9,6 @@ "codeowners": ["@OttoWinter", "@jesserockz"], "after_dependencies": ["bluetooth", "zeroconf", "tag"], "iot_class": "local_push", + "integration_type": "device", "loggers": ["aioesphomeapi", "noiseprotocol"] } diff --git a/homeassistant/components/hue/manifest.json b/homeassistant/components/hue/manifest.json index 3854b861c98..d726f773b9b 100644 --- a/homeassistant/components/hue/manifest.json +++ b/homeassistant/components/hue/manifest.json @@ -25,5 +25,6 @@ "codeowners": ["@balloob", "@marcelveldt"], "quality_scale": "platinum", "iot_class": "local_push", + "integration_type": "hub", "loggers": ["aiohue"] } diff --git a/homeassistant/generated/integrations.json b/homeassistant/generated/integrations.json index 9e8441dd242..f4c3c9cc76b 100644 --- a/homeassistant/generated/integrations.json +++ b/homeassistant/generated/integrations.json @@ -3,71 +3,85 @@ "abode": { "config_flow": true, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Abode" }, "accuweather": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "AccuWeather" }, "acer_projector": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Acer Projector" }, "acmeda": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Rollease Acmeda Automate" }, "actiontec": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Actiontec" }, "adax": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Adax" }, "adguard": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "service", "name": "AdGuard Home" }, "ads": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "ADS" }, "advantage_air": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Advantage Air" }, "aemet": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "AEMET OpenData" }, "aftership": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "AfterShip" }, "agent_dvr": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Agent DVR" }, "airly": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Airly" }, "airnow": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "AirNow" }, "airthings": { @@ -76,11 +90,13 @@ "airthings": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Airthings" }, "airthings_ble": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Airthings BLE" } } @@ -88,41 +104,49 @@ "airtouch4": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "AirTouch 4" }, "airvisual": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "AirVisual" }, "airzone": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Airzone" }, "aladdin_connect": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Aladdin Connect" }, "alarmdecoder": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "AlarmDecoder" }, "alert": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Alert" }, "almond": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Almond" }, "alpha_vantage": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Alpha Vantage" }, "amazon": { @@ -131,21 +155,25 @@ "alexa": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Amazon Alexa" }, "amazon_polly": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Amazon Polly" }, "aws": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Amazon Web Services (AWS)" }, "route53": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "AWS Route53" } } @@ -153,56 +181,67 @@ "amberelectric": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Amber Electric" }, "ambiclimate": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Ambiclimate" }, "ambient_station": { "config_flow": true, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Ambient Weather Station" }, "amcrest": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Amcrest" }, "ampio": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Ampio Smart Smog System" }, "android_ip_webcam": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Android IP Webcam" }, "androidtv": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Android TV" }, "anel_pwrctrl": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Anel NET-PwrCtrl" }, "anthemav": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Anthem A/V Receivers" }, "apache_kafka": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Apache Kafka" }, "apcupsd": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "APC UPS Daemon" }, "apple": { @@ -211,30 +250,36 @@ "apple_tv": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Apple TV" }, "homekit_controller": { "config_flow": true, - "iot_class": "local_push" + "iot_class": "local_push", + "integration_type": "hub" }, "homekit": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "HomeKit" }, "ibeacon": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "iBeacon Tracker" }, "icloud": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Apple iCloud" }, "itunes": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Apple iTunes" } } @@ -242,36 +287,43 @@ "apprise": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Apprise" }, "aprs": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "APRS" }, "aqualogic": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "AquaLogic" }, "aquostv": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Sharp Aquos TV" }, "arcam_fmj": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Arcam FMJ Receivers" }, "arest": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "aREST" }, "arris_tg2492lg": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Arris TG2492LG" }, "aruba": { @@ -280,11 +332,13 @@ "aruba": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Aruba" }, "cppm_tracker": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Aruba ClearPass" } } @@ -292,11 +346,13 @@ "arwn": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Ambient Radio Weather Network" }, "aseko_pool_live": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Aseko Pool Live" }, "asterisk": { @@ -305,11 +361,13 @@ "asterisk_cdr": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Asterisk Call Detail Records" }, "asterisk_mbox": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Asterisk Voicemail" } } @@ -317,21 +375,25 @@ "asuswrt": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "ASUSWRT" }, "atag": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Atag" }, "aten_pe": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "ATEN Rack PDU" }, "atome": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Atome Linky" }, "august": { @@ -340,226 +402,271 @@ "august": { "config_flow": true, "iot_class": "cloud_push", + "integration_type": "hub", "name": "August" }, "yalexs_ble": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Yale Access Bluetooth" } } }, "aurora": { "config_flow": true, - "iot_class": "cloud_polling" + "iot_class": "cloud_polling", + "integration_type": "hub" }, "aurora_abb_powerone": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Aurora ABB PowerOne Solar PV" }, "aussie_broadband": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Aussie Broadband" }, "avion": { "config_flow": false, "iot_class": "assumed_state", + "integration_type": "hub", "name": "Avi-on" }, "awair": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Awair" }, "axis": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Axis" }, "baf": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Big Ass Fans" }, "baidu": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Baidu" }, "balboa": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Balboa Spa Client" }, "bayesian": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Bayesian" }, "bbox": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Bbox" }, "beewi_smartclim": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "BeeWi SmartClim BLE sensor" }, "bitcoin": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Bitcoin" }, "bizkaibus": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Bizkaibus" }, "blackbird": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Monoprice Blackbird Matrix Switch" }, "blebox": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "BleBox devices" }, "blink": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Blink" }, "blinksticklight": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "BlinkStick" }, "blockchain": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Blockchain.com" }, "bloomsky": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "BloomSky" }, "bluemaestro": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "BlueMaestro" }, "bluesound": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Bluesound" }, "bluetooth": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Bluetooth" }, "bluetooth_le_tracker": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Bluetooth LE Tracker" }, "bluetooth_tracker": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Bluetooth Tracker" }, "bmw_connected_drive": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "BMW Connected Drive" }, "bond": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Bond" }, "bosch_shc": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Bosch SHC" }, "broadlink": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Broadlink" }, "brother": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Brother Printer" }, "brottsplatskartan": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Brottsplatskartan" }, "browser": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Browser" }, "brunt": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Brunt Blind Engine" }, "bsblan": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "BSB-Lan" }, "bt_home_hub_5": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "BT Home Hub 5" }, "bt_smarthub": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "BT Smart Hub" }, "bthome": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "BTHome" }, "buienradar": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Buienradar" }, "caldav": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "CalDAV" }, "canary": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Canary" }, "cert_expiry": { "config_flow": true, - "iot_class": "cloud_polling" + "iot_class": "cloud_polling", + "integration_type": "hub" }, "channels": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Channels" }, "circuit": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Unify Circuit" }, "cisco": { @@ -568,16 +675,19 @@ "cisco_ios": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Cisco IOS" }, "cisco_mobility_express": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Cisco Mobility Express" }, "cisco_webex_teams": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Cisco Webex Teams" } } @@ -585,16 +695,19 @@ "citybikes": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "CityBikes" }, "clementine": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Clementine Music Player" }, "clickatell": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Clickatell" }, "clicksend": { @@ -603,11 +716,13 @@ "clicksend": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "ClickSend SMS" }, "clicksend_tts": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "ClickSend TTS" } } @@ -615,150 +730,180 @@ "cloud": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Home Assistant Cloud" }, "cloudflare": { "config_flow": true, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Cloudflare" }, "cmus": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "cmus" }, "co2signal": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "CO2 Signal" }, "coinbase": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Coinbase" }, "color_extractor": { "config_flow": false, "iot_class": null, + "integration_type": "hub", "name": "ColorExtractor" }, "comed_hourly_pricing": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "ComEd Hourly Pricing" }, "comfoconnect": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Zehnder ComfoAir Q" }, "command_line": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Command Line" }, "compensation": { "config_flow": false, "iot_class": "calculated", + "integration_type": "hub", "name": "Compensation" }, "concord232": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Concord232" }, "control4": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Control4" }, "coolmaster": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "CoolMasterNet" }, "coronavirus": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Coronavirus (COVID-19)" }, "cpuspeed": { "config_flow": true, - "iot_class": "local_push" + "iot_class": "local_push", + "integration_type": "hub" }, "crownstone": { "config_flow": true, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Crownstone" }, "cups": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "CUPS" }, "currencylayer": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "currencylayer" }, "daikin": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Daikin AC" }, "danfoss_air": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Danfoss Air" }, "darksky": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Dark Sky" }, "datadog": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Datadog" }, "ddwrt": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "DD-WRT" }, "debugpy": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Remote Python Debugger" }, "deconz": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "deCONZ" }, "decora": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Leviton Decora" }, "decora_wifi": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Leviton Decora Wi-Fi" }, "delijn": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "De Lijn" }, "deluge": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Deluge" }, "demo": { "config_flow": false, - "iot_class": "calculated" + "iot_class": "calculated", + "integration_type": "hub" }, "denon": { "name": "Denon", @@ -766,16 +911,19 @@ "denon": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Denon Network Receivers" }, "denonavr": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Denon AVR Network Receivers" }, "heos": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Denon HEOS" } } @@ -783,11 +931,13 @@ "deutsche_bahn": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Deutsche Bahn" }, "device_sun_light_trigger": { "config_flow": false, "iot_class": "calculated", + "integration_type": "hub", "name": "Presence-based Lights" }, "devolo": { @@ -796,11 +946,13 @@ "devolo_home_control": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "devolo Home Control" }, "devolo_home_network": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "devolo Home Network" } } @@ -808,41 +960,49 @@ "dexcom": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Dexcom" }, "digital_ocean": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Digital Ocean" }, "directv": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "DirecTV" }, "discogs": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Discogs" }, "discord": { "config_flow": true, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Discord" }, "dlib_face_detect": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Dlib Face Detect" }, "dlib_face_identify": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Dlib Face Identify" }, "dlink": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "D-Link Wi-Fi Smart Plugs" }, "dlna": { @@ -851,11 +1011,13 @@ "dlna_dmr": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "DLNA Digital Media Renderer" }, "dlna_dms": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "DLNA Digital Media Server" } } @@ -863,141 +1025,169 @@ "dnsip": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "DNS IP" }, "dominos": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Dominos Pizza" }, "doods": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "DOODS - Dedicated Open Object Detection Service" }, "doorbird": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "DoorBird" }, "dovado": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Dovado" }, "downloader": { "config_flow": false, "iot_class": null, + "integration_type": "hub", "name": "Downloader" }, "dsmr": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "DSMR Slimme Meter" }, "dsmr_reader": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "DSMR Reader" }, "dte_energy_bridge": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "DTE Energy Bridge" }, "dublin_bus_transport": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Dublin Bus" }, "duckdns": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Duck DNS" }, "dunehd": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Dune HD" }, "dwd_weather_warnings": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Deutscher Wetterdienst (DWD) Weather Warnings" }, "dweet": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "dweet.io" }, "eafm": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Environment Agency Flood Gauges" }, "ebox": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "EBox" }, "ebusd": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "ebusd" }, "ecoal_boiler": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "eSterownik eCoal.pl Boiler" }, "ecobee": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "ecobee" }, "econet": { "config_flow": true, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Rheem EcoNet Products" }, "ecovacs": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Ecovacs" }, "ecowitt": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Ecowitt" }, "eddystone_temperature": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Eddystone" }, "edimax": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Edimax" }, "edl21": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "EDL21" }, "efergy": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Efergy" }, "egardia": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Egardia" }, "eight_sleep": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Eight Sleep" }, "elgato": { @@ -1006,11 +1196,13 @@ "avea": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Elgato Avea" }, "elgato": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Elgato Light" } } @@ -1018,26 +1210,31 @@ "eliqonline": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Eliqonline" }, "elkm1": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Elk-M1 Control" }, "elmax": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Elmax" }, "elv": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "ELV PCA" }, "emby": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Emby" }, "emoncms": { @@ -1046,11 +1243,13 @@ "emoncms": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Emoncms" }, "emoncms_history": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Emoncms History" } } @@ -1058,55 +1257,66 @@ "emonitor": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "SiteSage Emonitor" }, "emulated_hue": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Emulated Hue" }, "emulated_kasa": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Emulated Kasa" }, "emulated_roku": { "config_flow": true, - "iot_class": "local_push" + "iot_class": "local_push", + "integration_type": "hub" }, "enigma2": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Enigma2 (OpenWebif)" }, "enocean": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "EnOcean" }, "enphase_envoy": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Enphase Envoy" }, "entur_public_transport": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Entur" }, "environment_canada": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Environment Canada" }, "envisalink": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Envisalink" }, "ephember": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "EPH Controls" }, "epson": { @@ -1115,11 +1325,13 @@ "epson": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Epson" }, "epsonworkforce": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Epson Workforce" } } @@ -1130,11 +1342,13 @@ "eq3btsmart": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "eQ-3 Bluetooth Smart Thermostats" }, "maxcube": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "eQ-3 MAX!" } } @@ -1142,66 +1356,79 @@ "escea": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Escea" }, "esphome": { "config_flow": true, "iot_class": "local_push", + "integration_type": "device", "name": "ESPHome" }, "etherscan": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Etherscan" }, "eufy": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "eufy" }, "everlights": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "EverLights" }, "evil_genius_labs": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Evil Genius Labs" }, "ezviz": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "EZVIZ" }, "faa_delays": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "FAA Delays" }, "facebook": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Facebook Messenger" }, "facebox": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Facebox" }, "fail2ban": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Fail2Ban" }, "fastdotcom": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Fast.com" }, "feedreader": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Feedreader" }, "ffmpeg": { @@ -1210,16 +1437,19 @@ "ffmpeg": { "config_flow": false, "iot_class": null, + "integration_type": "hub", "name": "FFmpeg" }, "ffmpeg_motion": { "config_flow": false, "iot_class": "calculated", + "integration_type": "hub", "name": "FFmpeg Motion" }, "ffmpeg_noise": { "config_flow": false, "iot_class": "calculated", + "integration_type": "hub", "name": "FFmpeg Noise" } } @@ -1227,170 +1457,204 @@ "fibaro": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Fibaro" }, "fido": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Fido" }, "file": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "File" }, "filesize": { "config_flow": true, - "iot_class": "local_polling" + "iot_class": "local_polling", + "integration_type": "hub" }, "filter": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Filter" }, "fints": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "FinTS" }, "fireservicerota": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "FireServiceRota" }, "firmata": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Firmata" }, "fitbit": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Fitbit" }, "fivem": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "FiveM" }, "fixer": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Fixer" }, "fjaraskupan": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Fj\u00e4r\u00e5skupan" }, "fleetgo": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "FleetGO" }, "flexit": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Flexit" }, "flic": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Flic" }, "flick_electric": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Flick Electric" }, "flipr": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Flipr" }, "flo": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Flo" }, "flock": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Flock" }, "flume": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Flume" }, "flux": { "config_flow": false, "iot_class": "calculated", + "integration_type": "hub", "name": "Flux" }, "flux_led": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Magic Home" }, "folder": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Folder" }, "folder_watcher": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Folder Watcher" }, "foobot": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Foobot" }, "forecast_solar": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Forecast.Solar" }, "forked_daapd": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Owntone" }, "fortios": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "FortiOS" }, "foscam": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Foscam" }, "foursquare": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Foursquare" }, "free_mobile": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Free Mobile" }, "freebox": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Freebox" }, "freedns": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "FreeDNS" }, "freedompro": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Freedompro" }, "fritzbox": { @@ -1399,16 +1663,19 @@ "fritz": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "AVM FRITZ!Box Tools" }, "fritzbox": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "AVM FRITZ!SmartHome" }, "fritzbox_callmonitor": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "AVM FRITZ!Box Call Monitor" } } @@ -1416,75 +1683,90 @@ "fronius": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Fronius" }, "frontier_silicon": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Frontier Silicon" }, "fully_kiosk": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Fully Kiosk Browser" }, "futurenow": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "P5 FutureNow" }, "garadget": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Garadget" }, "garages_amsterdam": { "config_flow": true, - "iot_class": "cloud_polling" + "iot_class": "cloud_polling", + "integration_type": "hub" }, "gdacs": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Global Disaster Alert and Coordination System (GDACS)" }, "generic": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Generic Camera" }, "generic_hygrostat": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Generic hygrostat" }, "generic_thermostat": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Generic Thermostat" }, "geniushub": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Genius Hub" }, "geo_json_events": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "GeoJSON" }, "geo_rss_events": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "GeoRSS" }, "geocaching": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Geocaching" }, "geofency": { "config_flow": true, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Geofency" }, "geonet": { @@ -1493,11 +1775,13 @@ "geonetnz_quakes": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "GeoNet NZ Quakes" }, "geonetnz_volcano": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "GeoNet NZ Volcano" } } @@ -1505,26 +1789,31 @@ "gios": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "GIO\u015a" }, "github": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "GitHub" }, "gitlab_ci": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "GitLab-CI" }, "gitter": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Gitter" }, "glances": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Glances" }, "globalcache": { @@ -1533,11 +1822,13 @@ "gc100": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Global Cach\u00e9 GC-100" }, "itach": { "config_flow": false, "iot_class": "assumed_state", + "integration_type": "hub", "name": "Global Cach\u00e9 iTach TCP/IP to IR" } } @@ -1545,21 +1836,25 @@ "goalfeed": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Goalfeed" }, "goalzero": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Goal Zero Yeti" }, "gogogate2": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Gogogate2 and ismartgate" }, "goodwe": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "GoodWe Inverter" }, "google": { @@ -1568,70 +1863,84 @@ "google_assistant": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Google Assistant" }, "google_cloud": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Google Cloud Platform" }, "google_domains": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Google Domains" }, "google_maps": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Google Maps" }, "google_pubsub": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Google Pub/Sub" }, "google_sheets": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Google Sheets" }, "google_translate": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Google Translate Text-to-Speech" }, "google_travel_time": { "config_flow": true, - "iot_class": "cloud_polling" + "iot_class": "cloud_polling", + "integration_type": "hub" }, "google_wifi": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Google Wifi" }, "google": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Google Calendar" }, "nest": { "config_flow": true, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Google Nest" }, "cast": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Google Cast" }, "hangouts": { "config_flow": true, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Google Chat" }, "dialogflow": { "config_flow": true, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Dialogflow" } } @@ -1639,95 +1948,120 @@ "govee_ble": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Govee Bluetooth" }, "gpsd": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "GPSD" }, "gpslogger": { "config_flow": true, "iot_class": "cloud_push", + "integration_type": "hub", "name": "GPSLogger" }, "graphite": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Graphite" }, "gree": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Gree Climate" }, "greeneye_monitor": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "GreenEye Monitor (GEM)" }, "greenwave": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Greenwave Reality" }, "growatt_server": { "config_flow": true, - "iot_class": "cloud_polling" + "iot_class": "cloud_polling", + "integration_type": "hub" }, "gstreamer": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "GStreamer" }, "gtfs": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "General Transit Feed Specification (GTFS)" }, "guardian": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Elexa Guardian" }, "habitica": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Habitica" }, + "hardkernel": { + "config_flow": false, + "iot_class": null, + "integration_type": "hardware", + "name": "Hardkernel" + }, "harman_kardon_avr": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Harman Kardon AVR" }, "hassio": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Home Assistant Supervisor" }, "haveibeenpwned": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "HaveIBeenPwned" }, "hddtemp": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "hddtemp" }, "hdmi_cec": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "HDMI-CEC" }, "heatmiser": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Heatmiser" }, "here_travel_time": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "HERE Travel Time" }, "hikvision": { @@ -1736,11 +2070,13 @@ "hikvision": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Hikvision" }, "hikvisioncam": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Hikvision" } } @@ -1748,54 +2084,76 @@ "hisense_aehw4a1": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Hisense AEH-W4A1" }, "history_stats": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "History Stats" }, "hitron_coda": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Rogers Hitron CODA" }, "hive": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Hive" }, "hlk_sw16": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Hi-Link HLK-SW16" }, "home_connect": { "config_flow": true, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Home Connect" }, "home_plus_control": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Legrand Home+ Control" }, "homeassistant_alerts": { "config_flow": false, "iot_class": null, + "integration_type": "hub", "name": "Home Assistant Alerts" }, + "homeassistant_sky_connect": { + "config_flow": false, + "iot_class": null, + "integration_type": "hardware", + "name": "Home Assistant Sky Connect" + }, + "homeassistant_yellow": { + "config_flow": false, + "iot_class": null, + "integration_type": "hardware", + "name": "Home Assistant Yellow" + }, "homematic": { "name": "Homematic", "integrations": { "homematic": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Homematic" }, "homematicip_cloud": { "config_flow": true, "iot_class": "cloud_push", + "integration_type": "hub", "name": "HomematicIP Cloud" } } @@ -1803,6 +2161,7 @@ "homewizard": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "HomeWizard Energy" }, "honeywell": { @@ -1811,16 +2170,19 @@ "lyric": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Honeywell Lyric" }, "evohome": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Honeywell Total Connect Comfort (Europe)" }, "honeywell": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Honeywell Total Connect Comfort (US)" } } @@ -1828,61 +2190,73 @@ "horizon": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Unitymedia Horizon HD Recorder" }, "hp_ilo": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "HP Integrated Lights-Out (ILO)" }, "html5": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "HTML5 Push Notifications" }, "huawei_lte": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Huawei LTE" }, "huisbaasje": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Huisbaasje" }, "hunterdouglas_powerview": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Hunter Douglas PowerView" }, "hvv_departures": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "HVV Departures" }, "hydrawise": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Hunter Hydrawise" }, "hyperion": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Hyperion" }, "ialarm": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Antifurto365 iAlarm" }, "iammeter": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "IamMeter" }, "iaqualink": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Jandy iAqualink" }, "ibm": { @@ -1891,11 +2265,13 @@ "watson_iot": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "IBM Watson IoT Platform" }, "watson_tts": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "IBM Watson TTS" } } @@ -1903,51 +2279,61 @@ "idteck_prox": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "IDTECK Proximity Reader" }, "ifttt": { "config_flow": true, "iot_class": "cloud_push", + "integration_type": "hub", "name": "IFTTT" }, "iglo": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "iGlo" }, "ign_sismologia": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "IGN Sismolog\u00eda" }, "ihc": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "IHC Controller" }, "imap": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "IMAP" }, "imap_email_content": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "IMAP Email Content" }, "incomfort": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Intergas InComfort/Intouch Lan2RF gateway" }, "influxdb": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "InfluxDB" }, "inkbird": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "INKBIRD" }, "inovelli": { @@ -1960,75 +2346,90 @@ "insteon": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Insteon" }, "intellifire": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "IntelliFire" }, "intent_script": { "config_flow": false, "iot_class": null, + "integration_type": "hub", "name": "Intent Script" }, "intesishome": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "IntesisHome" }, "ios": { "config_flow": true, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Home Assistant iOS" }, "iotawatt": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "IoTaWatt" }, "iperf3": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Iperf3" }, "ipma": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Instituto Portugu\u00eas do Mar e Atmosfera (IPMA)" }, "ipp": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Internet Printing Protocol (IPP)" }, "iqvia": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "IQVIA" }, "irish_rail_transport": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Irish Rail Transport" }, "islamic_prayer_times": { "config_flow": true, - "iot_class": "cloud_polling" + "iot_class": "cloud_polling", + "integration_type": "hub" }, "iss": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "International Space Station (ISS)" }, "isy994": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Universal Devices ISY994" }, "izone": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "iZone" }, "jasco": { @@ -2040,176 +2441,211 @@ "jellyfin": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Jellyfin" }, "jewish_calendar": { "config_flow": false, "iot_class": "calculated", + "integration_type": "hub", "name": "Jewish Calendar" }, "joaoapps_join": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Joaoapps Join" }, "juicenet": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "JuiceNet" }, "justnimbus": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "JustNimbus" }, "kaiterra": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Kaiterra" }, "kaleidescape": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Kaleidescape" }, "kankun": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Kankun" }, "keba": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Keba Charging Station" }, "keenetic_ndms2": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Keenetic NDMS2 Router" }, "kef": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "KEF" }, "kegtron": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Kegtron" }, "keyboard": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Keyboard" }, "keyboard_remote": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Keyboard Remote" }, "keymitt_ble": { "config_flow": true, "iot_class": "assumed_state", + "integration_type": "hub", "name": "Keymitt MicroBot Push" }, "kira": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Kira" }, "kiwi": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "KIWI" }, "kmtronic": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "KMtronic" }, "knx": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "KNX" }, "kodi": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Kodi" }, "konnected": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Konnected.io" }, "kostal_plenticore": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Kostal Plenticore Solar Inverter" }, "kraken": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Kraken" }, "kulersky": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Kuler Sky" }, "kwb": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "KWB Easyfire" }, "lacrosse": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "LaCrosse" }, "lacrosse_view": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "LaCrosse View" }, "lametric": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "LaMetric" }, "landisgyr_heat_meter": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Landis+Gyr Heat Meter" }, "lannouncer": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "LANnouncer" }, "lastfm": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Last.fm" }, "launch_library": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Launch Library" }, "laundrify": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "laundrify" }, "lcn": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "LCN" }, "led_ble": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "LED BLE" }, "leviton": { @@ -2224,16 +2660,19 @@ "lg_netcast": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "LG Netcast" }, "lg_soundbar": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "LG Soundbars" }, "webostv": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "LG webOS Smart TV" } } @@ -2241,90 +2680,108 @@ "lidarr": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Lidarr" }, "life360": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Life360" }, "lifx": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "LIFX" }, "lifx_cloud": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "LIFX Cloud" }, "lightwave": { "config_flow": false, "iot_class": "assumed_state", + "integration_type": "hub", "name": "Lightwave" }, "limitlessled": { "config_flow": false, "iot_class": "assumed_state", + "integration_type": "hub", "name": "LimitlessLED" }, "linksys_smart": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Linksys Smart Wi-Fi" }, "linode": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Linode" }, "linux_battery": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Linux Battery" }, "lirc": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "LIRC" }, "litejet": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "LiteJet" }, "litterrobot": { "config_flow": true, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Litter-Robot" }, "llamalab_automate": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "LlamaLab Automate" }, "local_file": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Local File" }, "local_ip": { "config_flow": true, - "iot_class": "local_polling" + "iot_class": "local_polling", + "integration_type": "hub" }, "locative": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Locative" }, "logentries": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Logentries" }, "logi_circle": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Logi Circle" }, "logitech": { @@ -2333,16 +2790,19 @@ "harmony": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Logitech Harmony Hub" }, "ue_smart_radio": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Logitech UE Smart Radio" }, "squeezebox": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Squeezebox (Logitech Media Server)" } } @@ -2350,26 +2810,31 @@ "london_air": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "London Air" }, "london_underground": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "London Underground" }, "lookin": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "LOOKin" }, "luftdaten": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Sensor.Community" }, "lupusec": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Lupus Electronics LUPUSEC" }, "lutron": { @@ -2378,16 +2843,19 @@ "lutron": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Lutron" }, "lutron_caseta": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Lutron Cas\u00e9ta" }, "homeworks": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Lutron Homeworks" } } @@ -2395,71 +2863,85 @@ "lw12wifi": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "LAGUTE LW-12" }, "magicseaweed": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Magicseaweed" }, "mailgun": { "config_flow": true, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Mailgun" }, "manual": { "config_flow": false, "iot_class": "calculated", + "integration_type": "hub", "name": "Manual Alarm Control Panel" }, "map": { "config_flow": false, "iot_class": null, + "integration_type": "hub", "name": "Map" }, "marytts": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "MaryTTS" }, "mastodon": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Mastodon" }, "matrix": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Matrix" }, "mazda": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Mazda Connected Services" }, "meater": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Meater" }, "media_extractor": { "config_flow": false, "iot_class": "calculated", + "integration_type": "hub", "name": "Media Extractor" }, "mediaroom": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Mediaroom" }, "melcloud": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "MELCloud" }, "melissa": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Melissa" }, "melnor": { @@ -2468,11 +2950,13 @@ "melnor": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Melnor Bluetooth" }, "raincloud": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Melnor RainCloud" } } @@ -2480,46 +2964,55 @@ "meraki": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Meraki" }, "message_bird": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "MessageBird" }, "met": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Meteorologisk institutt (Met.no)" }, "met_eireann": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Met \u00c9ireann" }, "meteo_france": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "M\u00e9t\u00e9o-France" }, "meteoalarm": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "MeteoAlarm" }, "meteoclimatic": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Meteoclimatic" }, "metoffice": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Met Office" }, "mfi": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Ubiquiti mFi mPort" }, "microsoft": { @@ -2528,51 +3021,61 @@ "azure_devops": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Azure DevOps" }, "azure_event_hub": { "config_flow": true, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Azure Event Hub" }, "azure_service_bus": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Azure Service Bus" }, "microsoft_face_detect": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Microsoft Face Detect" }, "microsoft_face_identify": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Microsoft Face Identify" }, "microsoft_face": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Microsoft Face" }, "microsoft": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Microsoft Text-to-Speech (TTS)" }, "msteams": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Microsoft Teams" }, "xbox": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Xbox" }, "xbox_live": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Xbox Live" } } @@ -2580,98 +3083,118 @@ "miflora": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Mi Flora" }, "mikrotik": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Mikrotik" }, "mill": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Mill" }, "minecraft_server": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Minecraft Server" }, "minio": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Minio" }, "mitemp_bt": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Xiaomi Mijia BLE Temperature and Humidity Sensor" }, "mjpeg": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "MJPEG IP Camera" }, "moat": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Moat" }, "mobile_app": { "config_flow": true, - "iot_class": "local_push" + "iot_class": "local_push", + "integration_type": "hub" }, "mochad": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Mochad" }, "modbus": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Modbus" }, "modem_callerid": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Phone Modem" }, "modern_forms": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Modern Forms" }, "moehlenhoff_alpha2": { "config_flow": true, - "iot_class": "local_push" + "iot_class": "local_push", + "integration_type": "hub" }, "mold_indicator": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Mold Indicator" }, "monoprice": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Monoprice 6-Zone Amplifier" }, "moon": { "config_flow": true, - "iot_class": "local_polling" + "iot_class": "local_polling", + "integration_type": "hub" }, "motion_blinds": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Motion Blinds" }, "motioneye": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "motionEye" }, "mpd": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Music Player Daemon (MPD)" }, "mqtt": { @@ -2680,31 +3203,37 @@ "manual_mqtt": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Manual MQTT Alarm Control Panel" }, "mqtt": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "MQTT" }, "mqtt_eventstream": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "MQTT Eventstream" }, "mqtt_json": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "MQTT JSON" }, "mqtt_room": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "MQTT Room Presence" }, "mqtt_statestream": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "MQTT Statestream" } } @@ -2712,86 +3241,103 @@ "mullvad": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Mullvad VPN" }, "mutesync": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "mutesync" }, "mvglive": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "MVG" }, "mycroft": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Mycroft" }, "myq": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "MyQ" }, "mysensors": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "MySensors" }, "mystrom": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "myStrom" }, "mythicbeastsdns": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Mythic Beasts DNS" }, "nad": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "NAD" }, "nam": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Nettigo Air Monitor" }, "namecheapdns": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Namecheap FreeDNS" }, "nanoleaf": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Nanoleaf" }, "neato": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Neato Botvac" }, "nederlandse_spoorwegen": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Nederlandse Spoorwegen (NS)" }, "ness_alarm": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Ness Alarm" }, "netatmo": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Netatmo" }, "netdata": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Netdata" }, "netgear": { @@ -2800,11 +3346,13 @@ "netgear": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "NETGEAR" }, "netgear_lte": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "NETGEAR LTE" } } @@ -2812,285 +3360,342 @@ "netio": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Netio" }, "neurio_energy": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Neurio energy" }, "nexia": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Nexia/American Standard/Trane" }, "nextbus": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "NextBus" }, "nextcloud": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Nextcloud" }, "nextdns": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "NextDNS" }, "nfandroidtv": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Notifications for Android TV / Fire TV" }, "nibe_heatpump": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Nibe Heat Pump" }, "nightscout": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Nightscout" }, "niko_home_control": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Niko Home Control" }, "nilu": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Norwegian Institute for Air Research (NILU)" }, "nina": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "NINA" }, "nissan_leaf": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Nissan Leaf" }, "nmap_tracker": { "config_flow": true, - "iot_class": "local_polling" + "iot_class": "local_polling", + "integration_type": "hub" }, "nmbs": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "NMBS" }, "no_ip": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "No-IP.com" }, "noaa_tides": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "NOAA Tides" }, "nobo_hub": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Nob\u00f8 Ecohub" }, "norway_air": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Om Luftkvalitet i Norge (Norway Air)" }, "notify_events": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Notify.Events" }, "notion": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Notion" }, "nsw_fuel_station": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "NSW Fuel Station Price" }, "nsw_rural_fire_service_feed": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "NSW Rural Fire Service Incidents" }, "nuheat": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "NuHeat" }, "nuki": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Nuki" }, "numato": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Numato USB GPIO Expander" }, "nut": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Network UPS Tools (NUT)" }, "nws": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "National Weather Service (NWS)" }, "nx584": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "NX584" }, "nzbget": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "NZBGet" }, "oasa_telematics": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "OASA Telematics" }, "obihai": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Obihai" }, "octoprint": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "OctoPrint" }, "oem": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "OpenEnergyMonitor WiFi Thermostat" }, "ohmconnect": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "OhmConnect" }, "ombi": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Ombi" }, "omnilogic": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Hayward Omnilogic" }, "oncue": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Oncue by Kohler" }, "ondilo_ico": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Ondilo ICO" }, "onewire": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "1-Wire" }, "onkyo": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Onkyo" }, "onvif": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "ONVIF" }, "open_meteo": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Open-Meteo" }, "openalpr_cloud": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "OpenALPR Cloud" }, "openalpr_local": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "OpenALPR Local" }, "opencv": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "OpenCV" }, "openerz": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Open ERZ" }, "openevse": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "OpenEVSE" }, "openexchangerates": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Open Exchange Rates" }, "opengarage": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "OpenGarage" }, "openhardwaremonitor": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Open Hardware Monitor" }, "openhome": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Linn / OpenHome" }, "opensensemap": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "openSenseMap" }, "opensky": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "OpenSky Network" }, "opentherm_gw": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "OpenTherm Gateway" }, "openuv": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "OpenUV" }, "openweathermap": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "OpenWeatherMap" }, "openwrt": { @@ -3099,11 +3704,13 @@ "luci": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "OpenWrt (luci)" }, "ubus": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "OpenWrt (ubus)" } } @@ -3111,51 +3718,61 @@ "opnsense": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "OPNSense" }, "opple": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Opple" }, "oru": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Orange and Rockland Utility (ORU)" }, "orvibo": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Orvibo" }, "osramlightify": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Osramlightify" }, "otp": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "One-Time Password (OTP)" }, "overkiz": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Overkiz" }, "ovo_energy": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "OVO Energy" }, "owntracks": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "OwnTracks" }, "p1_monitor": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "P1 Monitor" }, "panasonic": { @@ -3164,11 +3781,13 @@ "panasonic_bluray": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Panasonic Blu-Ray Player" }, "panasonic_viera": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Panasonic Viera" } } @@ -3176,31 +3795,37 @@ "pandora": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Pandora" }, "panel_custom": { "config_flow": false, "iot_class": null, + "integration_type": "hub", "name": "Custom Panel" }, "panel_iframe": { "config_flow": false, "iot_class": null, + "integration_type": "hub", "name": "iframe Panel" }, "peco": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "PECO Outage Counter" }, "pencom": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Pencom" }, "persistent_notification": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Persistent Notification" }, "philips": { @@ -3209,16 +3834,19 @@ "dynalite": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Philips Dynalite" }, "hue": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Philips Hue" }, "philips_js": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Philips TV" } } @@ -3226,189 +3854,227 @@ "pi_hole": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Pi-hole" }, "picnic": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Picnic" }, "picotts": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Pico TTS" }, "pilight": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Pilight" }, "ping": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Ping (ICMP)" }, "pioneer": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Pioneer" }, "pjlink": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "PJLink" }, "plaato": { "config_flow": true, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Plaato" }, "plant": { "config_flow": false, - "iot_class": null + "iot_class": null, + "integration_type": "hub" }, "plex": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Plex Media Server" }, "plugwise": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Plugwise" }, "plum_lightpad": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Plum Lightpad" }, "pocketcasts": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Pocket Casts" }, "point": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Minut Point" }, "poolsense": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "PoolSense" }, "profiler": { "config_flow": true, "iot_class": null, + "integration_type": "hub", "name": "Profiler" }, "progettihwsw": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "ProgettiHWSW Automation" }, "proliphix": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Proliphix" }, "prometheus": { "config_flow": false, "iot_class": "assumed_state", + "integration_type": "hub", "name": "Prometheus" }, "prosegur": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Prosegur Alarm" }, "prowl": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Prowl" }, "proximity": { "config_flow": false, - "iot_class": "calculated" + "iot_class": "calculated", + "integration_type": "hub" }, "proxmoxve": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Proxmox VE" }, "proxy": { "config_flow": false, "iot_class": null, + "integration_type": "hub", "name": "Camera Proxy" }, "prusalink": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "PrusaLink" }, "pulseaudio_loopback": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "PulseAudio Loopback" }, "pure_energie": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Pure Energie" }, "push": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Push" }, "pushbullet": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Pushbullet" }, "pushover": { "config_flow": true, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Pushover" }, "pushsafer": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Pushsafer" }, "pvoutput": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "PVOutput" }, "pvpc_hourly_pricing": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Spain electricity hourly pricing (PVPC)" }, "pyload": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "pyLoad" }, "python_script": { "config_flow": false, "iot_class": null, + "integration_type": "hub", "name": "Python Scripts" }, "qbittorrent": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "qBittorrent" }, "qingping": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Qingping" }, "qld_bushfire": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Queensland Bushfire Alert" }, "qnap": { @@ -3417,11 +4083,13 @@ "qnap": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "QNAP" }, "qnap_qsw": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "QNAP QSW" } } @@ -3429,61 +4097,73 @@ "qrcode": { "config_flow": false, "iot_class": "calculated", + "integration_type": "hub", "name": "QR Code" }, "quantum_gateway": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Quantum Gateway" }, "qvr_pro": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "QVR Pro" }, "qwikswitch": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "QwikSwitch QSUSB" }, "rachio": { "config_flow": true, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Rachio" }, "radarr": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Radarr" }, "radio_browser": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Radio Browser" }, "radiotherm": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Radio Thermostat" }, "rainbird": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Rain Bird" }, "rainforest_eagle": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Rainforest Eagle" }, "rainmachine": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "RainMachine" }, "random": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Random" }, "raspberry": { @@ -3492,162 +4172,200 @@ "rpi_camera": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Raspberry Pi Camera" }, "rpi_power": { "config_flow": true, - "iot_class": "local_polling" + "iot_class": "local_polling", + "integration_type": "hub" }, "remote_rpi_gpio": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "remote_rpi_gpio" } } }, + "raspberry_pi": { + "config_flow": false, + "iot_class": null, + "integration_type": "hardware", + "name": "Raspberry Pi" + }, "raspyrfm": { "config_flow": false, "iot_class": "assumed_state", + "integration_type": "hub", "name": "RaspyRFM" }, "rdw": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "RDW" }, "recollect_waste": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "ReCollect Waste" }, "recswitch": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Ankuoo REC Switch" }, "reddit": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Reddit" }, "rejseplanen": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Rejseplanen" }, "remember_the_milk": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Remember The Milk" }, "renault": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Renault" }, "repetier": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Repetier-Server" }, "rest": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "RESTful" }, "rest_command": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "RESTful Command" }, "rflink": { "config_flow": false, "iot_class": "assumed_state", + "integration_type": "hub", "name": "RFLink" }, "rfxtrx": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "RFXCOM RFXtrx" }, "rhasspy": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Rhasspy" }, "ridwell": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Ridwell" }, "ring": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Ring" }, "ripple": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Ripple" }, "risco": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Risco" }, "rituals_perfume_genie": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Rituals Perfume Genie" }, "rmvtransport": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "RMV" }, "rocketchat": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Rocket.Chat" }, "roku": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Roku" }, "roomba": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "iRobot Roomba and Braava" }, "roon": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "RoonLabs music player" }, "rova": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "ROVA" }, "rss_feed_template": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "RSS Feed Template" }, "rtorrent": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "rTorrent" }, "rtsp_to_webrtc": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "RTSPtoWebRTC" }, "ruckus_unleashed": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Ruckus Unleashed" }, "russound": { @@ -3656,11 +4374,13 @@ "russound_rio": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Russound RIO" }, "russound_rnet": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Russound RNET" } } @@ -3668,11 +4388,13 @@ "sabnzbd": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "SABnzbd" }, "saj": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "SAJ Solar Inverter" }, "samsung": { @@ -3681,16 +4403,19 @@ "familyhub": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Samsung Family Hub" }, "samsungtv": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Samsung Smart TV" }, "syncthru": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Samsung SyncThru Printer" } } @@ -3698,270 +4423,324 @@ "satel_integra": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Satel Integra" }, "schluter": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Schluter" }, "scrape": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Scrape" }, "screenlogic": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Pentair ScreenLogic" }, "scsgate": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "SCSGate" }, "season": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Season" }, "sendgrid": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "SendGrid" }, "sense": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Sense" }, "senseme": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "SenseME" }, "sensibo": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Sensibo" }, "sensorpro": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "SensorPro" }, "sensorpush": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "SensorPush" }, "sentry": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Sentry" }, "senz": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "nVent RAYCHEM SENZ" }, "serial": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Serial" }, "serial_pm": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Serial Particulate Matter" }, "sesame": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Sesame Smart Lock" }, "seven_segments": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Seven Segments OCR" }, "seventeentrack": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "17TRACK" }, "sharkiq": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Shark IQ" }, "shell_command": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Shell Command" }, "shelly": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Shelly" }, "shiftr": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "shiftr.io" }, "shodan": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Shodan" }, "shopping_list": { "config_flow": true, - "iot_class": "local_push" + "iot_class": "local_push", + "integration_type": "hub" }, "sia": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "SIA Alarm Systems" }, "sigfox": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Sigfox" }, "sighthound": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Sighthound" }, "signal_messenger": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Signal Messenger" }, "simplepush": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Simplepush" }, "simplisafe": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "SimpliSafe" }, "simulated": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Simulated" }, "sinch": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Sinch SMS" }, "sisyphus": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Sisyphus" }, "sky_hub": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Sky Hub" }, "skybeacon": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Skybeacon" }, "skybell": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "SkyBell" }, "slack": { "config_flow": true, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Slack" }, "sleepiq": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "SleepIQ" }, "slide": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Slide" }, "slimproto": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "SlimProto (Squeezebox players)" }, "sma": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "SMA Solar" }, "smappee": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Smappee" }, "smart_meter_texas": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Smart Meter Texas" }, "smartthings": { "config_flow": true, "iot_class": "cloud_push", + "integration_type": "hub", "name": "SmartThings" }, "smarttub": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "SmartTub" }, "smarty": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Salda Smarty" }, "smhi": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "SMHI" }, "sms": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "SMS notifications via GSM-modem" }, "smtp": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "SMTP" }, "snapcast": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Snapcast" }, "snips": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Snips" }, "snmp": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "SNMP" }, "snooz": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Snooz" }, "solaredge": { @@ -3970,11 +4749,13 @@ "solaredge": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "SolarEdge" }, "solaredge_local": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "SolarEdge Local" } } @@ -3982,31 +4763,37 @@ "solarlog": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Solar-Log" }, "solax": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "SolaX Power" }, "soma": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Soma Connect" }, "somfy_mylink": { "config_flow": true, "iot_class": "assumed_state", + "integration_type": "hub", "name": "Somfy MyLink" }, "sonarr": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Sonarr" }, "sonos": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Sonos" }, "sony": { @@ -4015,21 +4802,25 @@ "braviatv": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Sony Bravia TV" }, "ps4": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Sony PlayStation 4" }, "sony_projector": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Sony Projector" }, "songpal": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Sony Songpal" } } @@ -4037,170 +4828,204 @@ "soundtouch": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Bose SoundTouch" }, "spaceapi": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Space API" }, "spc": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Vanderbilt SPC" }, "speedtestdotnet": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Speedtest.net" }, "spider": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Itho Daalderop Spider" }, "splunk": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Splunk" }, "spotify": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Spotify" }, "sql": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "SQL" }, "srp_energy": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "SRP Energy" }, "starline": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "StarLine" }, "starlingbank": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Starling Bank" }, "startca": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Start.ca" }, "statistics": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Statistics" }, "statsd": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "StatsD" }, "steam_online": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Steam" }, "steamist": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Steamist" }, "stiebel_eltron": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "STIEBEL ELTRON" }, "stookalert": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "RIVM Stookalert" }, "stream": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Stream" }, "streamlabswater": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "StreamLabs" }, "subaru": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Subaru" }, "suez_water": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Suez Water" }, "sun": { "config_flow": true, - "iot_class": "calculated" + "iot_class": "calculated", + "integration_type": "hub" }, "supervisord": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Supervisord" }, "supla": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Supla" }, "surepetcare": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Sure Petcare" }, "swiss_hydrological_data": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Swiss Hydrological Data" }, "swiss_public_transport": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Swiss public transport" }, "swisscom": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Swisscom Internet-Box" }, "switchbee": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "SwitchBee" }, "switchbot": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "SwitchBot" }, "switcher_kis": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Switcher" }, "switchmate": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Switchmate SimplySmart Home" }, "syncthing": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Syncthing" }, "synology": { @@ -4209,16 +5034,19 @@ "synology_chat": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Synology Chat" }, "synology_dsm": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Synology DSM" }, "synology_srm": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Synology SRM" } } @@ -4226,70 +5054,84 @@ "syslog": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Syslog" }, "system_bridge": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "System Bridge" }, "system_log": { "config_flow": false, "iot_class": null, + "integration_type": "hub", "name": "System Log" }, "systemmonitor": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "System Monitor" }, "tado": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Tado" }, "tag": { "config_flow": false, - "iot_class": null + "iot_class": null, + "integration_type": "hub" }, "tailscale": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Tailscale" }, "tank_utility": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Tank Utility" }, "tankerkoenig": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Tankerkoenig" }, "tapsaff": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Taps Aff" }, "tasmota": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Tasmota" }, "tautulli": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Tautulli" }, "tcp": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "TCP" }, "ted5000": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "The Energy Detective TED5000" }, "telegram": { @@ -4298,11 +5140,13 @@ "telegram": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Telegram" }, "telegram_bot": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Telegram bot" } } @@ -4313,11 +5157,13 @@ "tellduslive": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Telldus Live" }, "tellstick": { "config_flow": false, "iot_class": "assumed_state", + "integration_type": "hub", "name": "TellStick" } } @@ -4325,21 +5171,25 @@ "telnet": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Telnet" }, "temper": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "TEMPer" }, "template": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Template" }, "tensorflow": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "TensorFlow" }, "tesla": { @@ -4348,11 +5198,13 @@ "powerwall": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Tesla Powerwall" }, "tesla_wall_connector": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Tesla Wall Connector" } } @@ -4360,36 +5212,43 @@ "tfiac": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Tfiac" }, "thermobeacon": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "ThermoBeacon" }, "thermopro": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "ThermoPro" }, "thermoworks_smoke": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "ThermoWorks Smoke" }, "thethingsnetwork": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "The Things Network" }, "thingspeak": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "ThingSpeak" }, "thinkingcleaner": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Thinking Cleaner" }, "third_reality": { @@ -4401,101 +5260,121 @@ "thomson": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Thomson" }, "tibber": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Tibber" }, "tikteck": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Tikteck" }, "tile": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Tile" }, "tilt_ble": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Tilt Hydrometer BLE" }, "time_date": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Time & Date" }, "tmb": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Transports Metropolitans de Barcelona" }, "todoist": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Todoist" }, "tolo": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "TOLO Sauna" }, "tomato": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Tomato" }, "tomorrowio": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Tomorrow.io" }, "toon": { "config_flow": true, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Toon" }, "torque": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Torque" }, "totalconnect": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Total Connect" }, "touchline": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Roth Touchline" }, "tplink": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "TP-Link Kasa Smart" }, "tplink_lte": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "TP-Link LTE" }, "traccar": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Traccar" }, "tractive": { "config_flow": true, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Tractive" }, "tradfri": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "IKEA TR\u00c5DFRI" }, "trafikverket": { @@ -4504,16 +5383,19 @@ "trafikverket_ferry": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Trafikverket Ferry" }, "trafikverket_train": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Trafikverket Train" }, "trafikverket_weatherstation": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Trafikverket Weather Station" } } @@ -4521,31 +5403,37 @@ "transmission": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Transmission" }, "transport_nsw": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Transport NSW" }, "travisci": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Travis-CI" }, "trend": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Trend" }, "tuya": { "config_flow": true, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Tuya" }, "twentemilieu": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Twente Milieu" }, "twilio": { @@ -4554,16 +5442,19 @@ "twilio": { "config_flow": true, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Twilio" }, "twilio_call": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Twilio Call" }, "twilio_sms": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Twilio SMS" } } @@ -4571,16 +5462,19 @@ "twinkly": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Twinkly" }, "twitch": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Twitch" }, "twitter": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Twitter" }, "u_tec": { @@ -4595,21 +5489,25 @@ "unifi": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "UniFi Network" }, "unifi_direct": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "UniFi AP" }, "unifiled": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "UniFi LED" }, "unifiprotect": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "UniFi Protect" } } @@ -4617,130 +5515,156 @@ "uk_transport": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "UK Transport" }, "ukraine_alarm": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Ukraine Alarm" }, "universal": { "config_flow": false, "iot_class": "calculated", + "integration_type": "hub", "name": "Universal Media Player" }, "upb": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Universal Powerline Bus (UPB)" }, "upc_connect": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "UPC Connect Box" }, "upcloud": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "UpCloud" }, "upnp": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "UPnP/IGD" }, "uptime": { "config_flow": true, - "iot_class": "local_push" + "iot_class": "local_push", + "integration_type": "hub" }, "uptimerobot": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "UptimeRobot" }, "usgs_earthquakes_feed": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "U.S. Geological Survey Earthquake Hazards (USGS)" }, "uvc": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Ubiquiti UniFi Video" }, "vallox": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Vallox" }, "vasttrafik": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "V\u00e4sttrafik" }, "velbus": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Velbus" }, "velux": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Velux" }, "venstar": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Venstar" }, "vera": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Vera" }, "verisure": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Verisure" }, "versasense": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "VersaSense" }, "version": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Version" }, "vesync": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "VeSync" }, "viaggiatreno": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Trenitalia ViaggiaTreno" }, "vicare": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Viessmann ViCare" }, "vilfo": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Vilfo Router" }, "vivotek": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "VIVOTEK" }, "vizio": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "VIZIO SmartCast" }, "vlc": { @@ -4749,11 +5673,13 @@ "vlc": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "VLC media player" }, "vlc_telnet": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "VLC media player via Telnet" } } @@ -4761,160 +5687,192 @@ "voicerss": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "VoiceRSS" }, "volkszaehler": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Volkszaehler" }, "volumio": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Volumio" }, "volvooncall": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Volvo On Call" }, "vulcan": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Uonet+ Vulcan" }, "vultr": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Vultr" }, "w800rf32": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "WGL Designs W800RF32" }, "wake_on_lan": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Wake on LAN" }, "wallbox": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Wallbox" }, "waqi": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "World Air Quality Index (WAQI)" }, "waterfurnace": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "WaterFurnace" }, "watttime": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "WattTime" }, "waze_travel_time": { "config_flow": true, - "iot_class": "cloud_polling" + "iot_class": "cloud_polling", + "integration_type": "hub" }, "webhook": { "config_flow": false, "iot_class": null, + "integration_type": "hub", "name": "Webhook" }, "wemo": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Belkin WeMo" }, "whirlpool": { "config_flow": true, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Whirlpool Sixth Sense" }, "whois": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Whois" }, "wiffi": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Wiffi" }, "wilight": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "WiLight" }, "wirelesstag": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Wireless Sensor Tags" }, "withings": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Withings" }, "wiz": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "WiZ" }, "wled": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "WLED" }, "wolflink": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Wolf SmartSet Service" }, "workday": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Workday" }, "worldclock": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "Worldclock" }, "worldtidesinfo": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "World Tides" }, "worxlandroid": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Worx Landroid" }, "ws66i": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Soundavo WS66i 6-Zone Amplifier" }, "wsdot": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Washington State Department of Transportation (WSDOT)" }, "x10": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Heyu X10" }, "xeoma": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Xeoma" }, "xiaomi": { @@ -4923,26 +5881,31 @@ "xiaomi_aqara": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Xiaomi Gateway (Aqara)" }, "xiaomi_ble": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Xiaomi BLE" }, "xiaomi_miio": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Xiaomi Miio" }, "xiaomi_tv": { "config_flow": false, "iot_class": "assumed_state", + "integration_type": "hub", "name": "Xiaomi TV" }, "xiaomi": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Xiaomi" } } @@ -4950,11 +5913,13 @@ "xmpp": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Jabber (XMPP)" }, "xs1": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "EZcontrol XS1" }, "yale": { @@ -4963,16 +5928,19 @@ "august": { "config_flow": true, "iot_class": "cloud_push", + "integration_type": "hub", "name": "August" }, "yale_smart_alarm": { "config_flow": true, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Yale Smart Living" }, "yalexs_ble": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Yale Access Bluetooth" } } @@ -4980,11 +5948,13 @@ "yamaha": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Yamaha Network Receivers" }, "yamaha_musiccast": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "MusicCast" }, "yandex": { @@ -4993,11 +5963,13 @@ "yandex_transport": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Yandex Transport" }, "yandextts": { "config_flow": false, "iot_class": "cloud_push", + "integration_type": "hub", "name": "Yandex TTS" } } @@ -5008,11 +5980,13 @@ "yeelight": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Yeelight" }, "yeelightsunflower": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Yeelight Sunflower" } } @@ -5020,71 +5994,85 @@ "yi": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Yi Home Cameras" }, "yolink": { "config_flow": true, "iot_class": "cloud_push", + "integration_type": "hub", "name": "YoLink" }, "youless": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "YouLess" }, "zabbix": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Zabbix" }, "zamg": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Zentralanstalt f\u00fcr Meteorologie und Geodynamik (ZAMG)" }, "zengge": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Zengge" }, "zerproc": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Zerproc" }, "zestimate": { "config_flow": false, "iot_class": "cloud_polling", + "integration_type": "hub", "name": "Zestimate" }, "zha": { "config_flow": true, "iot_class": "local_polling", + "integration_type": "hub", "name": "Zigbee Home Automation" }, "zhong_hong": { "config_flow": false, "iot_class": "local_push", + "integration_type": "hub", "name": "ZhongHong" }, "ziggo_mediabox_xl": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Ziggo Mediabox XL" }, "zodiac": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "Zodiac" }, "zone": { "config_flow": false, "iot_class": null, + "integration_type": "hub", "name": "Zone" }, "zoneminder": { "config_flow": false, "iot_class": "local_polling", + "integration_type": "hub", "name": "ZoneMinder" }, "zooz": { @@ -5096,107 +6084,105 @@ "zwave_js": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Z-Wave" }, "zwave_me": { "config_flow": true, "iot_class": "local_push", + "integration_type": "hub", "name": "Z-Wave.Me" } }, - "hardware": { - "hardkernel": { - "config_flow": false, - "iot_class": null, - "name": "Hardkernel" - }, - "homeassistant_sky_connect": { - "config_flow": false, - "iot_class": null, - "name": "Home Assistant Sky Connect" - }, - "homeassistant_yellow": { - "config_flow": false, - "iot_class": null, - "name": "Home Assistant Yellow" - }, - "raspberry_pi": { - "config_flow": false, - "iot_class": null, - "name": "Raspberry Pi" - } - }, + "hardware": {}, "helper": { "counter": { "config_flow": false, "iot_class": null, + "integration_type": "helper", "name": "Counter" }, "derivative": { "config_flow": true, - "iot_class": "calculated" + "iot_class": "calculated", + "integration_type": "helper" }, "group": { "config_flow": true, - "iot_class": "calculated" + "iot_class": "calculated", + "integration_type": "helper" }, "input_boolean": { "config_flow": false, - "iot_class": null + "iot_class": null, + "integration_type": "helper" }, "input_button": { "config_flow": false, "iot_class": null, + "integration_type": "helper", "name": "Input Button" }, "input_datetime": { "config_flow": false, - "iot_class": null + "iot_class": null, + "integration_type": "helper" }, "input_number": { "config_flow": false, - "iot_class": null + "iot_class": null, + "integration_type": "helper" }, "input_select": { "config_flow": false, - "iot_class": null + "iot_class": null, + "integration_type": "helper" }, "input_text": { "config_flow": false, - "iot_class": null + "iot_class": null, + "integration_type": "helper" }, "integration": { "config_flow": true, - "iot_class": "local_push" + "iot_class": "local_push", + "integration_type": "helper" }, "min_max": { "config_flow": true, - "iot_class": "local_push" + "iot_class": "local_push", + "integration_type": "helper" }, "schedule": { "config_flow": false, - "iot_class": null + "iot_class": null, + "integration_type": "helper" }, "switch_as_x": { "config_flow": true, - "iot_class": "calculated" + "iot_class": "calculated", + "integration_type": "helper" }, "threshold": { "config_flow": true, - "iot_class": "local_polling" + "iot_class": "local_polling", + "integration_type": "helper" }, "timer": { "config_flow": false, "iot_class": null, + "integration_type": "helper", "name": "Timer" }, "tod": { "config_flow": true, - "iot_class": "local_push" + "iot_class": "local_push", + "integration_type": "helper" }, "utility_meter": { "config_flow": true, - "iot_class": "local_push" + "iot_class": "local_push", + "integration_type": "helper" } }, "translated_name": [ diff --git a/homeassistant/loader.py b/homeassistant/loader.py index f2a7948f4f5..e90d0b42036 100644 --- a/homeassistant/loader.py +++ b/homeassistant/loader.py @@ -130,7 +130,9 @@ class Manifest(TypedDict, total=False): name: str disabled: str domain: str - integration_type: Literal["entity", "integration", "hardware", "helper", "system"] + integration_type: Literal[ + "entity", "device", "hardware", "helper", "hub", "service", "system" + ] dependencies: list[str] after_dependencies: list[str] requirements: list[str] @@ -224,7 +226,7 @@ async def async_get_custom_components( async def async_get_config_flows( hass: HomeAssistant, - type_filter: Literal["helper", "integration"] | None = None, + type_filter: Literal["device", "helper", "hub", "service"] | None = None, ) -> set[str]: """Return cached list of config flows.""" # pylint: disable=import-outside-toplevel @@ -262,9 +264,11 @@ async def async_get_integration_descriptions( core_flows: dict[str, Any] = json_loads(flow) custom_integrations = await async_get_custom_components(hass) custom_flows: dict[str, Any] = { - "integration": {}, + "device": {}, "hardware": {}, "helper": {}, + "hub": {}, + "service": {}, } for integration in custom_integrations.values(): @@ -272,7 +276,7 @@ async def async_get_integration_descriptions( if integration.integration_type in ("entity", "system"): continue - for integration_type in ("integration", "hardware", "helper"): + for integration_type in ("device", "hardware", "helper", "hub", "service"): if integration.domain not in core_flows[integration_type]: continue del core_flows[integration_type][integration.domain] @@ -281,6 +285,7 @@ async def async_get_integration_descriptions( metadata = { "config_flow": integration.config_flow, + "integration_type": integration.integration_type, "iot_class": integration.iot_class, "name": integration.name, } @@ -599,9 +604,9 @@ class Integration: @property def integration_type( self, - ) -> Literal["entity", "integration", "hardware", "helper", "system"]: + ) -> Literal["entity", "device", "hardware", "helper", "hub", "service", "system"]: """Return the integration type.""" - return self.manifest.get("integration_type", "integration") + return self.manifest.get("integration_type", "hub") @property def mqtt(self) -> list[str] | None: diff --git a/script/hassfest/config_flow.py b/script/hassfest/config_flow.py index 81cc5fae829..6905cd60d49 100644 --- a/script/hassfest/config_flow.py +++ b/script/hassfest/config_flow.py @@ -86,7 +86,10 @@ def _generate_and_validate(integrations: dict[str, Integration], config: Config) _validate_integration(config, integration) - domains[integration.integration_type].append(domain) + if integration.integration_type == "helper": + domains["helper"].append(domain) + else: + domains["integration"].append(domain) return black.format_str(BASE.format(to_string(domains)), mode=black.Mode()) @@ -106,6 +109,7 @@ def _populate_brand_integrations( metadata = {} metadata["config_flow"] = integration.config_flow metadata["iot_class"] = integration.iot_class + metadata["integration_type"] = integration.integration_type if integration.translated_name: integration_data["translated_name"].add(domain) else: @@ -169,11 +173,16 @@ def _generate_integrations( continue metadata["config_flow"] = integration.config_flow metadata["iot_class"] = integration.iot_class + metadata["integration_type"] = integration.integration_type if integration.translated_name: result["translated_name"].add(domain) else: metadata["name"] = integration.name - result[integration.integration_type][domain] = metadata + + if integration.integration_type == "helper": + result["helper"][domain] = metadata + else: + result["integration"][domain] = metadata return json.dumps( result | {"translated_name": sorted(result["translated_name"])}, indent=2 diff --git a/script/hassfest/manifest.py b/script/hassfest/manifest.py index de227cbb59c..616faeb995e 100644 --- a/script/hassfest/manifest.py +++ b/script/hassfest/manifest.py @@ -162,8 +162,16 @@ MANIFEST_SCHEMA = vol.Schema( { vol.Required("domain"): str, vol.Required("name"): str, - vol.Optional("integration_type"): vol.In( - ["entity", "hardware", "helper", "system"] + vol.Optional("integration_type", default="hub"): vol.In( + [ + "device", + "entity", + "hardware", + "helper", + "hub", + "service", + "system", + ] ), vol.Optional("config_flow"): bool, vol.Optional("mqtt"): [str], diff --git a/script/hassfest/model.py b/script/hassfest/model.py index 6a7ab64c14f..b2459f931c6 100644 --- a/script/hassfest/model.py +++ b/script/hassfest/model.py @@ -177,7 +177,7 @@ class Integration: @property def integration_type(self) -> str: """Get integration_type.""" - return self.manifest.get("integration_type", "integration") + return self.manifest.get("integration_type", "hub") @property def iot_class(self) -> str | None: diff --git a/tests/components/bluetooth/test_config_flow.py b/tests/components/bluetooth/test_config_flow.py index 4c1e8f660b3..69619ba76a7 100644 --- a/tests/components/bluetooth/test_config_flow.py +++ b/tests/components/bluetooth/test_config_flow.py @@ -37,7 +37,6 @@ async def test_options_flow_disabled_not_setup( "id": 5, "type": "config_entries/get", "domain": "bluetooth", - "type_filter": "integration", } ) response = await ws_client.receive_json() @@ -341,7 +340,6 @@ async def test_options_flow_disabled_macos( "id": 5, "type": "config_entries/get", "domain": "bluetooth", - "type_filter": "integration", } ) response = await ws_client.receive_json() @@ -371,7 +369,6 @@ async def test_options_flow_enabled_linux( "id": 5, "type": "config_entries/get", "domain": "bluetooth", - "type_filter": "integration", } ) response = await ws_client.receive_json() diff --git a/tests/components/config/test_config_entries.py b/tests/components/config/test_config_entries.py index d36f7282bdb..29a2395a926 100644 --- a/tests/components/config/test_config_entries.py +++ b/tests/components/config/test_config_entries.py @@ -51,7 +51,15 @@ async def test_get_entries(hass, client, clear_handlers): mock_integration( hass, MockModule("comp2", partial_manifest={"integration_type": "helper"}) ) - mock_integration(hass, MockModule("comp3")) + mock_integration( + hass, MockModule("comp3", partial_manifest={"integration_type": "hub"}) + ) + mock_integration( + hass, MockModule("comp4", partial_manifest={"integration_type": "device"}) + ) + mock_integration( + hass, MockModule("comp5", partial_manifest={"integration_type": "service"}) + ) @HANDLERS.register("comp1") class Comp1ConfigFlow: @@ -91,6 +99,16 @@ async def test_get_entries(hass, client, clear_handlers): source="bla3", disabled_by=core_ce.ConfigEntryDisabler.USER, ).add_to_hass(hass) + MockConfigEntry( + domain="comp4", + title="Test 4", + source="bla4", + ).add_to_hass(hass) + MockConfigEntry( + domain="comp5", + title="Test 5", + source="bla5", + ).add_to_hass(hass) resp = await client.get("/api/config/config_entries/entry") assert resp.status == HTTPStatus.OK @@ -137,6 +155,32 @@ async def test_get_entries(hass, client, clear_handlers): "disabled_by": core_ce.ConfigEntryDisabler.USER, "reason": None, }, + { + "domain": "comp4", + "title": "Test 4", + "source": "bla4", + "state": core_ce.ConfigEntryState.NOT_LOADED.value, + "supports_options": False, + "supports_remove_device": False, + "supports_unload": False, + "pref_disable_new_entities": False, + "pref_disable_polling": False, + "disabled_by": None, + "reason": None, + }, + { + "domain": "comp5", + "title": "Test 5", + "source": "bla5", + "state": core_ce.ConfigEntryState.NOT_LOADED.value, + "supports_options": False, + "supports_remove_device": False, + "supports_unload": False, + "pref_disable_new_entities": False, + "pref_disable_polling": False, + "disabled_by": None, + "reason": None, + }, ] resp = await client.get("/api/config/config_entries/entry?domain=comp3") @@ -150,20 +194,25 @@ async def test_get_entries(hass, client, clear_handlers): data = await resp.json() assert len(data) == 0 - resp = await client.get( - "/api/config/config_entries/entry?domain=comp3&type=integration" - ) - assert resp.status == HTTPStatus.OK - data = await resp.json() - assert len(data) == 1 - - resp = await client.get("/api/config/config_entries/entry?type=integration") + resp = await client.get("/api/config/config_entries/entry?type=hub") assert resp.status == HTTPStatus.OK data = await resp.json() assert len(data) == 2 assert data[0]["domain"] == "comp1" assert data[1]["domain"] == "comp3" + resp = await client.get("/api/config/config_entries/entry?type=device") + assert resp.status == HTTPStatus.OK + data = await resp.json() + assert len(data) == 1 + assert data[0]["domain"] == "comp4" + + resp = await client.get("/api/config/config_entries/entry?type=service") + assert resp.status == HTTPStatus.OK + data = await resp.json() + assert len(data) == 1 + assert data[0]["domain"] == "comp5" + async def test_remove_entry(hass, client): """Test removing an entry via the API.""" @@ -1123,7 +1172,16 @@ async def test_get_entries_ws(hass, hass_ws_client, clear_handlers): mock_integration( hass, MockModule("comp2", partial_manifest={"integration_type": "helper"}) ) - mock_integration(hass, MockModule("comp3")) + mock_integration( + hass, MockModule("comp3", partial_manifest={"integration_type": "hub"}) + ) + mock_integration( + hass, MockModule("comp4", partial_manifest={"integration_type": "device"}) + ) + mock_integration( + hass, MockModule("comp5", partial_manifest={"integration_type": "service"}) + ) + entry = MockConfigEntry( domain="comp1", title="Test 1", @@ -1143,6 +1201,16 @@ async def test_get_entries_ws(hass, hass_ws_client, clear_handlers): source="bla3", disabled_by=core_ce.ConfigEntryDisabler.USER, ).add_to_hass(hass) + MockConfigEntry( + domain="comp4", + title="Test 4", + source="bla4", + ).add_to_hass(hass) + MockConfigEntry( + domain="comp5", + title="Test 5", + source="bla5", + ).add_to_hass(hass) ws_client = await hass_ws_client(hass) @@ -1197,6 +1265,34 @@ async def test_get_entries_ws(hass, hass_ws_client, clear_handlers): "supports_unload": False, "title": "Test 3", }, + { + "disabled_by": None, + "domain": "comp4", + "entry_id": ANY, + "pref_disable_new_entities": False, + "pref_disable_polling": False, + "reason": None, + "source": "bla4", + "state": "not_loaded", + "supports_options": False, + "supports_remove_device": False, + "supports_unload": False, + "title": "Test 4", + }, + { + "disabled_by": None, + "domain": "comp5", + "entry_id": ANY, + "pref_disable_new_entities": False, + "pref_disable_polling": False, + "reason": None, + "source": "bla5", + "state": "not_loaded", + "supports_options": False, + "supports_remove_device": False, + "supports_unload": False, + "title": "Test 5", + }, ] await ws_client.send_json( @@ -1204,7 +1300,7 @@ async def test_get_entries_ws(hass, hass_ws_client, clear_handlers): "id": 6, "type": "config_entries/get", "domain": "comp1", - "type_filter": "integration", + "type_filter": "hub", } ) response = await ws_client.receive_json() @@ -1225,22 +1321,102 @@ async def test_get_entries_ws(hass, hass_ws_client, clear_handlers): "title": "Test 1", } ] - # Verify we skip broken integrations + await ws_client.send_json( + { + "id": 7, + "type": "config_entries/get", + "type_filter": ["service", "device"], + } + ) + response = await ws_client.receive_json() + assert response["id"] == 7 + assert response["result"] == [ + { + "disabled_by": None, + "domain": "comp4", + "entry_id": ANY, + "pref_disable_new_entities": False, + "pref_disable_polling": False, + "reason": None, + "source": "bla4", + "state": "not_loaded", + "supports_options": False, + "supports_remove_device": False, + "supports_unload": False, + "title": "Test 4", + }, + { + "disabled_by": None, + "domain": "comp5", + "entry_id": ANY, + "pref_disable_new_entities": False, + "pref_disable_polling": False, + "reason": None, + "source": "bla5", + "state": "not_loaded", + "supports_options": False, + "supports_remove_device": False, + "supports_unload": False, + "title": "Test 5", + }, + ] + + await ws_client.send_json( + { + "id": 8, + "type": "config_entries/get", + "type_filter": "hub", + } + ) + response = await ws_client.receive_json() + assert response["id"] == 8 + assert response["result"] == [ + { + "disabled_by": None, + "domain": "comp1", + "entry_id": ANY, + "pref_disable_new_entities": False, + "pref_disable_polling": False, + "reason": None, + "source": "bla", + "state": "not_loaded", + "supports_options": False, + "supports_remove_device": False, + "supports_unload": False, + "title": "Test 1", + }, + { + "disabled_by": "user", + "domain": "comp3", + "entry_id": ANY, + "pref_disable_new_entities": False, + "pref_disable_polling": False, + "reason": None, + "source": "bla3", + "state": "not_loaded", + "supports_options": False, + "supports_remove_device": False, + "supports_unload": False, + "title": "Test 3", + }, + ] + + # Verify we skip broken integrations with patch( "homeassistant.components.config.config_entries.async_get_integration", side_effect=IntegrationNotFound("any"), ): await ws_client.send_json( { - "id": 7, + "id": 9, "type": "config_entries/get", - "type_filter": "integration", + "type_filter": "hub", } ) response = await ws_client.receive_json() - assert response["id"] == 7 + assert response["id"] == 9 assert response["result"] == [ { "disabled_by": None, @@ -1284,8 +1460,53 @@ async def test_get_entries_ws(hass, hass_ws_client, clear_handlers): "supports_unload": False, "title": "Test 3", }, + { + "disabled_by": None, + "domain": "comp4", + "entry_id": ANY, + "pref_disable_new_entities": False, + "pref_disable_polling": False, + "reason": None, + "source": "bla4", + "state": "not_loaded", + "supports_options": False, + "supports_remove_device": False, + "supports_unload": False, + "title": "Test 4", + }, + { + "disabled_by": None, + "domain": "comp5", + "entry_id": ANY, + "pref_disable_new_entities": False, + "pref_disable_polling": False, + "reason": None, + "source": "bla5", + "state": "not_loaded", + "supports_options": False, + "supports_remove_device": False, + "supports_unload": False, + "title": "Test 5", + }, ] + # Verify we don't send config entries when only helpers are requested + with patch( + "homeassistant.components.config.config_entries.async_get_integration", + side_effect=IntegrationNotFound("any"), + ): + await ws_client.send_json( + { + "id": 10, + "type": "config_entries/get", + "type_filter": ["helper"], + } + ) + response = await ws_client.receive_json() + + assert response["id"] == 10 + assert response["result"] == [] + # Verify we raise if something really goes wrong with patch( @@ -1294,14 +1515,14 @@ async def test_get_entries_ws(hass, hass_ws_client, clear_handlers): ): await ws_client.send_json( { - "id": 8, + "id": 11, "type": "config_entries/get", - "type_filter": "integration", + "type_filter": ["device", "hub", "service"], } ) response = await ws_client.receive_json() - assert response["id"] == 8 + assert response["id"] == 11 assert response["success"] is False @@ -1312,7 +1533,9 @@ async def test_subscribe_entries_ws(hass, hass_ws_client, clear_handlers): mock_integration( hass, MockModule("comp2", partial_manifest={"integration_type": "helper"}) ) - mock_integration(hass, MockModule("comp3")) + mock_integration( + hass, MockModule("comp3", partial_manifest={"integration_type": "device"}) + ) entry = MockConfigEntry( domain="comp1", title="Test 1", @@ -1476,7 +1699,12 @@ async def test_subscribe_entries_ws_filtered(hass, hass_ws_client, clear_handler mock_integration( hass, MockModule("comp2", partial_manifest={"integration_type": "helper"}) ) - mock_integration(hass, MockModule("comp3")) + mock_integration( + hass, MockModule("comp3", partial_manifest={"integration_type": "device"}) + ) + mock_integration( + hass, MockModule("comp4", partial_manifest={"integration_type": "service"}) + ) entry = MockConfigEntry( domain="comp1", title="Test 1", @@ -1491,12 +1719,19 @@ async def test_subscribe_entries_ws_filtered(hass, hass_ws_client, clear_handler reason="Unsupported API", ) entry2.add_to_hass(hass) - MockConfigEntry( + entry3 = MockConfigEntry( domain="comp3", title="Test 3", source="bla3", disabled_by=core_ce.ConfigEntryDisabler.USER, - ).add_to_hass(hass) + ) + entry3.add_to_hass(hass) + entry4 = MockConfigEntry( + domain="comp4", + title="Test 4", + source="bla4", + ) + entry4.add_to_hass(hass) ws_client = await hass_ws_client(hass) @@ -1504,7 +1739,7 @@ async def test_subscribe_entries_ws_filtered(hass, hass_ws_client, clear_handler { "id": 5, "type": "config_entries/subscribe", - "type_filter": "integration", + "type_filter": ["hub", "device"], } ) response = await ws_client.receive_json() @@ -1551,6 +1786,8 @@ async def test_subscribe_entries_ws_filtered(hass, hass_ws_client, clear_handler }, ] assert hass.config_entries.async_update_entry(entry, title="changed") + assert hass.config_entries.async_update_entry(entry3, title="changed too") + assert hass.config_entries.async_update_entry(entry4, title="changed but ignored") response = await ws_client.receive_json() assert response["id"] == 5 assert response["event"] == [ @@ -1572,6 +1809,27 @@ async def test_subscribe_entries_ws_filtered(hass, hass_ws_client, clear_handler "type": "updated", } ] + response = await ws_client.receive_json() + assert response["id"] == 5 + assert response["event"] == [ + { + "entry": { + "disabled_by": "user", + "domain": "comp3", + "entry_id": ANY, + "pref_disable_new_entities": False, + "pref_disable_polling": False, + "reason": None, + "source": "bla3", + "state": "not_loaded", + "supports_options": False, + "supports_remove_device": False, + "supports_unload": False, + "title": "changed too", + }, + "type": "updated", + } + ] await hass.config_entries.async_remove(entry.entry_id) await hass.config_entries.async_remove(entry2.entry_id) response = await ws_client.receive_json()