Class InsertionService

java.lang.Object
com.kosdev.kos.ext.dispense.service.insertion.InsertionService

public final class InsertionService extends Object
Service that manages the process of inserting an ingredient container into holders. This service allows filters to be added and every insertion must pass every filter in order to successfully complete the insertion process. For example, a filter may check if an ingredient is expired or sold out before allowing it to be inserted.

This service tracks installed containers so the data is available to filters which can enforce rules around switching ingredients. However, this service does not assume that containers that existed before the last reboot are installed after a reboot. That is, on every restart it is the responsibility of some other service to insert all the ingredients again. For more complex devices like Freestyle dispensers which have rfid to detect cartridges, this handles the case where someone swapped cartridges while the device was turned off. For a more typical BiB device the IngredientAssignmentService can be used to persistently assign an ingredient to a holder and that service will perform all the insertions at startup.

When a filter prevents a container from being inserted, it remains in the insertion queue unless explicitly removed. This allows pending insertions to be retried if internal state changes such that the insertion may be successful. For example, consider a filter that blocks insertions of containers that use unknown ingredients. Until ingredients are installed all containers will have unknown ingredients and thus the filter will block all insertions. Once ingredients become available the pending inserts can be retried and completed as ingredients will now be known.

When a cartridge is removed using this service, all troubles tagged with the container will also be removed. Any troubles added using a filter will automatically be tagged with the container. Any troubles generated after insertion that are relative to the cartridge (sold out, expired, etc...) should tag the container to be removed automatically. The troubles related to this service such as ContainerTrouble and ContainerHolderTrouble will automatically tag the container.

Since:
1
Version:
1
  • Field Details

  • Method Details

    • insertIntrinsic

      public void insertIntrinsic(String ingredientId, Holder holder)
      Insert an intrinsic ingredient to a holder. Intrinsic ingredients tend to be fixed ingredients like water and carb, which are physically plumbed to the wall and cannot ever be changed. An intrinsic insertion will bypass all insertion filters and will be locked so that it cannot be removed.

      Some ingredients like HFCS or NNS may have dedicated pumps and might be considered intrinsic, but they may rely on a setup process to initialize them which can be triggered by filters during the first insertion. In these cases it may be easier to use regular insert vs. intrinsic insert.

      Intrinsics use the holder path as the container id.

      Parameters:
      ingredientId - the id of the ingredient to be inserted
      holder - the holder to insert into
      Since:
      1
    • insertIntrinsic

      public void insertIntrinsic(String ingredientId, String holderPath)
      Insert an intrinsic ingredient to a holder. Intrinsic ingredients tend to be fixed ingredients like water and carb, which are physically plumbed to the wall and cannot ever be changed. An intrinsic insertion will bypass all insertion filters and will be locked so that it cannot be removed.

      Some ingredients like HFCS or NNS may have dedicated pumps and might be considered intrinsic, but they may rely on a setup process to initialize them which can be triggered by filters during the first insertion. In these cases it may be easier to use regular insert vs. intrinsic insert.

      Intrinsics use the holder path as the container id.

      Parameters:
      ingredientId - the id of the ingredient to be inserted
      holderPath - the holder path to insert into
      Since:
      1
    • insertLocked

      public void insertLocked(String ingredientId, Holder holder)
      Insert a locked ingredient to a holder. Locked ingredients tend to be fixed ingredients like nutritive or non-nutritive sweeteners that are locked to a given holder and while physically replaced, are never logically removed in software. Unlike intrinsics, locked insertions are subject to insertion filters which can trigger setup processes for first time use, providing this functionality for free without requiring custom setup logic.

      Locked insertions use the holder path as the container id.

      Parameters:
      ingredientId - the id of the ingredient to be inserted
      holder - the holder to insert into
      Since:
      1
    • insertLocked

      public void insertLocked(String ingredientId, String holderPath)
      Insert a locked ingredient to a holder. Locked ingredients tend to be fixed ingredients like nutritive or non-nutritive sweeteners that are locked to a given holder and while physically replaced, are never logically removed in software. Unlike intrinsics, locked insertions are subject to insertion filters which can trigger setup processes for first time use, providing this functionality for free without requiring custom setup logic.

      Locked insertions use the holder path as the container id.

      Parameters:
      ingredientId - the id of the ingredient to be inserted
      holderPath - the holder path to insert into
      Since:
      1
    • insert

      public void insert(boolean inventoryScan, Container container, String holderPath)
      Convenience method for calling insert() after looking up the Holder from the specified holderPath . See other insert() for more details.
      Parameters:
      inventoryScan - true if part of inventory scan at boot, vs inserted after boot
      container - the container to install
      holderPath - holder path to insert into
      Since:
      1
    • insert

      public void insert(boolean inventoryScan, Container container, Holder holder)
      Insert the specified container into the specified holder. If the container contains multiple slices then the following assumptions are made:
      • The holders support getNext() in order to identify the additional holders the container spans. An example of this is a Freestyle dual cartridge which consumes more than one holder in shelf.
      • The holder specified is the leftmost / topmost holder in the group. That is, all additional holders are identified by getNext() .

      When a device first boots there is a concept of an inventory scan of existing ingredients. For example, for assignments stored in a database, these would be the existing assignments vs assignments made after the system is running. For Freestyle, this would be rfid tags found in the shelves during the first few shelf scans. This flag allows filters to behave differently for ingredients that are assumed to have existed across a reboot and may not be subject to the same processes as a newly inserted ingredient.

      Parameters:
      inventoryScan - true if part of inventory scan at boot, vs inserted after boot
      container - the container to install
      holder - holder to insert into
      Since:
      1
    • removeFromHolder

      public void removeFromHolder(String holderPath)
      Remove the container attached to the specified holder.
      Parameters:
      holderPath - the holder to remove the container from
      Since:
      1
    • removeFromHolder

      public void removeFromHolder(Holder holder)
      Remove the container attached to the specified holder.
      Parameters:
      holder - the holder to remove the container from
      Since:
      1
    • removeContainer

      public void removeContainer(Container container)
      Remove the container from the associated holder or from the pending insert list. This cannot remove a locked container.
      Parameters:
      container - the container to remove
      Since:
      1
    • removeLockedContainer

      public void removeLockedContainer(Container container)
      Remove the container from the associated holder or from the pending insert list, even if the container is locked.
      Parameters:
      container - the container to remove
      Since:
      1
    • addFilter

      public void addFilter(InsertionFilter<?> filter)
      Add a filter to the filter list. This will effectively append the filter to the default group group 0.0 with the next available position.
      Parameters:
      filter - the filter to add
      Since:
      1
    • addFilter

      public void addFilter(InsertionFilter<?> filter, double group)
      Add a filter to the filter list at the next available position for the specified group.

      Most filters are added in the order in which they should run, thus the default addFilter(filter) method is all that is needed. However, if there is a need to add a filter to the end of the chain and keep it there as new filters are added, this method can be used with a group number greater than 0.0 as addFilter(filter) always appends to the 0.0 group.

      Parameters:
      filter - the filter to add
      group - the group to add the filter to
      Since:
      1
    • addFilter

      public void addFilter(InsertionFilter<?> filter, double group, double position)
      Add a filter to the internal list in the specified group at the specified position. If there is already a filter at this group and position, the order of the two filters will be undefined. All filters are ordered by group and then position within the group.

      If the position has a greater value than the next available position for the group, the next available position will be set to the next value after the new position (any new appends will occur after this filter). If the value is lower than any existing filters (an insert between existing filters) then the next position for the group will remain unchanged.

      Most filters are added in the order in which they should run, thus the default addFilter(filter) method is all that is needed. However, if there is a need to insert a filter between two existing filters, this method can be used to position a filter anywhere in the chain. This requires examining the existing chain and picking the correct group / position combination to place the new filter in the desired location.

      Parameters:
      filter - the filter to add
      group - the group to add the filter to
      position - the position in the group for the filter
      Since:
      1
    • removeFilter

      public void removeFilter(InsertionFilter<?> filter)
      Remove a filter from the service.
      Since:
      1
    • getPrevIngredientIds

      public Collection<String> getPrevIngredientIds(Pump<?> pump)
      Return all previously inserted ingredientId's for the pump.
      Parameters:
      pump - the pump to return ingredients for
      Since:
      1