Skip to content

Instantly share code, notes, and snippets.

@aphyr
Created February 13, 2017 21:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aphyr/a8f22272d3be3b4dd20db23d0faa9196 to your computer and use it in GitHub Desktop.
Save aphyr/a8f22272d3be3b4dd20db23d0faa9196 to your computer and use it in GitHub Desktop.
Randomly assign hue lights from interweb color schemes
(ns lights.core
(:require [me.raynes.clhue [config :as conf]
[lights :as lights]]
[clj-http.client :as http]
[clojure.pprint :refer [pprint]]
[clojure.java.io :as io]
[hickory [core :as h]
[select :as hs]]
[cheshire.core :as json]
[clojure.core.reducers :as r]))
(defn auth!
[]
(conf/auth-user {:address host} "waterhouse"))
(def host "your-hue-ip")
(def username "fill-me-in-with-auth!")
(def c {:address host
:user username})
(defn hex->rgb
"Takes a hex string and converts it to a double-precision {r, g, b} map, with
ranges 0->1."
[hex]
{:r (double (/ (Long/parseLong (subs hex 0 2) 16) 255))
:g (double (/ (Long/parseLong (subs hex 2 4) 16) 255))
:b (double (/ (Long/parseLong (subs hex 4 6) 16) 255))})
(defn rgb->xyz
"Maps rgb color to xyz CIE."
[{:keys [r g b]}]
(let [r (if (< 0.04045 r)
(Math/pow (/ (+ r 0.055) 1.055) 2.4)
(/ r 12.92))
g (if (< 0.04045 g)
(Math/pow (/ (+ g 0.055) 1.055) 2.4)
(/ g 12.92))
b (if (< 0.04045 b)
(Math/pow (/ (+ b 0.055) 1.055) 2.4)
(/ b 12.92))]
{:x (+ (* r 0.4124) (* g 0.3576) (* b 0.1805))
:y (+ (* r 0.2126) (* g 0.7152) (* b 0.0722))
:z (+ (* r 0.0193) (* g 0.1192) (* b 0.9505))}))
(defn xyz->hue
"Converts CIE xyz coordinates to hue coords"
[{:keys [x y z]}]
{:xy [x y]
:bri (long (* y 255))})
(defn hex->hue
[hex]
(-> hex hex->rgb rgb->xyz xyz->hue))
(defn map-kv
"Takes a function (f [k v]) which returns [k v], and builds a new map by
applying f to every pair."
[f m]
(into {} (r/map f m)))
(defn map-vals
"Maps values in a map."
[f m]
(map-kv (fn [[k v]] [k (f v)]) m))
(defn clip
"Clips a value to the 0-255 range."
[x]
(min 255 (max 0 x)))
(defn lights
"Gets lights config"
[config]
(lights/lights config))
(defn lights!
"Applies settings to multiple lights, given a map of light IDs to a map of
state names to values."
[config settings]
(pprint settings)
(doall
(map (fn [[id state]]
(lights/light config (name id) state))
settings)))
(defn scale!
[factor]
(->> (lights/lights c)
(map-vals #(->> % :state :bri (+ factor) clip (hash-map :bri)))
(lights! c)))
(defn higher!
[]
(scale! 50))
(defn lower!
[]
(scale! -50))
(defn rand-palette
"Get a color palette"
[]
(->> (http/get "http://www.colourlovers.com/api/palettes/random")
:body
h/parse
h/as-hickory
(hs/select (hs/child (hs/tag :palettes)
(hs/tag :palette)
(hs/tag :colors)
(hs/tag :hex)))
(map :content)
(map first)))
(defn apply-palette!
"Takes a palette and applies it to lights."
[config palette]
(->> (lights config)
(into {})
(map-vals (fn [_] (-> palette rand-nth hex->hue)))
(lights! c)))
(defn go!
[]
(while true
(Thread/sleep 5000)
(apply-palette! c (rand-palette))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment