       (swap! state assoc-in [:last-stage-positions stage-dev] [x y]))))
 
 (defn set-property
-  ([prop] (let [[d p v] prop]
-            (device-best-effort d (core setProperty d p v)))))
+  [prop]
+  (let [[d p v] prop]
+    (when (not= v (get-in @state [:last-property-settings d p]))
+      (device-best-effort d (core setProperty d p v))
+      (swap! state assoc-in [:last-property-settings d p] v))))
 
 (defn run-autofocus []
   (let [z-drive (@state :default-z-drive)

              0))
         z-ref))))

(defn update-z-positions [msp-index]
  (when-let [msp (get-msp msp-index)]
    (dotimes [i (.size msp)]
      (let [stage-pos (.get msp i)
            stage-name (.stageName stage-pos)]
        (when (= 1 (.numAxes stage-pos))
          (when (or (not (core isContinuousFocusEnabled))
                    (core isContinuousFocusDrive stage-name))
            (set-msp-z-position msp-index stage-name (get-z-stage-position stage-name))))))))

(defn recall-z-reference [current-position]
  (let [z-drive (@state :default-z-drive)]
    (when (or (not (core isContinuousFocusEnabled))
              (core isContinuousFocusDrive z-drive))
      (set-z-stage-position z-drive
        (or (get-msp-z-position current-position z-drive)
            (@state :reference-z))))))

(defn store-z-reference [current-position]
  (let [z-drive (@state :default-z-drive)]
    (when (and (or (not (core isContinuousFocusEnabled))
                   (core isContinuousFocusDrive z-drive)))
      (let [z (get-z-stage-position z-drive)]
        (state-assoc! :reference-z z)))))


            #(set-property [d p v]))
          #(when-lets [exposure (:exposure event)
                       camera (core getCameraDevice)]
             (set-exposure camera exposure))
          #(when check-z-ref
             (recall-z-reference current-position))
          #(when-let [wait-time-ms (:wait-time-ms event)]
