diff --git a/.coveragerc b/.coveragerc
index 83555abc974e47f6951f565e8237186ed5ac4143..b21e4d9d7f13e193529770e8c6210dd3a9b2505a 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -1585,10 +1585,6 @@ omit =
     homeassistant/components/vesync/sensor.py
     homeassistant/components/vesync/switch.py
     homeassistant/components/viaggiatreno/sensor.py
-    homeassistant/components/viam/__init__.py
-    homeassistant/components/viam/const.py
-    homeassistant/components/viam/manager.py
-    homeassistant/components/viam/services.py
     homeassistant/components/vicare/__init__.py
     homeassistant/components/vicare/button.py
     homeassistant/components/vicare/climate.py
diff --git a/CODEOWNERS b/CODEOWNERS
index 46476fac7c767b2dcd6fc0ac0a5191cdf2bdfb5a..d4bcc363e587a845fad21a3584ef4fe2b05dc36b 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -1523,8 +1523,6 @@ build.json @home-assistant/supervisor
 /tests/components/version/ @ludeeus
 /homeassistant/components/vesync/ @markperdue @webdjoe @thegardenmonkey @cdnninja
 /tests/components/vesync/ @markperdue @webdjoe @thegardenmonkey @cdnninja
-/homeassistant/components/viam/ @hipsterbrown
-/tests/components/viam/ @hipsterbrown
 /homeassistant/components/vicare/ @CFenner
 /tests/components/vicare/ @CFenner
 /homeassistant/components/vilfo/ @ManneW
diff --git a/homeassistant/components/viam/__init__.py b/homeassistant/components/viam/__init__.py
deleted file mode 100644
index 924e3a544fe245dd268028e90faecbc9b88aab09..0000000000000000000000000000000000000000
--- a/homeassistant/components/viam/__init__.py
+++ /dev/null
@@ -1,59 +0,0 @@
-"""The viam integration."""
-
-from __future__ import annotations
-
-from viam.app.viam_client import ViamClient
-from viam.rpc.dial import Credentials, DialOptions
-
-from homeassistant.config_entries import ConfigEntry
-from homeassistant.const import CONF_ADDRESS, CONF_API_KEY
-from homeassistant.core import HomeAssistant
-from homeassistant.helpers import config_validation as cv
-from homeassistant.helpers.typing import ConfigType
-
-from .const import (
-    CONF_API_ID,
-    CONF_CREDENTIAL_TYPE,
-    CONF_SECRET,
-    CRED_TYPE_API_KEY,
-    DOMAIN,
-)
-from .manager import ViamManager
-from .services import async_setup_services
-
-CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN)
-
-
-async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
-    """Set up the Viam services."""
-
-    async_setup_services(hass)
-
-    return True
-
-
-async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
-    """Set up viam from a config entry."""
-    credential_type = entry.data[CONF_CREDENTIAL_TYPE]
-    payload = entry.data[CONF_SECRET]
-    auth_entity = entry.data[CONF_ADDRESS]
-    if credential_type == CRED_TYPE_API_KEY:
-        payload = entry.data[CONF_API_KEY]
-        auth_entity = entry.data[CONF_API_ID]
-
-    credentials = Credentials(type=credential_type, payload=payload)
-    dial_options = DialOptions(auth_entity=auth_entity, credentials=credentials)
-    viam_client = await ViamClient.create_from_dial_options(dial_options=dial_options)
-    manager = ViamManager(hass, viam_client, entry.entry_id, dict(entry.data))
-
-    hass.data.setdefault(DOMAIN, {})[entry.entry_id] = manager
-
-    return True
-
-
-async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
-    """Unload a config entry."""
-    manager: ViamManager = hass.data[DOMAIN].pop(entry.entry_id)
-    manager.unload()
-
-    return True
diff --git a/homeassistant/components/viam/config_flow.py b/homeassistant/components/viam/config_flow.py
deleted file mode 100644
index 5afa00769e39d97d18fdcbbbc2b55f1218f82c75..0000000000000000000000000000000000000000
--- a/homeassistant/components/viam/config_flow.py
+++ /dev/null
@@ -1,212 +0,0 @@
-"""Config flow for viam integration."""
-
-from __future__ import annotations
-
-import logging
-from typing import Any
-
-from viam.app.viam_client import ViamClient
-from viam.rpc.dial import Credentials, DialOptions
-import voluptuous as vol
-
-from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
-from homeassistant.const import CONF_ADDRESS, CONF_API_KEY
-from homeassistant.core import callback
-from homeassistant.exceptions import HomeAssistantError
-from homeassistant.helpers.selector import (
-    SelectOptionDict,
-    SelectSelector,
-    SelectSelectorConfig,
-)
-
-from .const import (
-    CONF_API_ID,
-    CONF_CREDENTIAL_TYPE,
-    CONF_ROBOT,
-    CONF_ROBOT_ID,
-    CONF_SECRET,
-    CRED_TYPE_API_KEY,
-    CRED_TYPE_LOCATION_SECRET,
-    DOMAIN,
-)
-
-_LOGGER = logging.getLogger(__name__)
-
-
-STEP_AUTH_USER_DATA_SCHEMA = vol.Schema(
-    {
-        vol.Required(CONF_CREDENTIAL_TYPE): SelectSelector(
-            SelectSelectorConfig(
-                options=[
-                    CRED_TYPE_API_KEY,
-                    CRED_TYPE_LOCATION_SECRET,
-                ],
-                translation_key=CONF_CREDENTIAL_TYPE,
-            )
-        )
-    }
-)
-STEP_AUTH_ROBOT_DATA_SCHEMA = vol.Schema(
-    {
-        vol.Required(CONF_ADDRESS): str,
-        vol.Required(CONF_SECRET): str,
-    }
-)
-STEP_AUTH_ORG_DATA_SCHEMA = vol.Schema(
-    {
-        vol.Required(CONF_API_ID): str,
-        vol.Required(CONF_API_KEY): str,
-    }
-)
-
-
-async def validate_input(data: dict[str, Any]) -> tuple[str, ViamClient]:
-    """Validate the user input allows us to connect.
-
-    Data has the keys from STEP_USER_DATA_SCHEMA with values provided by the user.
-    """
-    credential_type = data[CONF_CREDENTIAL_TYPE]
-    auth_entity = data.get(CONF_API_ID)
-    secret = data.get(CONF_API_KEY)
-    if credential_type == CRED_TYPE_LOCATION_SECRET:
-        auth_entity = data.get(CONF_ADDRESS)
-        secret = data.get(CONF_SECRET)
-
-    if not secret:
-        raise CannotConnect
-
-    creds = Credentials(type=credential_type, payload=secret)
-    opts = DialOptions(auth_entity=auth_entity, credentials=creds)
-    client = await ViamClient.create_from_dial_options(opts)
-
-    # If you cannot connect:
-    # throw CannotConnect
-    if client:
-        locations = await client.app_client.list_locations()
-        location = await client.app_client.get_location(next(iter(locations)).id)
-
-        # Return info that you want to store in the config entry.
-        return (location.name, client)
-
-    raise CannotConnect
-
-
-class ViamFlowHandler(ConfigFlow, domain=DOMAIN):
-    """Handle a config flow for viam."""
-
-    VERSION = 1
-
-    def __init__(self) -> None:
-        """Initialize."""
-        self._title = ""
-        self._client: ViamClient
-        self._data: dict[str, Any] = {}
-
-    async def async_step_user(
-        self, user_input: dict[str, Any] | None = None
-    ) -> ConfigFlowResult:
-        """Handle the initial step."""
-        errors: dict[str, str] = {}
-        if user_input is not None:
-            self._data.update(user_input)
-
-            if self._data.get(CONF_CREDENTIAL_TYPE) == CRED_TYPE_API_KEY:
-                return await self.async_step_auth_api_key()
-
-            return await self.async_step_auth_robot_location()
-
-        return self.async_show_form(
-            step_id="user", data_schema=STEP_AUTH_USER_DATA_SCHEMA, errors=errors
-        )
-
-    async def async_step_auth_api_key(
-        self, user_input: dict[str, Any] | None = None
-    ) -> ConfigFlowResult:
-        """Handle the API Key authentication."""
-        errors = await self.__handle_auth_input(user_input)
-        if errors is None:
-            return await self.async_step_robot()
-
-        return self.async_show_form(
-            step_id="auth_api_key",
-            data_schema=STEP_AUTH_ORG_DATA_SCHEMA,
-            errors=errors,
-        )
-
-    async def async_step_auth_robot_location(
-        self, user_input: dict[str, Any] | None = None
-    ) -> ConfigFlowResult:
-        """Handle the robot location authentication."""
-        errors = await self.__handle_auth_input(user_input)
-        if errors is None:
-            return await self.async_step_robot()
-
-        return self.async_show_form(
-            step_id="auth_robot_location",
-            data_schema=STEP_AUTH_ROBOT_DATA_SCHEMA,
-            errors=errors,
-        )
-
-    async def async_step_robot(
-        self, user_input: dict[str, Any] | None = None
-    ) -> ConfigFlowResult:
-        """Select robot from location."""
-        if user_input is not None:
-            self._data.update({CONF_ROBOT_ID: user_input[CONF_ROBOT]})
-            return self.async_create_entry(title=self._title, data=self._data)
-
-        app_client = self._client.app_client
-        locations = await app_client.list_locations()
-        robots = await app_client.list_robots(next(iter(locations)).id)
-
-        return self.async_show_form(
-            step_id="robot",
-            data_schema=vol.Schema(
-                {
-                    vol.Required(CONF_ROBOT): SelectSelector(
-                        SelectSelectorConfig(
-                            options=[
-                                SelectOptionDict(value=robot.id, label=robot.name)
-                                for robot in robots
-                            ]
-                        )
-                    )
-                }
-            ),
-        )
-
-    @callback
-    def async_remove(self) -> None:
-        """Notification that the flow has been removed."""
-        if self._client is not None:
-            self._client.close()
-
-    async def __handle_auth_input(
-        self, user_input: dict[str, Any] | None = None
-    ) -> dict[str, str] | None:
-        """Validate user input for the common authentication logic.
-
-        Returns:
-            A dictionary with any handled errors if any occurred, or None
-
-        """
-        errors: dict[str, str] | None = None
-        if user_input is not None:
-            try:
-                self._data.update(user_input)
-                (title, client) = await validate_input(self._data)
-                self._title = title
-                self._client = client
-            except CannotConnect:
-                errors = {"base": "cannot_connect"}
-            except Exception:  # pylint: disable=broad-except
-                _LOGGER.exception("Unexpected exception")
-                errors = {"base": "unknown"}
-        else:
-            errors = {}
-
-        return errors
-
-
-class CannotConnect(HomeAssistantError):
-    """Error to indicate we cannot connect."""
diff --git a/homeassistant/components/viam/const.py b/homeassistant/components/viam/const.py
deleted file mode 100644
index 9cf4932d04e9ed766f5d7927b7defaa6c594977a..0000000000000000000000000000000000000000
--- a/homeassistant/components/viam/const.py
+++ /dev/null
@@ -1,12 +0,0 @@
-"""Constants for the viam integration."""
-
-DOMAIN = "viam"
-
-CONF_API_ID = "api_id"
-CONF_SECRET = "secret"
-CONF_CREDENTIAL_TYPE = "credential_type"
-CONF_ROBOT = "robot"
-CONF_ROBOT_ID = "robot_id"
-
-CRED_TYPE_API_KEY = "api-key"
-CRED_TYPE_LOCATION_SECRET = "robot-location-secret"
diff --git a/homeassistant/components/viam/icons.json b/homeassistant/components/viam/icons.json
deleted file mode 100644
index 0145db44d2171b0caaf7fc648ec05eb8152b57b4..0000000000000000000000000000000000000000
--- a/homeassistant/components/viam/icons.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "services": {
-    "capture_image": "mdi:camera",
-    "capture_data": "mdi:data-matrix",
-    "get_classifications": "mdi:cctv",
-    "get_detections": "mdi:cctv"
-  }
-}
diff --git a/homeassistant/components/viam/manager.py b/homeassistant/components/viam/manager.py
deleted file mode 100644
index 0248ed661971b05f2e6a85b855aa4d0a5056eae5..0000000000000000000000000000000000000000
--- a/homeassistant/components/viam/manager.py
+++ /dev/null
@@ -1,86 +0,0 @@
-"""Manage Viam client connection."""
-
-from typing import Any
-
-from viam.app.app_client import RobotPart
-from viam.app.viam_client import ViamClient
-from viam.robot.client import RobotClient
-from viam.rpc.dial import Credentials, DialOptions
-
-from homeassistant.const import CONF_ADDRESS
-from homeassistant.core import HomeAssistant
-from homeassistant.exceptions import ServiceValidationError
-
-from .const import (
-    CONF_API_ID,
-    CONF_CREDENTIAL_TYPE,
-    CONF_ROBOT_ID,
-    CONF_SECRET,
-    CRED_TYPE_API_KEY,
-    CRED_TYPE_LOCATION_SECRET,
-    DOMAIN,
-)
-
-
-class ViamManager:
-    """Manage Viam client and entry data."""
-
-    def __init__(
-        self,
-        hass: HomeAssistant,
-        viam: ViamClient,
-        entry_id: str,
-        data: dict[str, Any],
-    ) -> None:
-        """Store initialized client and user input data."""
-        self.address: str = data.get(CONF_ADDRESS, "")
-        self.auth_entity: str = data.get(CONF_API_ID, "")
-        self.cred_type: str = data.get(CONF_CREDENTIAL_TYPE, CRED_TYPE_API_KEY)
-        self.entry_id = entry_id
-        self.hass = hass
-        self.robot_id: str = data.get(CONF_ROBOT_ID, "")
-        self.secret: str = data.get(CONF_SECRET, "")
-        self.viam = viam
-
-    def unload(self) -> None:
-        """Clean up any open clients."""
-        self.viam.close()
-
-    async def get_robot_client(
-        self, robot_secret: str | None, robot_address: str | None
-    ) -> RobotClient:
-        """Check initialized data to create robot client."""
-        address = self.address
-        payload = self.secret
-        cred_type = self.cred_type
-        auth_entity: str | None = self.auth_entity
-
-        if robot_secret is not None:
-            if robot_address is None:
-                raise ServiceValidationError(
-                    "The robot address is required for this connection type.",
-                    translation_domain=DOMAIN,
-                    translation_key="robot_credentials_required",
-                )
-            cred_type = CRED_TYPE_LOCATION_SECRET
-            auth_entity = None
-            address = robot_address
-            payload = robot_secret
-
-        if address is None or payload is None:
-            raise ServiceValidationError(
-                "The necessary credentials for the RobotClient could not be found.",
-                translation_domain=DOMAIN,
-                translation_key="robot_credentials_not_found",
-            )
-
-        credentials = Credentials(type=cred_type, payload=payload)
-        robot_options = RobotClient.Options(
-            refresh_interval=0,
-            dial_options=DialOptions(auth_entity=auth_entity, credentials=credentials),
-        )
-        return await RobotClient.at_address(address, robot_options)
-
-    async def get_robot_parts(self) -> list[RobotPart]:
-        """Retrieve list of robot parts."""
-        return await self.viam.app_client.get_robot_parts(robot_id=self.robot_id)
diff --git a/homeassistant/components/viam/manifest.json b/homeassistant/components/viam/manifest.json
deleted file mode 100644
index 6626d2e3ddf6f7c947e5a7fd5be7f2b1bf7772c8..0000000000000000000000000000000000000000
--- a/homeassistant/components/viam/manifest.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-  "domain": "viam",
-  "name": "Viam",
-  "codeowners": ["@hipsterbrown"],
-  "config_flow": true,
-  "documentation": "https://www.home-assistant.io/integrations/viam",
-  "integration_type": "hub",
-  "iot_class": "cloud_polling",
-  "requirements": ["viam-sdk==0.17.0"]
-}
diff --git a/homeassistant/components/viam/services.py b/homeassistant/components/viam/services.py
deleted file mode 100644
index fbe0169d5510ba0e2fddd7de0f86de2d7836811d..0000000000000000000000000000000000000000
--- a/homeassistant/components/viam/services.py
+++ /dev/null
@@ -1,325 +0,0 @@
-"""Services for Viam integration."""
-
-from __future__ import annotations
-
-import base64
-from datetime import datetime
-from functools import partial
-
-from PIL import Image
-from viam.app.app_client import RobotPart
-from viam.services.vision import VisionClient
-from viam.services.vision.client import RawImage
-import voluptuous as vol
-
-from homeassistant.components import camera
-from homeassistant.config_entries import ConfigEntry, ConfigEntryState
-from homeassistant.core import (
-    HomeAssistant,
-    ServiceCall,
-    ServiceResponse,
-    SupportsResponse,
-    callback,
-)
-from homeassistant.exceptions import ServiceValidationError
-from homeassistant.helpers import selector
-
-from .const import DOMAIN
-from .manager import ViamManager
-
-ATTR_CONFIG_ENTRY = "config_entry"
-
-DATA_CAPTURE_SERVICE_NAME = "capture_data"
-CAPTURE_IMAGE_SERVICE_NAME = "capture_image"
-CLASSIFICATION_SERVICE_NAME = "get_classifications"
-DETECTIONS_SERVICE_NAME = "get_detections"
-
-SERVICE_VALUES = "values"
-SERVICE_COMPONENT_NAME = "component_name"
-SERVICE_COMPONENT_TYPE = "component_type"
-SERVICE_FILEPATH = "filepath"
-SERVICE_CAMERA = "camera"
-SERVICE_CONFIDENCE = "confidence_threshold"
-SERVICE_ROBOT_ADDRESS = "robot_address"
-SERVICE_ROBOT_SECRET = "robot_secret"
-SERVICE_FILE_NAME = "file_name"
-SERVICE_CLASSIFIER_NAME = "classifier_name"
-SERVICE_COUNT = "count"
-SERVICE_DETECTOR_NAME = "detector_name"
-
-ENTRY_SERVICE_SCHEMA = vol.Schema(
-    {
-        vol.Required(ATTR_CONFIG_ENTRY): selector.ConfigEntrySelector(
-            {
-                "integration": DOMAIN,
-            }
-        ),
-    }
-)
-DATA_CAPTURE_SERVICE_SCHEMA = ENTRY_SERVICE_SCHEMA.extend(
-    {
-        vol.Required(SERVICE_VALUES): vol.All(dict),
-        vol.Required(SERVICE_COMPONENT_NAME): vol.All(str),
-        vol.Required(SERVICE_COMPONENT_TYPE, default="sensor"): vol.All(str),
-    }
-)
-
-IMAGE_SERVICE_FIELDS = ENTRY_SERVICE_SCHEMA.extend(
-    {
-        vol.Optional(SERVICE_FILEPATH): vol.All(str, vol.IsFile),
-        vol.Optional(SERVICE_CAMERA): vol.All(str),
-    }
-)
-VISION_SERVICE_FIELDS = IMAGE_SERVICE_FIELDS.extend(
-    {
-        vol.Optional(SERVICE_CONFIDENCE, default="0.6"): vol.All(
-            str, vol.Coerce(float), vol.Range(min=0, max=1)
-        ),
-        vol.Optional(SERVICE_ROBOT_ADDRESS): vol.All(str),
-        vol.Optional(SERVICE_ROBOT_SECRET): vol.All(str),
-    }
-)
-
-CAPTURE_IMAGE_SERVICE_SCHEMA = IMAGE_SERVICE_FIELDS.extend(
-    {
-        vol.Optional(SERVICE_FILE_NAME, default="camera"): vol.All(str),
-        vol.Optional(SERVICE_COMPONENT_NAME): vol.All(str),
-    }
-)
-
-CLASSIFICATION_SERVICE_SCHEMA = VISION_SERVICE_FIELDS.extend(
-    {
-        vol.Required(SERVICE_CLASSIFIER_NAME): vol.All(str),
-        vol.Optional(SERVICE_COUNT, default="2"): vol.All(str, vol.Coerce(int)),
-    }
-)
-
-DETECTIONS_SERVICE_SCHEMA = VISION_SERVICE_FIELDS.extend(
-    {
-        vol.Required(SERVICE_DETECTOR_NAME): vol.All(str),
-    }
-)
-
-
-def __fetch_image(filepath: str | None) -> Image.Image | None:
-    if filepath is None:
-        return None
-    return Image.open(filepath)
-
-
-def __encode_image(image: Image.Image | RawImage) -> str:
-    """Create base64-encoded Image string."""
-    if isinstance(image, Image.Image):
-        image_bytes = image.tobytes()
-    else:  # RawImage
-        image_bytes = image.data
-
-    image_string = base64.b64encode(image_bytes).decode()
-    return f"data:image/jpeg;base64,{image_string}"
-
-
-async def __get_image(
-    hass: HomeAssistant, filepath: str | None, camera_entity: str | None
-) -> RawImage | Image.Image | None:
-    """Retrieve image type from camera entity or file system."""
-    if filepath is not None:
-        return await hass.async_add_executor_job(__fetch_image, filepath)
-    if camera_entity is not None:
-        image = await camera.async_get_image(hass, camera_entity)
-        return RawImage(image.content, image.content_type)
-
-    return None
-
-
-def __get_manager(hass: HomeAssistant, call: ServiceCall) -> ViamManager:
-    entry_id: str = call.data[ATTR_CONFIG_ENTRY]
-    entry: ConfigEntry | None = hass.config_entries.async_get_entry(entry_id)
-
-    if not entry:
-        raise ServiceValidationError(
-            f"Invalid config entry: {entry_id}",
-            translation_domain=DOMAIN,
-            translation_key="invalid_config_entry",
-            translation_placeholders={
-                "config_entry": entry_id,
-            },
-        )
-    if entry.state != ConfigEntryState.LOADED:
-        raise ServiceValidationError(
-            f"{entry.title} is not loaded",
-            translation_domain=DOMAIN,
-            translation_key="unloaded_config_entry",
-            translation_placeholders={
-                "config_entry": entry.title,
-            },
-        )
-
-    manager: ViamManager = hass.data[DOMAIN][entry_id]
-    return manager
-
-
-async def __capture_data(call: ServiceCall, *, hass: HomeAssistant) -> None:
-    """Accept input from service call to send to Viam."""
-    manager: ViamManager = __get_manager(hass, call)
-    parts: list[RobotPart] = await manager.get_robot_parts()
-    values = [call.data.get(SERVICE_VALUES, {})]
-    component_type = call.data.get(SERVICE_COMPONENT_TYPE, "sensor")
-    component_name = call.data.get(SERVICE_COMPONENT_NAME, "")
-
-    await manager.viam.data_client.tabular_data_capture_upload(
-        tabular_data=values,
-        part_id=parts.pop().id,
-        component_type=component_type,
-        component_name=component_name,
-        method_name="capture_data",
-        data_request_times=[(datetime.now(), datetime.now())],
-    )
-
-
-async def __capture_image(call: ServiceCall, *, hass: HomeAssistant) -> None:
-    """Accept input from service call to send to Viam."""
-    manager: ViamManager = __get_manager(hass, call)
-    parts: list[RobotPart] = await manager.get_robot_parts()
-    filepath = call.data.get(SERVICE_FILEPATH)
-    camera_entity = call.data.get(SERVICE_CAMERA)
-    component_name = call.data.get(SERVICE_COMPONENT_NAME)
-    file_name = call.data.get(SERVICE_FILE_NAME, "camera")
-
-    if filepath is not None:
-        await manager.viam.data_client.file_upload_from_path(
-            filepath=filepath,
-            part_id=parts.pop().id,
-            component_name=component_name,
-        )
-    if camera_entity is not None:
-        image = await camera.async_get_image(hass, camera_entity)
-        await manager.viam.data_client.file_upload(
-            part_id=parts.pop().id,
-            component_name=component_name,
-            file_name=file_name,
-            file_extension=".jpeg",
-            data=image.content,
-        )
-
-
-async def __get_service_values(
-    hass: HomeAssistant, call: ServiceCall, service_config_name: str
-):
-    """Create common values for vision services."""
-    manager: ViamManager = __get_manager(hass, call)
-    filepath = call.data.get(SERVICE_FILEPATH)
-    camera_entity = call.data.get(SERVICE_CAMERA)
-    service_name = call.data.get(service_config_name, "")
-    count = int(call.data.get(SERVICE_COUNT, 2))
-    confidence_threshold = float(call.data.get(SERVICE_CONFIDENCE, 0.6))
-
-    async with await manager.get_robot_client(
-        call.data.get(SERVICE_ROBOT_SECRET), call.data.get(SERVICE_ROBOT_ADDRESS)
-    ) as robot:
-        service: VisionClient = VisionClient.from_robot(robot, service_name)
-        image = await __get_image(hass, filepath, camera_entity)
-
-    return manager, service, image, filepath, confidence_threshold, count
-
-
-async def __get_classifications(
-    call: ServiceCall, *, hass: HomeAssistant
-) -> ServiceResponse:
-    """Accept input configuration to request classifications."""
-    (
-        manager,
-        classifier,
-        image,
-        filepath,
-        confidence_threshold,
-        count,
-    ) = await __get_service_values(hass, call, SERVICE_CLASSIFIER_NAME)
-
-    if image is None:
-        return {
-            "classifications": [],
-            "img_src": filepath or None,
-        }
-
-    img_src = filepath or __encode_image(image)
-    classifications = await classifier.get_classifications(image, count)
-
-    return {
-        "classifications": [
-            {"name": c.class_name, "confidence": c.confidence}
-            for c in classifications
-            if c.confidence >= confidence_threshold
-        ],
-        "img_src": img_src,
-    }
-
-
-async def __get_detections(
-    call: ServiceCall, *, hass: HomeAssistant
-) -> ServiceResponse:
-    """Accept input configuration to request detections."""
-    (
-        manager,
-        detector,
-        image,
-        filepath,
-        confidence_threshold,
-        _count,
-    ) = await __get_service_values(hass, call, SERVICE_DETECTOR_NAME)
-
-    if image is None:
-        return {
-            "detections": [],
-            "img_src": filepath or None,
-        }
-
-    img_src = filepath or __encode_image(image)
-    detections = await detector.get_detections(image)
-
-    return {
-        "detections": [
-            {
-                "name": c.class_name,
-                "confidence": c.confidence,
-                "x_min": c.x_min,
-                "y_min": c.y_min,
-                "x_max": c.x_max,
-                "y_max": c.y_max,
-            }
-            for c in detections
-            if c.confidence >= confidence_threshold
-        ],
-        "img_src": img_src,
-    }
-
-
-@callback
-def async_setup_services(hass: HomeAssistant) -> None:
-    """Set up services for Viam integration."""
-
-    hass.services.async_register(
-        DOMAIN,
-        DATA_CAPTURE_SERVICE_NAME,
-        partial(__capture_data, hass=hass),
-        DATA_CAPTURE_SERVICE_SCHEMA,
-    )
-    hass.services.async_register(
-        DOMAIN,
-        CAPTURE_IMAGE_SERVICE_NAME,
-        partial(__capture_image, hass=hass),
-        CAPTURE_IMAGE_SERVICE_SCHEMA,
-    )
-    hass.services.async_register(
-        DOMAIN,
-        CLASSIFICATION_SERVICE_NAME,
-        partial(__get_classifications, hass=hass),
-        CLASSIFICATION_SERVICE_SCHEMA,
-        supports_response=SupportsResponse.ONLY,
-    )
-    hass.services.async_register(
-        DOMAIN,
-        DETECTIONS_SERVICE_NAME,
-        partial(__get_detections, hass=hass),
-        DETECTIONS_SERVICE_SCHEMA,
-        supports_response=SupportsResponse.ONLY,
-    )
diff --git a/homeassistant/components/viam/services.yaml b/homeassistant/components/viam/services.yaml
deleted file mode 100644
index 76a35e1ff067b4b6c2cf0679e987695f19f0b628..0000000000000000000000000000000000000000
--- a/homeassistant/components/viam/services.yaml
+++ /dev/null
@@ -1,98 +0,0 @@
-capture_data:
-  fields:
-    values:
-      required: true
-      selector:
-        object:
-    component_name:
-      required: true
-      selector:
-        text:
-    component_type:
-      required: false
-      selector:
-        text:
-capture_image:
-  fields:
-    filepath:
-      required: false
-      selector:
-        text:
-    camera:
-      required: false
-      selector:
-        entity:
-          filter:
-            domain: camera
-    file_name:
-      required: false
-      selector:
-        text:
-    component_name:
-      required: false
-      selector:
-        text:
-get_classifications:
-  fields:
-    classifier_name:
-      required: true
-      selector:
-        text:
-    confidence:
-      required: false
-      default: 0.6
-      selector:
-        text:
-          type: number
-    count:
-      required: false
-      selector:
-        number:
-    robot_address:
-      required: false
-      selector:
-        text:
-    robot_secret:
-      required: false
-      selector:
-        text:
-    filepath:
-      required: false
-      selector:
-        text:
-    camera:
-      required: false
-      selector:
-        entity:
-          filter:
-            domain: camera
-get_detections:
-  fields:
-    detector_name:
-      required: true
-      selector:
-        text:
-    confidence:
-      required: false
-      default: 0.6
-      selector:
-        text:
-          type: number
-    robot_address:
-      required: false
-      selector:
-        text:
-    robot_secret:
-      required: false
-      selector:
-        text:
-    filepath:
-      required: false
-      selector:
-        text:
-    camera:
-      required: false
-      selector:
-        entity:
-          filter:
-            domain: camera
diff --git a/homeassistant/components/viam/strings.json b/homeassistant/components/viam/strings.json
deleted file mode 100644
index e6074749ca798168916a51a28e5067b4cec9c600..0000000000000000000000000000000000000000
--- a/homeassistant/components/viam/strings.json
+++ /dev/null
@@ -1,171 +0,0 @@
-{
-  "config": {
-    "step": {
-      "user": {
-        "title": "Authenticate with Viam",
-        "description": "Select which credential type to use.",
-        "data": {
-          "credential_type": "Credential type"
-        }
-      },
-      "auth": {
-        "title": "[%key:component::viam::config::step::user::title%]",
-        "description": "Provide the credentials for communicating with the Viam service.",
-        "data": {
-          "api_id": "API key ID",
-          "api_key": "API key",
-          "address": "Robot address",
-          "secret": "Robot secret"
-        },
-        "data_description": {
-          "address": "Find this under the Code Sample tab in the app.",
-          "secret": "Find this under the Code Sample tab in the app when 'include secret' is enabled."
-        }
-      },
-      "robot": {
-        "data": {
-          "robot": "Select a robot"
-        }
-      }
-    },
-    "error": {
-      "cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
-      "invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",
-      "unknown": "[%key:common::config_flow::error::unknown%]"
-    }
-  },
-  "selector": {
-    "credential_type": {
-      "options": {
-        "api-key": "Org API key",
-        "robot-location-secret": "Robot location secret"
-      }
-    }
-  },
-  "exceptions": {
-    "entry_not_found": {
-      "message": "No Viam config entries found"
-    },
-    "entry_not_loaded": {
-      "message": "{config_entry_title} is not loaded"
-    },
-    "invalid_config_entry": {
-      "message": "Invalid config entry provided. Got {config_entry}"
-    },
-    "unloaded_config_entry": {
-      "message": "Invalid config entry provided. {config_entry} is not loaded."
-    },
-    "robot_credentials_required": {
-      "message": "The robot address is required for this connection type."
-    },
-    "robot_credentials_not_found": {
-      "message": "The necessary credentials for the RobotClient could not be found."
-    }
-  },
-  "services": {
-    "capture_data": {
-      "name": "Capture data",
-      "description": "Send arbitrary tabular data to Viam for analytics and model training.",
-      "fields": {
-        "values": {
-          "name": "Values",
-          "description": "List of tabular data to send to Viam."
-        },
-        "component_name": {
-          "name": "Component name",
-          "description": "The name of the configured robot component to use."
-        },
-        "component_type": {
-          "name": "Component type",
-          "description": "The type of the associated component."
-        }
-      }
-    },
-    "capture_image": {
-      "name": "Capture image",
-      "description": "Send images to Viam for analytics and model training.",
-      "fields": {
-        "filepath": {
-          "name": "Filepath",
-          "description": "Local file path to the image you wish to reference."
-        },
-        "camera": {
-          "name": "Camera entity",
-          "description": "The camera entity from which an image is captured."
-        },
-        "file_name": {
-          "name": "File name",
-          "description": "The name of the file that will be displayed in the metadata within Viam."
-        },
-        "component_name": {
-          "name": "Component name",
-          "description": "The name of the configured robot component to use."
-        }
-      }
-    },
-    "get_classifications": {
-      "name": "Classify images",
-      "description": "Get a list of classifications from an image.",
-      "fields": {
-        "classifier_name": {
-          "name": "Classifier name",
-          "description": "Name of classifier vision service configured in Viam"
-        },
-        "confidence": {
-          "name": "Confidence",
-          "description": "Threshold for filtering results returned by the service"
-        },
-        "count": {
-          "name": "Classification count",
-          "description": "Number of classifications to return from the service"
-        },
-        "robot_address": {
-          "name": "Robot address",
-          "description": "If authenticated using an Org API key, provide the robot address associated with the configured vision service."
-        },
-        "robot_secret": {
-          "name": "Robot secret",
-          "description": "If authenticated using an Org API key, provide the robot location secret associated with the configured vision service."
-        },
-        "filepath": {
-          "name": "Filepath",
-          "description": "Local file path to the image you wish to reference."
-        },
-        "camera": {
-          "name": "Camera entity",
-          "description": "The camera entity from which an image is captured."
-        }
-      }
-    },
-    "get_detections": {
-      "name": "Detect objects in images",
-      "description": "Get a list of detected objects from an image.",
-      "fields": {
-        "detector_name": {
-          "name": "Detector name",
-          "description": "Name of detector vision service configured in Viam"
-        },
-        "confidence": {
-          "name": "Confidence",
-          "description": "Threshold for filtering results returned by the service"
-        },
-        "robot_address": {
-          "name": "Robot address",
-          "description": "If authenticated using an Org API key, provide the robot address associated with the configured vision service."
-        },
-        "robot_secret": {
-          "name": "Robot secret",
-          "description": "If authenticated using an Org API key, provide the robot location secret associated with the configured vision service."
-        },
-        "filepath": {
-          "name": "Filepath",
-          "description": "Local file path to the image you wish to reference."
-        },
-        "camera": {
-          "name": "Camera entity",
-          "description": "The camera entity from which an image is captured."
-        }
-      }
-    }
-  }
-}
diff --git a/homeassistant/generated/config_flows.py b/homeassistant/generated/config_flows.py
index 1987581ff7c3a09d8b0d504770e5b70b3ef13a5e..9f24c9676e5550b3b97a9bfea3bfec3df3497716 100644
--- a/homeassistant/generated/config_flows.py
+++ b/homeassistant/generated/config_flows.py
@@ -592,7 +592,6 @@ FLOWS = {
         "verisure",
         "version",
         "vesync",
-        "viam",
         "vicare",
         "vilfo",
         "vizio",
diff --git a/homeassistant/generated/integrations.json b/homeassistant/generated/integrations.json
index 7c2f8a95de53694828ddea5dd1441794064caad8..d5199e6ba1e7bdb117fd0ed62e7965cf813a89c0 100644
--- a/homeassistant/generated/integrations.json
+++ b/homeassistant/generated/integrations.json
@@ -6603,12 +6603,6 @@
       "config_flow": false,
       "iot_class": "cloud_polling"
     },
-    "viam": {
-      "name": "Viam",
-      "integration_type": "hub",
-      "config_flow": true,
-      "iot_class": "cloud_polling"
-    },
     "vicare": {
       "name": "Viessmann ViCare",
       "integration_type": "hub",
diff --git a/requirements_all.txt b/requirements_all.txt
index 0a1c8a9899e6a4f7debd7295ec59e8f9a926ba88..bc1457cd3742b62942f5eff877bce61995e1970f 100644
--- a/requirements_all.txt
+++ b/requirements_all.txt
@@ -2816,9 +2816,6 @@ velbus-aio==2024.4.1
 # homeassistant.components.venstar
 venstarcolortouch==0.19
 
-# homeassistant.components.viam
-viam-sdk==0.17.0
-
 # homeassistant.components.vilfo
 vilfo-api-client==0.5.0
 
diff --git a/requirements_test_all.txt b/requirements_test_all.txt
index bcb3484f30f5289719cdab22dc5f0e070314b723..06e7ae8fd30e00d1789a5f25c90907728ea1b93b 100644
--- a/requirements_test_all.txt
+++ b/requirements_test_all.txt
@@ -2184,9 +2184,6 @@ velbus-aio==2024.4.1
 # homeassistant.components.venstar
 venstarcolortouch==0.19
 
-# homeassistant.components.viam
-viam-sdk==0.17.0
-
 # homeassistant.components.vilfo
 vilfo-api-client==0.5.0
 
diff --git a/tests/components/viam/__init__.py b/tests/components/viam/__init__.py
deleted file mode 100644
index f606728242ea35d88425abef5efb02808be5b971..0000000000000000000000000000000000000000
--- a/tests/components/viam/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-"""Tests for the viam integration."""
diff --git a/tests/components/viam/conftest.py b/tests/components/viam/conftest.py
deleted file mode 100644
index 3da6b27214524a000b716c4c919af694373df94d..0000000000000000000000000000000000000000
--- a/tests/components/viam/conftest.py
+++ /dev/null
@@ -1,60 +0,0 @@
-"""Common fixtures for the viam tests."""
-
-import asyncio
-from collections.abc import Generator
-from dataclasses import dataclass
-from unittest.mock import AsyncMock, MagicMock, patch
-
-import pytest
-from viam.app.viam_client import ViamClient
-
-
-@dataclass
-class MockLocation:
-    """Fake location for testing."""
-
-    id: str = "13"
-    name: str = "home"
-
-
-@dataclass
-class MockRobot:
-    """Fake robot for testing."""
-
-    id: str = "1234"
-    name: str = "test"
-
-
-def async_return(result):
-    """Allow async return value with MagicMock."""
-
-    future = asyncio.Future()
-    future.set_result(result)
-    return future
-
-
-@pytest.fixture
-def mock_setup_entry() -> Generator[AsyncMock, None, None]:
-    """Override async_setup_entry."""
-    with patch(
-        "homeassistant.components.viam.async_setup_entry", return_value=True
-    ) as mock_setup_entry:
-        yield mock_setup_entry
-
-
-@pytest.fixture(name="mock_viam_client")
-def mock_viam_client_fixture() -> Generator[tuple[MagicMock, MockRobot], None, None]:
-    """Override ViamClient from Viam SDK."""
-    with (
-        patch("viam.app.viam_client.ViamClient") as MockClient,
-        patch.object(ViamClient, "create_from_dial_options") as mock_create_client,
-    ):
-        instance: MagicMock = MockClient.return_value
-        mock_create_client.return_value = instance
-
-        mock_location = MockLocation()
-        mock_robot = MockRobot()
-        instance.app_client.list_locations.return_value = async_return([mock_location])
-        instance.app_client.get_location.return_value = async_return(mock_location)
-        instance.app_client.list_robots.return_value = async_return([mock_robot])
-        yield instance, mock_robot
diff --git a/tests/components/viam/test_config_flow.py b/tests/components/viam/test_config_flow.py
deleted file mode 100644
index 8ab6edb154fc925d169b9cb6437877e6be7dc488..0000000000000000000000000000000000000000
--- a/tests/components/viam/test_config_flow.py
+++ /dev/null
@@ -1,238 +0,0 @@
-"""Test the viam config flow."""
-
-from collections.abc import Generator
-from unittest.mock import AsyncMock, MagicMock, patch
-
-import pytest
-from viam.app.viam_client import ViamClient
-
-from homeassistant import config_entries
-from homeassistant.components.viam.config_flow import CannotConnect
-from homeassistant.components.viam.const import (
-    CONF_API_ID,
-    CONF_CREDENTIAL_TYPE,
-    CONF_ROBOT,
-    CONF_ROBOT_ID,
-    CONF_SECRET,
-    CRED_TYPE_API_KEY,
-    CRED_TYPE_LOCATION_SECRET,
-    DOMAIN,
-)
-from homeassistant.const import CONF_ADDRESS, CONF_API_KEY
-from homeassistant.core import HomeAssistant
-from homeassistant.data_entry_flow import FlowResultType
-
-from .conftest import MockRobot
-
-pytestmark = pytest.mark.usefixtures("mock_setup_entry")
-
-
-async def test_user_form(
-    hass: HomeAssistant,
-    mock_setup_entry: AsyncMock,
-    mock_viam_client: Generator[tuple[MagicMock, MockRobot], None, None],
-) -> None:
-    """Test that the form is served with no input."""
-    result = await hass.config_entries.flow.async_init(
-        DOMAIN, context={"source": config_entries.SOURCE_USER}
-    )
-
-    assert result["type"] == FlowResultType.FORM
-    assert result["errors"] == {}
-    assert result["step_id"] == "user"
-
-    result = await hass.config_entries.flow.async_configure(
-        result["flow_id"],
-        {
-            CONF_CREDENTIAL_TYPE: CRED_TYPE_API_KEY,
-        },
-    )
-    assert result["type"] == FlowResultType.FORM
-    assert result["step_id"] == "auth_api_key"
-    assert result["errors"] == {}
-
-    _client, mock_robot = mock_viam_client
-
-    result = await hass.config_entries.flow.async_configure(
-        result["flow_id"],
-        {
-            CONF_API_ID: "someTestId",
-            CONF_API_KEY: "randomSecureAPIKey",
-        },
-    )
-    assert result["type"] == FlowResultType.FORM
-    assert result["errors"] is None
-    assert result["step_id"] == "robot"
-
-    result = await hass.config_entries.flow.async_configure(
-        result["flow_id"],
-        {
-            CONF_ROBOT: mock_robot.id,
-        },
-    )
-    await hass.async_block_till_done()
-
-    assert result["type"] == FlowResultType.CREATE_ENTRY
-    assert result["title"] == "home"
-    assert result["data"] == {
-        CONF_API_ID: "someTestId",
-        CONF_API_KEY: "randomSecureAPIKey",
-        CONF_ROBOT_ID: mock_robot.id,
-        CONF_CREDENTIAL_TYPE: CRED_TYPE_API_KEY,
-    }
-
-    assert len(mock_setup_entry.mock_calls) == 1
-
-
-async def test_user_form_with_location_secret(
-    hass: HomeAssistant,
-    mock_setup_entry: AsyncMock,
-    mock_viam_client: Generator[tuple[MagicMock, MockRobot], None, None],
-) -> None:
-    """Test that the form is served with no input."""
-    result = await hass.config_entries.flow.async_init(
-        DOMAIN, context={"source": config_entries.SOURCE_USER}
-    )
-
-    assert result["type"] == FlowResultType.FORM
-    assert result["errors"] == {}
-    assert result["step_id"] == "user"
-
-    result = await hass.config_entries.flow.async_configure(
-        result["flow_id"],
-        {
-            CONF_CREDENTIAL_TYPE: CRED_TYPE_LOCATION_SECRET,
-        },
-    )
-    assert result["type"] == FlowResultType.FORM
-    assert result["step_id"] == "auth_robot_location"
-    assert result["errors"] == {}
-
-    result = await hass.config_entries.flow.async_configure(
-        result["flow_id"],
-        {
-            CONF_ADDRESS: "my.robot.cloud",
-            CONF_SECRET: "randomSecreteForRobot",
-        },
-    )
-    assert result["type"] == FlowResultType.FORM
-    assert result["errors"] is None
-    assert result["step_id"] == "robot"
-
-    _client, mock_robot = mock_viam_client
-
-    result = await hass.config_entries.flow.async_configure(
-        result["flow_id"],
-        {
-            CONF_ROBOT: mock_robot.id,
-        },
-    )
-    await hass.async_block_till_done()
-
-    assert result["type"] == FlowResultType.CREATE_ENTRY
-    assert result["title"] == "home"
-    assert result["data"] == {
-        CONF_ADDRESS: "my.robot.cloud",
-        CONF_SECRET: "randomSecreteForRobot",
-        CONF_ROBOT_ID: mock_robot.id,
-        CONF_CREDENTIAL_TYPE: CRED_TYPE_LOCATION_SECRET,
-    }
-
-    assert len(mock_setup_entry.mock_calls) == 1
-
-
-@patch(
-    "viam.app.viam_client.ViamClient.create_from_dial_options",
-    side_effect=CannotConnect,
-)
-async def test_form_missing_secret(
-    _mock_create_client: AsyncMock, hass: HomeAssistant
-) -> None:
-    """Test we handle cannot connect error."""
-    result = await hass.config_entries.flow.async_init(
-        DOMAIN, context={"source": config_entries.SOURCE_USER}
-    )
-
-    result = await hass.config_entries.flow.async_configure(
-        result["flow_id"],
-        {
-            CONF_CREDENTIAL_TYPE: CRED_TYPE_API_KEY,
-        },
-    )
-    assert result["type"] == FlowResultType.FORM
-    assert result["step_id"] == "auth_api_key"
-
-    result = await hass.config_entries.flow.async_configure(
-        result["flow_id"],
-        {
-            CONF_API_ID: "someTestId",
-            CONF_API_KEY: "",
-        },
-    )
-    assert result["type"] == FlowResultType.FORM
-    assert result["step_id"] == "auth_api_key"
-    assert result["errors"] == {"base": "cannot_connect"}
-
-
-@patch.object(ViamClient, "create_from_dial_options", return_value=None)
-async def test_form_cannot_connect(
-    _mock_create_client: AsyncMock,
-    hass: HomeAssistant,
-    mock_setup_entry: AsyncMock,
-) -> None:
-    """Test we handle cannot connect error."""
-    result = await hass.config_entries.flow.async_init(
-        DOMAIN, context={"source": config_entries.SOURCE_USER}
-    )
-
-    result = await hass.config_entries.flow.async_configure(
-        result["flow_id"],
-        {
-            CONF_CREDENTIAL_TYPE: CRED_TYPE_API_KEY,
-        },
-    )
-    assert result["type"] == FlowResultType.FORM
-    assert result["step_id"] == "auth_api_key"
-
-    result = await hass.config_entries.flow.async_configure(
-        result["flow_id"],
-        {
-            CONF_API_ID: "someTestId",
-            CONF_API_KEY: "randomSecureAPIKey",
-        },
-    )
-    assert result["type"] == FlowResultType.FORM
-    assert result["step_id"] == "auth_api_key"
-    assert result["errors"] == {"base": "cannot_connect"}
-
-
-@patch(
-    "viam.app.viam_client.ViamClient.create_from_dial_options", side_effect=Exception
-)
-async def test_form_exception(
-    _mock_create_client: AsyncMock, hass: HomeAssistant
-) -> None:
-    """Test we handle cannot connect error."""
-    result = await hass.config_entries.flow.async_init(
-        DOMAIN, context={"source": config_entries.SOURCE_USER}
-    )
-
-    result = await hass.config_entries.flow.async_configure(
-        result["flow_id"],
-        {
-            CONF_CREDENTIAL_TYPE: CRED_TYPE_API_KEY,
-        },
-    )
-    assert result["type"] == FlowResultType.FORM
-    assert result["step_id"] == "auth_api_key"
-
-    result = await hass.config_entries.flow.async_configure(
-        result["flow_id"],
-        {
-            CONF_API_ID: "someTestId",
-            CONF_API_KEY: "randomSecureAPIKey",
-        },
-    )
-    assert result["type"] == FlowResultType.FORM
-    assert result["step_id"] == "auth_api_key"
-    assert result["errors"] == {"base": "unknown"}