diff --git a/.gitignore b/.gitignore
index 24c7debdd80..7d32575773a 100755
--- a/.gitignore
+++ b/.gitignore
@@ -160,4 +160,5 @@ opentrons-robot-app.tar.gz
 # asdf versions file
 .tool-versions
 mock_dir
+.npm-cache/
 .eslintcache
diff --git a/api/src/opentrons/config/defaults_ot3.py b/api/src/opentrons/config/defaults_ot3.py
index 0b2499feaab..10b48f36a8d 100644
--- a/api/src/opentrons/config/defaults_ot3.py
+++ b/api/src/opentrons/config/defaults_ot3.py
@@ -44,6 +44,7 @@
             max_overrun_distance_mm=5.0,
             speed_mm_per_s=1.0,
             sensor_threshold_pf=3.0,
+            output_option=OutputOptions.sync_only,
         ),
     ),
     edge_sense=EdgeSenseSettings(
@@ -54,6 +55,7 @@
             max_overrun_distance_mm=0.5,
             speed_mm_per_s=1,
             sensor_threshold_pf=3.0,
+            output_option=OutputOptions.sync_only,
         ),
         search_initial_tolerance_mm=12.0,
         search_iteration_limit=8,
@@ -315,6 +317,7 @@ def _build_default_cap_pass(
         sensor_threshold_pf=from_conf.get(
             "sensor_threshold_pf", default.sensor_threshold_pf
         ),
+        output_option=from_conf.get("output_option", default.output_option),
     )
 
 
diff --git a/api/src/opentrons/config/types.py b/api/src/opentrons/config/types.py
index f13d5a5e6e3..c096d7c098e 100644
--- a/api/src/opentrons/config/types.py
+++ b/api/src/opentrons/config/types.py
@@ -103,12 +103,25 @@ def by_gantry_load(
         )
 
 
+class OutputOptions(int, Enum):
+    """Specifies where we should report sensor data to during a sensor pass."""
+
+    stream_to_csv = 0x1  # compile sensor data stream into a csv file, in addition to can_bus_only behavior
+    sync_buffer_to_csv = 0x2  # collect sensor data on pipette mcu, then stream to robot server and compile into a csv file, in addition to can_bus_only behavior
+    can_bus_only = (
+        0x4  # stream sensor data over CAN bus, in addition to sync_only behavior
+    )
+    sync_only = 0x8  # trigger pipette sync line upon sensor's detection of something
+
+
 @dataclass(frozen=True)
 class CapacitivePassSettings:
     prep_distance_mm: float
     max_overrun_distance_mm: float
     speed_mm_per_s: float
     sensor_threshold_pf: float
+    output_option: OutputOptions
+    data_files: Optional[Dict[InstrumentProbeType, str]] = None
 
 
 @dataclass(frozen=True)
@@ -116,16 +129,6 @@ class ZSenseSettings:
     pass_settings: CapacitivePassSettings
 
 
-# str enum so it can be json serializable
-class OutputOptions(int, Enum):
-    """Specifies where we should report sensor data to during a sensor pass."""
-
-    stream_to_csv = 0x1
-    sync_buffer_to_csv = 0x2
-    can_bus_only = 0x4
-    sync_only = 0x8
-
-
 @dataclass
 class LiquidProbeSettings:
     starting_mount_height: float
diff --git a/api/src/opentrons/hardware_control/backends/flex_protocol.py b/api/src/opentrons/hardware_control/backends/flex_protocol.py
index 7bd2969de6b..31dcb24a0c2 100644
--- a/api/src/opentrons/hardware_control/backends/flex_protocol.py
+++ b/api/src/opentrons/hardware_control/backends/flex_protocol.py
@@ -365,7 +365,9 @@ async def capacitive_probe(
         distance_mm: float,
         speed_mm_per_s: float,
         sensor_threshold_pf: float,
-        probe: InstrumentProbeType,
+        probe: InstrumentProbeType = InstrumentProbeType.PRIMARY,
+        output_format: OutputOptions = OutputOptions.sync_only,
+        data_files: Optional[Dict[InstrumentProbeType, str]] = None,
     ) -> bool:
         ...
 
diff --git a/api/src/opentrons/hardware_control/backends/ot3controller.py b/api/src/opentrons/hardware_control/backends/ot3controller.py
index 1b90e086dca..c8a6efb9b0c 100644
--- a/api/src/opentrons/hardware_control/backends/ot3controller.py
+++ b/api/src/opentrons/hardware_control/backends/ot3controller.py
@@ -1430,15 +1430,44 @@ async def capacitive_probe(
         distance_mm: float,
         speed_mm_per_s: float,
         sensor_threshold_pf: float,
-        probe: InstrumentProbeType,
+        probe: InstrumentProbeType = InstrumentProbeType.PRIMARY,
+        output_option: OutputOptions = OutputOptions.sync_only,
+        data_files: Optional[Dict[InstrumentProbeType, str]] = None,
     ) -> bool:
+        if output_option == OutputOptions.sync_buffer_to_csv:
+            assert (
+                self._subsystem_manager.device_info[
+                    SubSystem.of_mount(mount)
+                ].revision.tertiary
+                == "1"
+            )
+        csv_output = bool(output_option.value & OutputOptions.stream_to_csv.value)
+        sync_buffer_output = bool(
+            output_option.value & OutputOptions.sync_buffer_to_csv.value
+        )
+        can_bus_only_output = bool(
+            output_option.value & OutputOptions.can_bus_only.value
+        )
+        data_files_transposed = (
+            None
+            if data_files is None
+            else {
+                sensor_id_for_instrument(probe): data_files[probe]
+                for probe in data_files.keys()
+            }
+        )
         status = await capacitive_probe(
-            self._messenger,
-            sensor_node_for_mount(mount),
-            axis_to_node(moving),
-            distance_mm,
-            speed_mm_per_s,
-            sensor_id_for_instrument(probe),
+            messenger=self._messenger,
+            tool=sensor_node_for_mount(mount),
+            mover=axis_to_node(moving),
+            distance=distance_mm,
+            plunger_speed=speed_mm_per_s,
+            mount_speed=speed_mm_per_s,
+            csv_output=csv_output,
+            sync_buffer_output=sync_buffer_output,
+            can_bus_only_output=can_bus_only_output,
+            data_files=data_files_transposed,
+            sensor_id=sensor_id_for_instrument(probe),
             relative_threshold_pf=sensor_threshold_pf,
         )
 
diff --git a/api/src/opentrons/hardware_control/backends/ot3simulator.py b/api/src/opentrons/hardware_control/backends/ot3simulator.py
index 1e6d9756cf0..c6058820433 100644
--- a/api/src/opentrons/hardware_control/backends/ot3simulator.py
+++ b/api/src/opentrons/hardware_control/backends/ot3simulator.py
@@ -749,7 +749,9 @@ async def capacitive_probe(
         distance_mm: float,
         speed_mm_per_s: float,
         sensor_threshold_pf: float,
-        probe: InstrumentProbeType,
+        probe: InstrumentProbeType = InstrumentProbeType.PRIMARY,
+        output_format: OutputOptions = OutputOptions.sync_only,
+        data_files: Optional[Dict[InstrumentProbeType, str]] = None,
     ) -> bool:
         self._position[moving] += distance_mm
         return True
diff --git a/api/src/opentrons/hardware_control/ot3api.py b/api/src/opentrons/hardware_control/ot3api.py
index c50dc08aebb..aadd1625fad 100644
--- a/api/src/opentrons/hardware_control/ot3api.py
+++ b/api/src/opentrons/hardware_control/ot3api.py
@@ -2660,7 +2660,9 @@ async def capacitive_probe(
             machine_pass_distance,
             pass_settings.speed_mm_per_s,
             pass_settings.sensor_threshold_pf,
-            probe=probe,
+            probe,
+            pass_settings.output_option,
+            pass_settings.data_files,
         )
         end_pos = await self.gantry_position(mount, refresh=True)
         if retract_after:
diff --git a/api/tests/opentrons/config/ot3_settings.py b/api/tests/opentrons/config/ot3_settings.py
index 3cfa9b7c34c..c5a9d778e72 100644
--- a/api/tests/opentrons/config/ot3_settings.py
+++ b/api/tests/opentrons/config/ot3_settings.py
@@ -138,6 +138,8 @@
                 "max_overrun_distance_mm": 2,
                 "speed_mm_per_s": 3,
                 "sensor_threshold_pf": 4,
+                "output_option": OutputOptions.sync_only,
+                "data_files": None,
             },
         },
         "edge_sense": {
@@ -148,6 +150,8 @@
                 "max_overrun_distance_mm": 5,
                 "speed_mm_per_s": 6,
                 "sensor_threshold_pf": 7,
+                "output_option": OutputOptions.sync_only,
+                "data_files": None,
             },
             "search_initial_tolerance_mm": 18,
             "search_iteration_limit": 3,
diff --git a/api/tests/opentrons/hardware_control/test_ot3_api.py b/api/tests/opentrons/hardware_control/test_ot3_api.py
index 7ab0a2f1c00..54065f3cf66 100644
--- a/api/tests/opentrons/hardware_control/test_ot3_api.py
+++ b/api/tests/opentrons/hardware_control/test_ot3_api.py
@@ -107,6 +107,7 @@ def fake_settings() -> CapacitivePassSettings:
         max_overrun_distance_mm=2,
         speed_mm_per_s=4,
         sensor_threshold_pf=1.0,
+        output_option=OutputOptions.sync_only,
     )
 
 
@@ -486,6 +487,8 @@ def _update_position(
             speed_mm_per_s: float,
             threshold_pf: float,
             probe: InstrumentProbeType,
+            output_option: OutputOptions = OutputOptions.sync_only,
+            data_file: Optional[str] = None,
         ) -> None:
             hardware_backend._position[moving] += distance_mm / 2
 
@@ -865,7 +868,14 @@ async def test_capacitive_probe(
     # This is a negative probe because the current position is the home position
     # which is very large.
     mock_backend_capacitive_probe.assert_called_once_with(
-        mount, moving, 3, 4, 1.0, InstrumentProbeType.PRIMARY
+        mount,
+        moving,
+        3,
+        4,
+        1.0,
+        InstrumentProbeType.PRIMARY,
+        fake_settings.output_option,
+        fake_settings.data_files,
     )
 
     original = moving.set_in_point(here, 0)
diff --git a/hardware-testing/hardware_testing/examples/capacitive_probe_ot3.py b/hardware-testing/hardware_testing/examples/capacitive_probe_ot3.py
index 9f775246cb6..241309de41a 100644
--- a/hardware-testing/hardware_testing/examples/capacitive_probe_ot3.py
+++ b/hardware-testing/hardware_testing/examples/capacitive_probe_ot3.py
@@ -2,7 +2,7 @@
 import argparse
 import asyncio
 
-from opentrons.config.types import CapacitivePassSettings
+from opentrons.config.types import CapacitivePassSettings, OutputOptions
 from opentrons.hardware_control.ot3api import OT3API
 
 from hardware_testing.opentrons_api import types
@@ -44,12 +44,14 @@
     max_overrun_distance_mm=3,
     speed_mm_per_s=1,
     sensor_threshold_pf=STABLE_CAP_PF,
+    output_option=OutputOptions.sync_only,
 )
 PROBE_SETTINGS_XY_AXIS = CapacitivePassSettings(
     prep_distance_mm=CUTOUT_SIZE / 2,
     max_overrun_distance_mm=3,
     speed_mm_per_s=1,
     sensor_threshold_pf=STABLE_CAP_PF,
+    output_option=OutputOptions.sync_only,
 )
 
 
diff --git a/hardware-testing/hardware_testing/examples/capacitive_probe_ot3_tunable.py b/hardware-testing/hardware_testing/examples/capacitive_probe_ot3_tunable.py
new file mode 100644
index 00000000000..2b4496e0eb2
--- /dev/null
+++ b/hardware-testing/hardware_testing/examples/capacitive_probe_ot3_tunable.py
@@ -0,0 +1,109 @@
+"""Capacitive probe OT3."""
+import argparse
+import asyncio
+
+from opentrons.config.types import CapacitivePassSettings, OutputOptions
+from opentrons.hardware_control.ot3api import OT3API
+from opentrons.hardware_control.types import InstrumentProbeType
+
+from hardware_testing.opentrons_api import types
+from hardware_testing.opentrons_api import helpers_ot3
+
+# distance added to the pipette shaft
+# when the calibration probe is attached
+PROBE_LENGTH = 34.5
+
+# the capacitive readings need to be stable <0.1
+# before probing anything
+STABLE_CAP_PF = 0.1
+
+# capacitance relative threshold in picofarads
+CAP_REL_THRESHOLD_PF = 10.0
+
+# ideally these values come from either:
+# 1) the API config file
+# 2) or, found through manually jogging
+# The Z is different from the XY probing location
+# because the pipette cannot reach the bottom of the
+# cutout, so we cannot probe the Z inside the cutout
+ASSUMED_Z_LOCATION = types.Point(x=228, y=150, z=80)  # C2 slot center
+ASSUMED_XY_LOCATION = types.Point(x=228, y=150, z=ASSUMED_Z_LOCATION.z)
+
+# configure how the probing motion behaves
+# capacitive_probe will always automatically do the following:
+# 1) move to the "prep" distance away from the assumed location
+# 2) set the capacitive threshold
+#   a) the value is sent over CAN to the pipette's MCU
+#   b) the pipette will trigger the SYNC line when the threshold is reached
+# 3) move along the specified axis, at the specified speed
+#   a) the max distance probed = prep + max_overrun
+# 4) movement will stop when (either/or):
+#   a) the sensor is triggered
+#   b) or, the max distance is reached
+# 5) move to the "prep" distance away from the assumed location
+PROBE_SETTINGS_Z_AXIS = CapacitivePassSettings(
+    prep_distance_mm=10,
+    max_overrun_distance_mm=3,
+    speed_mm_per_s=1,
+    sensor_threshold_pf=CAP_REL_THRESHOLD_PF,
+    output_option=OutputOptions.sync_only,
+)
+PROBE_SETTINGS_Z_AXIS_OUTPUT = CapacitivePassSettings(
+    prep_distance_mm=10,
+    max_overrun_distance_mm=3,
+    speed_mm_per_s=1,
+    sensor_threshold_pf=CAP_REL_THRESHOLD_PF,
+    output_option=OutputOptions.sync_buffer_to_csv,
+    data_files={InstrumentProbeType.PRIMARY: "/data/capacitive_sensor_data.csv"},
+)
+
+
+async def _probe_sequence(api: OT3API, mount: types.OT3Mount, stable: bool) -> float:
+    z_ax = types.Axis.by_mount(mount)
+
+    print("Align the XY axes above Z probe location...")
+    home_pos_z = helpers_ot3.get_endstop_position_ot3(api, mount)[z_ax]
+    await api.move_to(mount, ASSUMED_Z_LOCATION._replace(z=home_pos_z))
+
+    if stable:
+        await helpers_ot3.wait_for_stable_capacitance_ot3(
+            api, mount, threshold_pf=STABLE_CAP_PF, duration=1.0
+        )
+    found_z, _ = await api.capacitive_probe(
+        mount, z_ax, ASSUMED_Z_LOCATION.z, PROBE_SETTINGS_Z_AXIS
+    )
+    print(f"Found deck Z location = {found_z} mm")
+    return found_z
+
+
+async def _main(is_simulating: bool, cycles: int, stable: bool) -> None:
+    api = await helpers_ot3.build_async_ot3_hardware_api(
+        is_simulating=is_simulating, pipette_left="p1000_single_v3.3"
+    )
+    mount = types.OT3Mount.LEFT
+    if not api.hardware_pipettes[mount.to_mount()]:
+        raise RuntimeError("No pipette attached")
+
+    # add length to the pipette, to account for the attached probe
+    await api.add_tip(mount, PROBE_LENGTH)
+
+    await helpers_ot3.home_ot3(api)
+    for c in range(cycles):
+        print(f"Cycle {c + 1}/{cycles}")
+        await _probe_sequence(api, mount, stable)
+
+    # move up, "remove" the probe, then disengage the XY motors when done
+    z_ax = types.Axis.by_mount(mount)
+    top_z = helpers_ot3.get_endstop_position_ot3(api, mount)[z_ax]
+    await api.move_to(mount, ASSUMED_XY_LOCATION._replace(z=top_z))
+    await api.remove_tip(mount)
+    await api.disengage_axes([types.Axis.X, types.Axis.Y])
+
+
+if __name__ == "__main__":
+    parser = argparse.ArgumentParser()
+    parser.add_argument("--simulate", action="store_true")
+    parser.add_argument("--cycles", type=int, default=1)
+    parser.add_argument("--stable", type=bool, default=True)
+    args = parser.parse_args()
+    asyncio.run(_main(args.simulate, args.cycles, args.stable))
diff --git a/hardware-testing/hardware_testing/production_qc/ninety_six_assembly_qc_ot3/test_capacitance.py b/hardware-testing/hardware_testing/production_qc/ninety_six_assembly_qc_ot3/test_capacitance.py
index 3564bc0d364..3a3b7cc128b 100644
--- a/hardware-testing/hardware_testing/production_qc/ninety_six_assembly_qc_ot3/test_capacitance.py
+++ b/hardware-testing/hardware_testing/production_qc/ninety_six_assembly_qc_ot3/test_capacitance.py
@@ -173,7 +173,8 @@ async def _probe(distance: float, speed: float) -> float:
                 NodeId.pipette_left,
                 NodeId.head_l,
                 distance=distance,
-                speed=speed,
+                plunger_speed=speed,
+                mount_speed=speed,
                 sensor_id=sensor_id,
                 relative_threshold_pf=default_probe_cfg.sensor_threshold_pf,
             )
diff --git a/hardware-testing/hardware_testing/production_qc/robot_assembly_qc_ot3/test_instruments.py b/hardware-testing/hardware_testing/production_qc/robot_assembly_qc_ot3/test_instruments.py
index 65d4618ff74..3301c1d7ab0 100644
--- a/hardware-testing/hardware_testing/production_qc/robot_assembly_qc_ot3/test_instruments.py
+++ b/hardware-testing/hardware_testing/production_qc/robot_assembly_qc_ot3/test_instruments.py
@@ -1,7 +1,7 @@
 """Test Instruments."""
 from typing import List, Tuple, Optional, Union
 
-from opentrons.config.types import CapacitivePassSettings
+from opentrons.config.types import CapacitivePassSettings, OutputOptions
 from opentrons.hardware_control.ot3api import OT3API
 
 from hardware_testing.data.csv_report import (
@@ -30,6 +30,7 @@
     max_overrun_distance_mm=0,
     speed_mm_per_s=Z_PROBE_DISTANCE_MM / Z_PROBE_TIME_SECONDS,
     sensor_threshold_pf=1.0,
+    output_option=OutputOptions.can_bus_only,
 )
 
 RELATIVE_MOVE_FROM_HOME_DELTA = Point(x=-500, y=-300)
diff --git a/hardware-testing/hardware_testing/scripts/gripper_ot3.py b/hardware-testing/hardware_testing/scripts/gripper_ot3.py
index de2578c9ff8..6c64d84105d 100644
--- a/hardware-testing/hardware_testing/scripts/gripper_ot3.py
+++ b/hardware-testing/hardware_testing/scripts/gripper_ot3.py
@@ -4,7 +4,7 @@
 from dataclasses import dataclass
 from typing import Optional, List, Any, Dict
 
-from opentrons.config.defaults_ot3 import CapacitivePassSettings
+from opentrons.config.defaults_ot3 import CapacitivePassSettings, OutputOptions
 from opentrons.hardware_control.ot3api import OT3API
 
 from hardware_testing.opentrons_api import types
@@ -73,6 +73,7 @@
     max_overrun_distance_mm=1,
     speed_mm_per_s=1,
     sensor_threshold_pf=0.5,
+    output_option=OutputOptions.sync_only,
 )
 LABWARE_PROBE_CORNER_TOP_LEFT_XY = {
     "plate": Point(x=5, y=-5),
diff --git a/hardware/opentrons_hardware/firmware_bindings/constants.py b/hardware/opentrons_hardware/firmware_bindings/constants.py
index cd91ced91b7..f569b0d8ff4 100644
--- a/hardware/opentrons_hardware/firmware_bindings/constants.py
+++ b/hardware/opentrons_hardware/firmware_bindings/constants.py
@@ -253,7 +253,7 @@ class MessageId(int, Enum):
     peripheral_status_request = 0x8C
     peripheral_status_response = 0x8D
     baseline_sensor_response = 0x8E
-    send_accumulated_pressure_data = 0x8F
+    send_accumulated_sensor_data = 0x8F
 
     set_hepa_fan_state_request = 0x90
     get_hepa_fan_state_request = 0x91
diff --git a/hardware/opentrons_hardware/firmware_bindings/messages/message_definitions.py b/hardware/opentrons_hardware/firmware_bindings/messages/message_definitions.py
index 3164d147fde..82ba3040928 100644
--- a/hardware/opentrons_hardware/firmware_bindings/messages/message_definitions.py
+++ b/hardware/opentrons_hardware/firmware_bindings/messages/message_definitions.py
@@ -1024,13 +1024,13 @@ class GetHepaUVStateResponse(BaseMessage):
 
 
 @dataclass
-class SendAccumulatedPressureDataRequest(BaseMessage):
+class SendAccumulatedSensorDataRequest(BaseMessage):
     """Send all the saved sensor data."""
 
-    payload: payloads.SendAccumulatedPressureDataPayload
+    payload: payloads.SendAccumulatedSensorDataPayload
     payload_type: Type[
-        payloads.SendAccumulatedPressureDataPayload
-    ] = payloads.SendAccumulatedPressureDataPayload
+        payloads.SendAccumulatedSensorDataPayload
+    ] = payloads.SendAccumulatedSensorDataPayload
     message_id: Literal[
-        MessageId.send_accumulated_pressure_data
-    ] = MessageId.send_accumulated_pressure_data
+        MessageId.send_accumulated_sensor_data
+    ] = MessageId.send_accumulated_sensor_data
diff --git a/hardware/opentrons_hardware/firmware_bindings/messages/messages.py b/hardware/opentrons_hardware/firmware_bindings/messages/messages.py
index 9906aa8dc07..772bb6c7e86 100644
--- a/hardware/opentrons_hardware/firmware_bindings/messages/messages.py
+++ b/hardware/opentrons_hardware/firmware_bindings/messages/messages.py
@@ -109,9 +109,8 @@
     defs.SetHepaUVStateRequest,
     defs.GetHepaUVStateRequest,
     defs.GetHepaUVStateResponse,
-    defs.SendAccumulatedPressureDataRequest,
+    defs.SendAccumulatedSensorDataRequest,
     defs.AddSensorLinearMoveRequest,
-    defs.SendAccumulatedPressureDataRequest,
 ]
 
 
diff --git a/hardware/opentrons_hardware/firmware_bindings/messages/payloads.py b/hardware/opentrons_hardware/firmware_bindings/messages/payloads.py
index c351495ba5b..49845c8820d 100644
--- a/hardware/opentrons_hardware/firmware_bindings/messages/payloads.py
+++ b/hardware/opentrons_hardware/firmware_bindings/messages/payloads.py
@@ -493,6 +493,7 @@ class AddSensorLinearMoveBasePayload(AddLinearMoveRequestPayload):
     """A request to add a linear move that also requires sensor reading for its duration."""
 
     sensor_id: SensorIdField
+    sensor_type: SensorTypeField
 
 
 @dataclass(eq=False)
@@ -687,7 +688,8 @@ class GetHepaUVStatePayloadResponse(EmptyPayload):
 
 
 @dataclass(eq=False)
-class SendAccumulatedPressureDataPayload(EmptyPayload):
+class SendAccumulatedSensorDataPayload(EmptyPayload):
     """Send queued readings from a sensor."""
 
     sensor_id: SensorIdField
+    sensor_type: SensorTypeField
diff --git a/hardware/opentrons_hardware/hardware_control/motion.py b/hardware/opentrons_hardware/hardware_control/motion.py
index 4b482cf01a3..c355093e18a 100644
--- a/hardware/opentrons_hardware/hardware_control/motion.py
+++ b/hardware/opentrons_hardware/hardware_control/motion.py
@@ -8,6 +8,7 @@
     NodeId,
     PipetteTipActionType,
     MoveStopCondition as MoveStopCondition,
+    SensorType,
     SensorId,
 )
 
@@ -53,6 +54,7 @@ class MoveGroupSingleAxisStep:
     acceleration_mm_sec_sq: np.float64 = np.float64(0)
     stop_condition: MoveStopCondition = MoveStopCondition.none
     move_type: MoveType = MoveType.linear
+    sensor_type: Optional[SensorType] = None
     sensor_id: Optional[SensorId] = None
 
     def is_moving_step(self) -> bool:
@@ -133,7 +135,8 @@ def create_step(
     duration: np.float64,
     present_nodes: Iterable[NodeId],
     stop_condition: MoveStopCondition = MoveStopCondition.none,
-    sensor_to_use: Optional[SensorId] = None,
+    sensor_type_pass: Optional[SensorType] = None,
+    sensor_id_pass: Optional[SensorId] = None,
 ) -> MoveGroupStep:
     """Create a move from a block.
 
@@ -160,7 +163,8 @@ def create_step(
             duration_sec=duration,
             stop_condition=stop_condition,
             move_type=MoveType.get_move_type(stop_condition),
-            sensor_id=sensor_to_use,
+            sensor_type=sensor_type_pass,
+            sensor_id=sensor_id_pass,
         )
     return step
 
diff --git a/hardware/opentrons_hardware/hardware_control/move_group_runner.py b/hardware/opentrons_hardware/hardware_control/move_group_runner.py
index 4b7f409b38b..d68f4573cf1 100644
--- a/hardware/opentrons_hardware/hardware_control/move_group_runner.py
+++ b/hardware/opentrons_hardware/hardware_control/move_group_runner.py
@@ -75,6 +75,7 @@
     PipetteTipActionTypeField,
     MoveStopConditionField,
     SensorIdField,
+    SensorTypeField,
 )
 from opentrons_hardware.hardware_control.motion import MoveStopCondition
 from opentrons_hardware.hardware_control.motor_position_status import (
@@ -307,6 +308,7 @@ def _get_stepper_motor_message(
             return HomeRequest(payload=home_payload)
         elif step.move_type == MoveType.sensor:
             # stop_condition = step.stop_condition.value
+            assert step.sensor_type is not None
             assert step.sensor_id is not None
             stop_condition = MoveStopCondition.sync_line
             sensor_move_payload = AddSensorLinearMoveBasePayload(
@@ -328,6 +330,7 @@ def _get_stepper_motor_message(
                 velocity_mm=Int32Field(
                     int((step.velocity_mm_sec / interrupts_per_sec) * (2**31))
                 ),
+                sensor_type=SensorTypeField(step.sensor_type),
                 sensor_id=SensorIdField(step.sensor_id),
             )
             return AddSensorLinearMoveRequest(payload=sensor_move_payload)
diff --git a/hardware/opentrons_hardware/hardware_control/tool_sensors.py b/hardware/opentrons_hardware/hardware_control/tool_sensors.py
index 0676a29967a..6a3d77ee8e5 100644
--- a/hardware/opentrons_hardware/hardware_control/tool_sensors.py
+++ b/hardware/opentrons_hardware/hardware_control/tool_sensors.py
@@ -16,18 +16,16 @@
 from math import copysign
 from typing_extensions import Literal
 
-from opentrons_shared_data.errors.exceptions import CanbusCommunicationError
-
 from opentrons_hardware.firmware_bindings.constants import (
     NodeId,
     SensorId,
     SensorType,
-    SensorThresholdMode,
     SensorOutputBinding,
     ErrorCode,
+    SensorThresholdMode,
 )
 from opentrons_hardware.firmware_bindings.messages.payloads import (
-    SendAccumulatedPressureDataPayload,
+    SendAccumulatedSensorDataPayload,
     BindSensorOutputRequestPayload,
 )
 from opentrons_hardware.firmware_bindings.messages.fields import (
@@ -37,16 +35,18 @@
 )
 from opentrons_hardware.firmware_bindings.messages.message_definitions import (
     BindSensorOutputRequest,
-    SendAccumulatedPressureDataRequest,
+    SendAccumulatedSensorDataRequest,
 )
 from opentrons_hardware.sensors.sensor_driver import SensorDriver, LogListener
 from opentrons_hardware.sensors.types import (
-    SensorDataType,
     sensor_fixed_point_conversion,
 )
-from opentrons_hardware.sensors.sensor_types import SensorInformation, PressureSensor
+from opentrons_hardware.sensors.sensor_types import (
+    SensorInformation,
+    PressureSensor,
+    CapacitiveSensor,
+)
 from opentrons_hardware.sensors.scheduler import SensorScheduler
-from opentrons_hardware.sensors.utils import SensorThresholdInformation
 from opentrons_hardware.drivers.can_bus.can_messenger import CanMessenger
 from opentrons_hardware.hardware_control.motion import (
     MoveStopCondition,
@@ -59,6 +59,9 @@
 LOG = getLogger(__name__)
 PipetteProbeTarget = Literal[NodeId.pipette_left, NodeId.pipette_right]
 InstrumentProbeTarget = Union[PipetteProbeTarget, Literal[NodeId.gripper]]
+ProbeSensorDict = Union[
+    Dict[SensorId, PressureSensor], Dict[SensorId, CapacitiveSensor]
+]
 
 pressure_output_file_heading = [
     "time(s)",
@@ -68,6 +71,14 @@
     "threshold(pascals)",
 ]
 
+capacitive_output_file_heading = [
+    "time(s)",
+    "Capacitance(farads)",
+    "z_velocity(mm/s)",
+    "plunger_velocity(mm/s)",
+    "threshold(farads)",
+]
+
 # FIXME we should organize all of these functions to use the sensor drivers.
 # FIXME we should restrict some of these functions by instrument type.
 
@@ -77,27 +88,45 @@ def _fix_pass_step_for_buffer(
     movers: List[NodeId],
     distance: Dict[NodeId, float],
     speed: Dict[NodeId, float],
+    sensor_type: SensorType,
+    sensor_id: SensorId,
     stop_condition: MoveStopCondition = MoveStopCondition.sync_line,
-    sensor_to_use: Optional[SensorId] = None,
 ) -> MoveGroupStep:
-    pipette_nodes = [
-        i for i in movers if i in [NodeId.pipette_left, NodeId.pipette_right]
+    tool_nodes = [
+        i
+        for i in movers
+        if i in [NodeId.pipette_left, NodeId.pipette_right, NodeId.gripper]
     ]
-    pipette_move = create_step(
-        distance={ax: float64(abs(distance[ax])) for ax in movers},
-        velocity={
-            ax: float64(speed[ax] * copysign(1.0, distance[ax])) for ax in movers
-        },
-        acceleration={},
-        # use any node present to calculate duration of the move, assuming the durations
-        #   will be the same
-        duration=float64(abs(distance[movers[0]] / speed[movers[0]])),
-        present_nodes=pipette_nodes,
-        stop_condition=MoveStopCondition.sensor_report,
-        sensor_to_use=sensor_to_use,
-    )
-    for node in pipette_nodes:
-        move_group[node] = pipette_move[node]
+    if sensor_type == SensorType.pressure:
+        tool_move = create_step(
+            distance={ax: float64(abs(distance[ax])) for ax in movers},
+            velocity={
+                ax: float64(speed[ax] * copysign(1.0, distance[ax])) for ax in movers
+            },
+            acceleration={},
+            # use any node present to calculate duration of the move, assuming the durations
+            #   will be the same
+            duration=float64(abs(distance[movers[0]] / speed[movers[0]])),
+            present_nodes=tool_nodes,
+            stop_condition=MoveStopCondition.sensor_report,
+            sensor_type_pass=sensor_type,
+            sensor_id_pass=sensor_id,
+        )
+    elif sensor_type == SensorType.capacitive:
+        tool_move = create_step(
+            distance={},
+            velocity={},
+            acceleration={},
+            # use any node present to calculate duration of the move, assuming the durations
+            #   will be the same
+            duration=float64(abs(distance[movers[0]] / speed[movers[0]])),
+            present_nodes=tool_nodes,
+            stop_condition=MoveStopCondition.sensor_report,
+            sensor_type_pass=sensor_type,
+            sensor_id_pass=sensor_id,
+        )
+    for node in tool_nodes:
+        move_group[node] = tool_move[node]
     return move_group
 
 
@@ -105,8 +134,9 @@ def _build_pass_step(
     movers: List[NodeId],
     distance: Dict[NodeId, float],
     speed: Dict[NodeId, float],
+    sensor_type: SensorType,
+    sensor_id: SensorId,
     stop_condition: MoveStopCondition = MoveStopCondition.sync_line,
-    sensor_to_use: Optional[SensorId] = None,
 ) -> MoveGroupStep:
     move_group = create_step(
         distance={ax: float64(abs(distance[ax])) for ax in movers},
@@ -119,38 +149,42 @@ def _build_pass_step(
         duration=float64(abs(distance[movers[0]] / speed[movers[0]])),
         present_nodes=movers,
         stop_condition=stop_condition,
+        sensor_type_pass=sensor_type,
+        sensor_id_pass=sensor_id,
     )
     return move_group
 
 
 async def run_sync_buffer_to_csv(
     messenger: CanMessenger,
-    sensor_driver: SensorDriver,
     mount_speed: float,
     plunger_speed: float,
-    threshold_pascals: float,
+    threshold: float,
     head_node: NodeId,
     move_group: MoveGroupRunner,
     log_files: Dict[SensorId, str],
-    tool: PipetteProbeTarget,
+    tool: InstrumentProbeTarget,
+    sensor_type: SensorType,
+    output_file_heading: list[str],
 ) -> Dict[NodeId, MotorPositionStatus]:
     """Runs the sensor pass move group and creates a csv file with the results."""
-    sensor_metadata = [0, 0, mount_speed, plunger_speed, threshold_pascals]
+    sensor_metadata = [0, 0, mount_speed, plunger_speed, threshold]
     positions = await move_group.run(can_messenger=messenger)
     for sensor_id in log_files.keys():
         sensor_capturer = LogListener(
             mount=head_node,
             data_file=log_files[sensor_id],
-            file_heading=pressure_output_file_heading,
+            file_heading=output_file_heading,
             sensor_metadata=sensor_metadata,
         )
         async with sensor_capturer:
             messenger.add_listener(sensor_capturer, None)
             await messenger.send(
                 node_id=tool,
-                message=SendAccumulatedPressureDataRequest(
-                    payload=SendAccumulatedPressureDataPayload(
-                        sensor_id=SensorIdField(sensor_id)
+                message=SendAccumulatedSensorDataRequest(
+                    payload=SendAccumulatedSensorDataPayload(
+                        sensor_id=SensorIdField(sensor_id),
+                        sensor_type=SensorTypeField(sensor_type),
                     )
                 ),
             )
@@ -160,7 +194,7 @@ async def run_sync_buffer_to_csv(
             node_id=tool,
             message=BindSensorOutputRequest(
                 payload=BindSensorOutputRequestPayload(
-                    sensor=SensorTypeField(SensorType.pressure),
+                    sensor=SensorTypeField(sensor_type),
                     sensor_id=SensorIdField(sensor_id),
                     binding=SensorOutputBindingField(SensorOutputBinding.none),
                 )
@@ -171,29 +205,29 @@ async def run_sync_buffer_to_csv(
 
 async def run_stream_output_to_csv(
     messenger: CanMessenger,
-    sensor_driver: SensorDriver,
-    pressure_sensors: Dict[SensorId, PressureSensor],
+    sensors: ProbeSensorDict,
     mount_speed: float,
     plunger_speed: float,
-    threshold_pascals: float,
+    threshold: float,
     head_node: NodeId,
     move_group: MoveGroupRunner,
     log_files: Dict[SensorId, str],
+    output_file_heading: list[str],
 ) -> Dict[NodeId, MotorPositionStatus]:
     """Runs the sensor pass move group and creates a csv file with the results."""
-    sensor_metadata = [0, 0, mount_speed, plunger_speed, threshold_pascals]
+    sensor_metadata = [0, 0, mount_speed, plunger_speed, threshold]
     sensor_capturer = LogListener(
         mount=head_node,
         data_file=log_files[
             next(iter(log_files))
         ],  # hardcode to the first file, need to think more on this
-        file_heading=pressure_output_file_heading,
+        file_heading=output_file_heading,
         sensor_metadata=sensor_metadata,
     )
     binding = [SensorOutputBinding.sync, SensorOutputBinding.report]
     binding_field = SensorOutputBindingField.from_flags(binding)
-    for sensor_id in pressure_sensors.keys():
-        sensor_info = pressure_sensors[sensor_id].sensor
+    for sensor_id in sensors.keys():
+        sensor_info = sensors[sensor_id].sensor
         await messenger.send(
             node_id=sensor_info.node_id,
             message=BindSensorOutputRequest(
@@ -210,8 +244,8 @@ async def run_stream_output_to_csv(
         positions = await move_group.run(can_messenger=messenger)
     messenger.remove_listener(sensor_capturer)
 
-    for sensor_id in pressure_sensors.keys():
-        sensor_info = pressure_sensors[sensor_id].sensor
+    for sensor_id in sensors.keys():
+        sensor_info = sensors[sensor_id].sensor
         await messenger.send(
             node_id=sensor_info.node_id,
             message=BindSensorOutputRequest(
@@ -260,15 +294,46 @@ async def _setup_pressure_sensors(
     return result
 
 
+async def _setup_capacitive_sensors(
+    messenger: CanMessenger,
+    sensor_id: SensorId,
+    tool: InstrumentProbeTarget,
+    relative_threshold_pf: float,
+    sensor_driver: SensorDriver,
+) -> Dict[SensorId, CapacitiveSensor]:
+    sensors: List[SensorId] = []
+    result: Dict[SensorId, CapacitiveSensor] = {}
+    if sensor_id == SensorId.BOTH:
+        sensors.append(SensorId.S0)
+        sensors.append(SensorId.S1)
+    else:
+        sensors.append(sensor_id)
+
+    for sensor in sensors:
+        capacitive_sensor = CapacitiveSensor.build(
+            sensor_id=sensor,
+            node_id=tool,
+            stop_threshold=relative_threshold_pf,
+        )
+        threshold = await sensor_driver.send_stop_threshold(
+            messenger, capacitive_sensor, SensorThresholdMode.auto_baseline
+        )
+        LOG.info(
+            f"starting capacitive probe with threshold {threshold.to_float() if threshold is not None else None}"
+        )
+        result[sensor] = capacitive_sensor
+    return result
+
+
 async def _run_with_binding(
     messenger: CanMessenger,
-    pressure_sensors: Dict[SensorId, PressureSensor],
+    sensors: ProbeSensorDict,
     sensor_runner: MoveGroupRunner,
     binding: List[SensorOutputBinding],
 ) -> Dict[NodeId, MotorPositionStatus]:
     binding_field = SensorOutputBindingField.from_flags(binding)
-    for sensor_id in pressure_sensors.keys():
-        sensor_info = pressure_sensors[sensor_id].sensor
+    for sensor_id in sensors.keys():
+        sensor_info = sensors[sensor_id].sensor
         await messenger.send(
             node_id=sensor_info.node_id,
             message=BindSensorOutputRequest(
@@ -281,8 +346,8 @@ async def _run_with_binding(
         )
 
     result = await sensor_runner.run(can_messenger=messenger)
-    for sensor_id in pressure_sensors.keys():
-        sensor_info = pressure_sensors[sensor_id].sensor
+    for sensor_id in sensors.keys():
+        sensor_info = sensors[sensor_id].sensor
         await messenger.send(
             node_id=sensor_info.node_id,
             message=BindSensorOutputRequest(
@@ -330,8 +395,9 @@ async def liquid_probe(
         movers=[head_node, tool],
         distance={head_node: max_z_distance, tool: max_z_distance},
         speed={head_node: mount_speed, tool: plunger_speed},
+        sensor_type=SensorType.pressure,
+        sensor_id=sensor_id,
         stop_condition=MoveStopCondition.sync_line,
-        sensor_to_use=sensor_id,
     )
     if sync_buffer_output:
         sensor_group = _fix_pass_step_for_buffer(
@@ -339,15 +405,15 @@ async def liquid_probe(
             movers=[head_node, tool],
             distance={head_node: max_z_distance, tool: max_z_distance},
             speed={head_node: mount_speed, tool: plunger_speed},
+            sensor_type=SensorType.pressure,
+            sensor_id=sensor_id,
             stop_condition=MoveStopCondition.sync_line,
-            sensor_to_use=sensor_id,
         )
 
     sensor_runner = MoveGroupRunner(move_groups=[[sensor_group]])
     if csv_output:
         return await run_stream_output_to_csv(
             messenger,
-            sensor_driver,
             pressure_sensors,
             mount_speed,
             plunger_speed,
@@ -355,18 +421,20 @@ async def liquid_probe(
             head_node,
             sensor_runner,
             log_files,
+            pressure_output_file_heading,
         )
     elif sync_buffer_output:
         return await run_sync_buffer_to_csv(
             messenger,
-            sensor_driver,
             mount_speed,
             plunger_speed,
             threshold_pascals,
             head_node,
             sensor_runner,
             log_files,
-            tool,
+            tool=tool,
+            sensor_type=SensorType.pressure,
+            output_file_heading=pressure_output_file_heading,
         )
     elif can_bus_only_output:
         binding = [SensorOutputBinding.sync, SensorOutputBinding.report]
@@ -404,10 +472,14 @@ async def capacitive_probe(
     tool: InstrumentProbeTarget,
     mover: NodeId,
     distance: float,
-    speed: float,
+    plunger_speed: float,
+    mount_speed: float,
     sensor_id: SensorId = SensorId.S0,
     relative_threshold_pf: float = 1.0,
-    log_sensor_values: bool = False,
+    csv_output: bool = False,
+    sync_buffer_output: bool = False,
+    can_bus_only_output: bool = False,
+    data_files: Optional[Dict[SensorId, str]] = None,
 ) -> MotorPositionStatus:
     """Move the specified tool down until its capacitive sensor triggers.
 
@@ -417,35 +489,72 @@ async def capacitive_probe(
     The direction is sgn(distance)*sgn(speed), so you can set the direction
     either by negating speed or negating distance.
     """
-    sensor_scheduler = SensorScheduler()
-    sensor_info = SensorInformation(SensorType.capacitive, sensor_id, tool)
-    threshold = await sensor_scheduler.send_threshold(
-        SensorThresholdInformation(
-            sensor=sensor_info,
-            data=SensorDataType.build(relative_threshold_pf, SensorType.capacitive),
-            mode=SensorThresholdMode.auto_baseline,
-        ),
+    log_files: Dict[SensorId, str] = {} if not data_files else data_files
+    sensor_driver = SensorDriver()
+    capacitive_sensors = await _setup_capacitive_sensors(
         messenger,
+        sensor_id,
+        tool,
+        relative_threshold_pf,
+        sensor_driver,
     )
-    if not threshold:
-        raise CanbusCommunicationError(
-            message="Could not set threshold for probe",
-            detail={
-                "tool": tool.name,
-                "sensor": sensor_id.name,
-                "threshold": str(relative_threshold_pf),
-            },
+
+    sensor_group = _build_pass_step(
+        movers=[mover, tool],
+        distance={mover: distance, tool: 0.0},
+        speed={mover: mount_speed, tool: 0.0},
+        sensor_type=SensorType.capacitive,
+        sensor_id=sensor_id,
+        stop_condition=MoveStopCondition.sync_line,
+    )
+    if sync_buffer_output:
+        sensor_group = _fix_pass_step_for_buffer(
+            sensor_group,
+            movers=[mover, tool],
+            distance={mover: distance, tool: distance},
+            speed={mover: mount_speed, tool: plunger_speed},
+            sensor_type=SensorType.capacitive,
+            sensor_id=sensor_id,
+            stop_condition=MoveStopCondition.sync_line,
         )
-    LOG.info(f"starting capacitive probe with threshold {threshold.to_float()}")
-    pass_group = _build_pass_step([mover], {mover: distance}, {mover: speed})
-    runner = MoveGroupRunner(move_groups=[[pass_group]])
-    async with sensor_scheduler.bind_sync(
-        sensor_info,
-        messenger,
-        do_log=log_sensor_values,
-    ):
-        position = await runner.run(can_messenger=messenger)
-        return position[mover]
+
+    runner = MoveGroupRunner(move_groups=[[sensor_group]])
+    if csv_output:
+        positions = await run_stream_output_to_csv(
+            messenger,
+            capacitive_sensors,
+            mount_speed,
+            0.0,
+            relative_threshold_pf,
+            mover,
+            runner,
+            log_files,
+            capacitive_output_file_heading,
+        )
+    elif sync_buffer_output:
+        positions = await run_sync_buffer_to_csv(
+            messenger,
+            mount_speed,
+            0.0,
+            relative_threshold_pf,
+            mover,
+            runner,
+            log_files,
+            tool=tool,
+            sensor_type=SensorType.capacitive,
+            output_file_heading=capacitive_output_file_heading,
+        )
+    elif can_bus_only_output:
+        binding = [SensorOutputBinding.sync, SensorOutputBinding.report]
+        positions = await _run_with_binding(
+            messenger, capacitive_sensors, runner, binding
+        )
+    else:
+        binding = [SensorOutputBinding.sync]
+        positions = await _run_with_binding(
+            messenger, capacitive_sensors, runner, binding
+        )
+    return positions[mover]
 
 
 async def capacitive_pass(
@@ -463,8 +572,16 @@ async def capacitive_pass(
         sensor_id=sensor_id,
         node_id=tool,
     )
-    pass_group = _build_pass_step([mover], {mover: distance}, {mover: speed})
-    runner = MoveGroupRunner(move_groups=[[pass_group]])
+
+    sensor_group = _build_pass_step(
+        movers=[mover],
+        distance={mover: distance},
+        speed={mover: speed},
+        sensor_type=SensorType.capacitive,
+        sensor_id=sensor_id,
+    )
+
+    runner = MoveGroupRunner(move_groups=[[sensor_group]])
     await runner.prep(messenger)
     async with sensor_scheduler.capture_output(sensor_info, messenger) as output_queue:
         await runner.execute(messenger)
diff --git a/hardware/opentrons_hardware/sensors/sensor_driver.py b/hardware/opentrons_hardware/sensors/sensor_driver.py
index 189560aecf8..ac34dde2afe 100644
--- a/hardware/opentrons_hardware/sensors/sensor_driver.py
+++ b/hardware/opentrons_hardware/sensors/sensor_driver.py
@@ -127,13 +127,14 @@ async def send_stop_threshold(
         self,
         can_messenger: CanMessenger,
         sensor: ThresholdSensorType,
+        mode: SensorThresholdMode = SensorThresholdMode.absolute,
         timeout: int = 1,
-    ) -> Optional[SensorReturnType]:
+    ) -> Optional[SensorDataType]:
         """Send threshold for stopping a move."""
         write = SensorThresholdInformation(
             sensor.sensor,
             SensorDataType.build(sensor.stop_threshold, sensor.sensor.sensor_type),
-            SensorThresholdMode.absolute,
+            mode,
         )
         threshold_data = await self._scheduler.send_threshold(write, can_messenger)
         if not threshold_data:
@@ -146,7 +147,7 @@ async def send_zero_threshold(
         can_messenger: CanMessenger,
         sensor: ThresholdSensorType,
         timeout: int = 1,
-    ) -> Optional[SensorReturnType]:
+    ) -> Optional[SensorDataType]:
         """Send the zero threshold which the offset value is compared to."""
         write = SensorThresholdInformation(
             sensor.sensor,
diff --git a/hardware/tests/opentrons_hardware/hardware_control/test_tool_sensors.py b/hardware/tests/opentrons_hardware/hardware_control/test_tool_sensors.py
index c88de67f089..0b6a1ff8967 100644
--- a/hardware/tests/opentrons_hardware/hardware_control/test_tool_sensors.py
+++ b/hardware/tests/opentrons_hardware/hardware_control/test_tool_sensors.py
@@ -1,6 +1,6 @@
 """Test the tool-sensor coordination code."""
 import logging
-from mock import patch, ANY, AsyncMock, call
+from mock import patch, AsyncMock, call
 import os
 import pytest
 from contextlib import asynccontextmanager
@@ -315,7 +315,6 @@ async def test_capacitive_probe(
     mock_messenger: AsyncMock,
     message_send_loopback: CanLoopback,
     mock_sensor_threshold: AsyncMock,
-    mock_bind_sync: AsyncMock,
     target_node: InstrumentProbeTarget,
     motor_node: NodeId,
     caplog: Any,
@@ -355,6 +354,25 @@ def move_responder(
                     ),
                     motor_node,
                 ),
+                (
+                    NodeId.host,
+                    Acknowledgement(payload=ack_payload),
+                    target_node,
+                ),
+                (
+                    NodeId.host,
+                    MoveCompleted(
+                        payload=MoveCompletedPayload(
+                            group_id=UInt8Field(0),
+                            seq_id=UInt8Field(0),
+                            current_position_um=UInt32Field(10000),
+                            encoder_position_um=Int32Field(10000),
+                            position_flags=MotorPositionFlagsField(0),
+                            ack_id=UInt8Field(1),
+                        )
+                    ),
+                    target_node,
+                ),
             ]
         else:
             return []
@@ -362,7 +380,7 @@ def move_responder(
     message_send_loopback.add_responder(move_responder)
 
     status = await capacitive_probe(
-        mock_messenger, target_node, motor_node, distance, speed
+        mock_messenger, target_node, motor_node, distance, speed, speed
     )
     assert status.motor_position == 10  # this comes from the current_position_um above
     assert status.encoder_position == 10
@@ -372,13 +390,6 @@ def move_responder(
         data=SensorDataType.build(1.0, sensor_info.sensor_type),
         mode=SensorThresholdMode.auto_baseline,
     )
-    # this mock assert is annoying because, see below
-    mock_bind_sync.assert_called_once_with(
-        ANY,  # this is a mock of a function on a class not a method so this is self
-        sensor_info,
-        ANY,
-        do_log=ANY,
-    )
 
 
 @pytest.mark.parametrize(