                   {:onClick (back-to-projects history)}
                   (title-for projects)]]]
            (om/build properties-table properties {:opts {:histkey :properties}})]])))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; sensors
+(defn status-label [status]
+  (if (= status "OK")
+    [:span {:class "label label-success"} status]
+    [:span {:class "label label-danger"} status]))
+
+(defn sensors-table [data owner {:keys [histkey path]}]
+  (reify
+    om/IRender
+    (render [_]
+      (let [sensors (:sensors data)
+            chart   (:chart data)
+            history (om/get-shared owner :history)
+            table-id "sensors-table"]
+
+        (html
+         [:table {:className "table table-hover"}
+          [:thead
+           [:tr [:th "Type"] [:th "Unit"] [:th "Period"] [:th "Device"] [:th "Status"]]]
+          [:tbody
+           (for [row (sort-by :type (-> sensors :data))]
+             (let [{:keys [device_id type unit period status]} row
+                   id (str type "-" device_id)]
+               [:tr {:onClick (fn [_ _]
+                                (om/update! sensors :selected id)
+                                (om/update! chart :sensor id)
+                                (om/update! chart :unit unit)
+                                (history/update-token-ids! history :sensors id))
+                     :className (if (= id (:selected sensors)) "success")
+                     :id (str table-id "-selected")}
+                [:td type]
+                [:td unit]
+                [:td period]
+                [:td device_id]
+                [:td (status-label status)]]))]])))))
+
+(defn chart-summary
+  "Show min, max, delta and average of chart data."
+  [chart owner]
+  (reify
+    om/IRender
+    (render [_]
+      (let [{:keys [unit measurements]} chart
+            ;; FIXME why are measurements nested? (in prep for multi-series?)
+            series-1 (:measurements measurements)
+            vals-1 (map :value series-1)
+            series-1-min (apply min vals-1)
+            series-1-max (apply max vals-1)
+            series-1-sum (reduce + vals-1)
+            series-1-count (count series-1)
+            series-1-mean (if (not= 0 series-1-count) (/ series-1-sum series-1-count) "NA")]
+        (html
+         (if (seq series-1)
+           [:div.col-md-12#summary-stats
+            [:div {:class "col-md-3"}
+             (bs/panel "Minimum" (str (.toFixed (js/Number. series-1-min) 3) " " unit))]
+            [:div {:class "col-md-3"}
+             (bs/panel "Maximum" (str (.toFixed (js/Number. series-1-max) 3) " " unit))]
+            [:div {:class "col-md-3"}
+             (bs/panel "Average (mean)" (str (.toFixed (js/Number. series-1-mean) 3) " " unit))]
+            [:div {:class "col-md-3"}
+             (bs/panel "Range" (str (.toFixed (js/Number. (- series-1-max series-1-min)) 3) " " unit))]]
+           [:div.row#summary-stats [:div.col-md-12.text-center [:p.lead {:style {:padding-top 30}} "No data."]]]))))))
+
+(defn sensors-div [data owner]
+  (reify
+    om/IRender
+    (render [_]
+      (html
+       [:div.col-md-12
+        [:h3 {:id "sensors"} "Sensors"]
+        (om/build sensors-table data {:opts {:histkey :sensors
+                                             :path    :readings}})
+        [:div {:id "chart-div"}
+         [:div {:id "date-picker"}
+          (om/build dtpicker/date-picker data {:opts {:histkey :range}})]
+         (om/build chart-feedback-box (get-in data [:chart :message]))
+         (om/build chart-summary (:chart data))
+         [:div {:className "well" :id "chart" :style {:width "100%" :height 600}}
+          (om/build chart/chart-figure (:chart data))]]]))))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; property-details

             (om/build properties-div data)
             (om/build property-details-div data)
             ;; (om/build devices-div data)
             ;; (om/build device-detail devices)
             ;; (om/build sensors-div data)
             ;; (om/build sensor/define-data-set-button data)

             ]))))

                                    :properties
                                    :data
                                    (filter #(= (:id %) properties))
                                    first)
              devices (get property-details :devices [])]
          (println "property-details keys: " (keys property-details))
          (om/update! data [:property-details :data] property-details)
          (om/update! data [:sensors :data] (extract-sensors devices))))
      
      ;; Update the new active components
      (om/update! data :active-components (-> nav-event :args :ids)))
