```json
{
  "sym_variables": [
    ("x0", "cans of coffee"),
    ("x1", "rubber bands"),
    ("x2", "headsets")
  ],
  "objective_function": "9*x0 + 8*x1 + 6*x2",
  "constraints": [
    "17*x0 + 16*x1 >= 52",
    "16*x1 + 13*x2 >= 30",
    "17*x0 + 16*x1 + 13*x2 >= 40",
    "6*x0 - 2*x2 >= 0",
    "16*x1 + 13*x2 <= 157",
    "17*x0 + 16*x1 + 13*x2 <= 161",
    "x0, x1, x2 are integers"
  ]
}
```

```python
import gurobipy as gp

# Create a new model
model = gp.Model("optimization_problem")

# Create variables
cans_of_coffee = model.addVar(vtype=gp.GRB.INTEGER, name="cans_of_coffee")
rubber_bands = model.addVar(vtype=gp.GRB.INTEGER, name="rubber_bands")
headsets = model.addVar(vtype=gp.GRB.INTEGER, name="headsets")


# Set objective function
model.setObjective(9 * cans_of_coffee + 8 * rubber_bands + 6 * headsets, gp.GRB.MINIMIZE)

# Add constraints
model.addConstr(17 * cans_of_coffee + 16 * rubber_bands >= 52, "c1")
model.addConstr(16 * rubber_bands + 13 * headsets >= 30, "c2")
model.addConstr(17 * cans_of_coffee + 16 * rubber_bands + 13 * headsets >= 40, "c3")
model.addConstr(6 * cans_of_coffee - 2 * headsets >= 0, "c4")
model.addConstr(16 * rubber_bands + 13 * headsets <= 157, "c5")

# Add upper bound constraint on total usefulness
model.addConstr(17 * cans_of_coffee + 16 * rubber_bands + 13 * headsets <= 161, "c6")


# Optimize model
model.optimize()

# Check for infeasibility
if model.status == gp.GRB.INFEASIBLE:
    print("The model is infeasible.")
else:
    # Print optimal solution
    print("Optimal solution:")
    print(f"Cans of coffee: {cans_of_coffee.x}")
    print(f"Rubber bands: {rubber_bands.x}")
    print(f"Headsets: {headsets.x}")
    print(f"Objective value: {model.objVal}")

```
