yeah, the devil is in the details...
the problem with this is that calculations are done on a line item basis, so since you have product options it is causing the calculation to trigger on each option, and not the ID.
the work around would be to create a separate shipping rule for each product.
so for widget A which has a product of of 1, create a shipping rule using:
trigger:
"Presence of item in cart"
If item ID "1" "exists" in the cart
calculation:
"Flat Rate"
(ceil($this->GetInfo("1", "Quantity") / 5)) * $this->GetInfo("1", "shipRate")
and for widget 2 which has an ID of 2, create another shipping rule as:
trigger:
"Presence of item in cart"
If item ID "21" "exists" in the cart
calcualtion:
"Flat Rate"
(ceil($this->GetInfo("2", "Quantity") / 5)) * $this->GetInfo("2", "shipRate")
for additional widgets, you would need to create additional shipping rules using the appropriate ID value.