To solve this optimization problem, we need to define the decision variables, the objective function, and the constraints. 

Let's denote:
- $x$ as the amount of maple syrup produced (in kg),
- $y$ as the amount of maple candy produced (in kg).

The objective is to maximize profit. Given that the profit per kg of maple syrup is $20 and the profit per kg of maple candy is $15, the objective function can be written as:
\[ \text{Maximize} \quad 20x + 15y \]

Now, let's define the constraints based on the given information:
1. The farm can make at most 10 kg of maple syrup: \( x \leq 10 \)
2. The farm can make at most 12 kg of maple candy: \( y \leq 12 \)
3. The farm must supply at least 3 kg of maple syrup: \( x \geq 3 \)
4. The farm must supply at least 5 kg of maple candy: \( y \geq 5 \)
5. Each kg of maple syrup and maple candy requires 2 hours at the boiling station, and the boiling station is available for at most 20 hours per day: \( 2x + 2y \leq 20 \)

Given these constraints and the objective function, we can now write the Gurobi code to solve this linear programming problem.

```python
from gurobipy import *

# Create a new model
m = Model("Maple_Farm_Optimization")

# Define the decision variables
x = m.addVar(lb=3, ub=10, name="maple_syrup")  # Amount of maple syrup (kg)
y = m.addVar(lb=5, ub=12, name="maple_candy")  # Amount of maple candy (kg)

# Define the objective function
m.setObjective(20*x + 15*y, GRB.MAXIMIZE)

# Define the constraints
m.addConstr(2*x + 2*y <= 20, name="boiling_station_time")

# Optimize the model
m.optimize()

# Print the results
if m.status == GRB.OPTIMAL:
    print("Optimal solution found:")
    print(f"Maple Syrup: {x.x} kg")
    print(f"Maple Candy: {y.x} kg")
    print(f"Maximum Profit: ${m.objVal}")
else:
    print("No optimal solution found")

```