   by the watcher, if it is currently connected, and cancel the
   watcher itself. In such cases, `:disconnected` is meaningless."
   [controller & {:keys [disconnected] :or {disconnected false}}]
-  {:pre [(#{:launchpad-mini :launchpad-mini-watcher} (type controller))]}
+  {:pre [(have? #{:launchpad-mini :launchpad-mini-watcher} (type controller))]}
   (if (= (type controller) :launchpad-mini-watcher)
     (do ((:cancel controller))  ; Shut down the watcher
         (when-let [watched-controller @(:controller controller)]

(ns afterglow.controllers.launchpad-mini
  "Allows the Novation Launchpad Mini to be used as a control surface
  for Afterglow."
  {:author "James Elliott"}
  (:require [afterglow.controllers :as controllers]
            [afterglow.controllers.tempo :as tempo]
            [afterglow.effects.cues :as cues]
            [afterglow.midi :as amidi]
            [afterglow.rhythm :as rhythm]
            [afterglow.show :as show]
            [afterglow.show-context :refer [with-show]]
            [afterglow.util :as util]
            [clojure.math.numeric-tower :as math]
            [com.evocomputing.colors :as colors]
            [overtone.at-at :as at-at]
            [overtone.midi :as midi]
            [taoensso.timbre :as timbre :refer [warn]]

  [show & {:keys [device-filter refresh-interval display-name skip-animation]
           :or   {device-filter    "Mini"
                  refresh-interval (/ 1000 15)}}]
  {:pre [(have? some? show)]}
  (let [port-in        (first (amidi/filter-devices device-filter (amidi/open-inputs-if-needed!)))
        port-out       (first (amidi/filter-devices device-filter (amidi/open-outputs-if-needed!)))
        [device model] (when (every? some? [port-in port-out]) (valid-identity port-in port-out))]
