hued 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +57 -0
- data/README.md +149 -0
- data/Rakefile +19 -0
- data/VERSION +1 -0
- data/bin/hued +36 -0
- data/lib/hued.rb +115 -0
- data/resources/api/config +13 -0
- data/resources/api/description.xml +39 -0
- metadata +96 -0
    
        checksums.yaml
    ADDED
    
    | @@ -0,0 +1,7 @@ | |
| 1 | 
            +
            ---
         | 
| 2 | 
            +
            SHA1:
         | 
| 3 | 
            +
              metadata.gz: b5cf08955db23b65793e437c07db14d6b866017b
         | 
| 4 | 
            +
              data.tar.gz: 086a26303c15748e74ed137ab8d44e23f25b9590
         | 
| 5 | 
            +
            SHA512:
         | 
| 6 | 
            +
              metadata.gz: d5a4c0d3238d1278a878fc5053f1aa5f6601a00a9f15bfde35c53597d97124a1bc8ea7b2c13a11ad4cfaea34cced002d4e2509acce8494d01eb588b501bfb215
         | 
| 7 | 
            +
              data.tar.gz: 1785b51a324ec14fe8e1237177013a217440a583d102f7de2c4797e9eb6fc335a2396c758feb53a0e4222faa2c51b9ec7b8c215830ac35edbef6fd43c2654886
         | 
    
        data/Gemfile
    ADDED
    
    
    
        data/Gemfile.lock
    ADDED
    
    | @@ -0,0 +1,57 @@ | |
| 1 | 
            +
            GEM
         | 
| 2 | 
            +
              remote: https://rubygems.org/
         | 
| 3 | 
            +
              specs:
         | 
| 4 | 
            +
                addressable (2.4.0)
         | 
| 5 | 
            +
                builder (3.2.2)
         | 
| 6 | 
            +
                descendants_tracker (0.0.4)
         | 
| 7 | 
            +
                  thread_safe (~> 0.3, >= 0.3.1)
         | 
| 8 | 
            +
                faraday (0.9.2)
         | 
| 9 | 
            +
                  multipart-post (>= 1.2, < 3)
         | 
| 10 | 
            +
                git (1.3.0)
         | 
| 11 | 
            +
                github_api (0.13.1)
         | 
| 12 | 
            +
                  addressable (~> 2.4.0)
         | 
| 13 | 
            +
                  descendants_tracker (~> 0.0.4)
         | 
| 14 | 
            +
                  faraday (~> 0.8, < 0.10)
         | 
| 15 | 
            +
                  hashie (>= 3.4)
         | 
| 16 | 
            +
                  multi_json (>= 1.7.5, < 2.0)
         | 
| 17 | 
            +
                  oauth2
         | 
| 18 | 
            +
                hashie (3.4.4)
         | 
| 19 | 
            +
                highline (1.7.8)
         | 
| 20 | 
            +
                jeweler (2.0.1)
         | 
| 21 | 
            +
                  builder
         | 
| 22 | 
            +
                  bundler (>= 1.0)
         | 
| 23 | 
            +
                  git (>= 1.2.5)
         | 
| 24 | 
            +
                  github_api
         | 
| 25 | 
            +
                  highline (>= 1.6.15)
         | 
| 26 | 
            +
                  nokogiri (>= 1.5.10)
         | 
| 27 | 
            +
                  rake
         | 
| 28 | 
            +
                  rdoc
         | 
| 29 | 
            +
                json (1.8.3)
         | 
| 30 | 
            +
                jwt (1.5.1)
         | 
| 31 | 
            +
                mini_portile2 (2.0.0)
         | 
| 32 | 
            +
                multi_json (1.11.3)
         | 
| 33 | 
            +
                multi_xml (0.5.5)
         | 
| 34 | 
            +
                multipart-post (2.0.0)
         | 
| 35 | 
            +
                nokogiri (1.6.7.2)
         | 
| 36 | 
            +
                  mini_portile2 (~> 2.0.0.rc2)
         | 
| 37 | 
            +
                oauth2 (1.1.0)
         | 
| 38 | 
            +
                  faraday (>= 0.8, < 0.10)
         | 
| 39 | 
            +
                  jwt (~> 1.0, < 1.5.2)
         | 
| 40 | 
            +
                  multi_json (~> 1.3)
         | 
| 41 | 
            +
                  multi_xml (~> 0.5)
         | 
| 42 | 
            +
                  rack (>= 1.2, < 3)
         | 
| 43 | 
            +
                rack (1.6.4)
         | 
| 44 | 
            +
                rake (10.5.0)
         | 
| 45 | 
            +
                rdoc (4.2.2)
         | 
| 46 | 
            +
                  json (~> 1.4)
         | 
| 47 | 
            +
                thread_safe (0.3.5)
         | 
| 48 | 
            +
             | 
| 49 | 
            +
            PLATFORMS
         | 
| 50 | 
            +
              ruby
         | 
| 51 | 
            +
             | 
| 52 | 
            +
            DEPENDENCIES
         | 
| 53 | 
            +
              jeweler (~> 2.0.1, >= 2.0.1)
         | 
| 54 | 
            +
              json (~> 1.8.3, >= 1.8)
         | 
| 55 | 
            +
             | 
| 56 | 
            +
            BUNDLED WITH
         | 
| 57 | 
            +
               1.11.2
         | 
    
        data/README.md
    ADDED
    
    | @@ -0,0 +1,149 @@ | |
| 1 | 
            +
            hued - (?:ab)using the Hue HTTP API
         | 
| 2 | 
            +
            ====
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            - [writeup](#writeup)
         | 
| 5 | 
            +
            - [API methods](#api-methods)
         | 
| 6 | 
            +
            - [notes](#notes)
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            # writeup
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            want to talk to your [Philips Hue](http://www2.meethue.com/en-us/) lights directly through an HTTP API without registering an application?
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            to turn off the currently-in-use lighting scheme:
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            ```
         | 
| 15 | 
            +
            ~/hue $ curl -X PUT http://<hue hub>/api/<token>/groups/0/action -d '{"on":true}'
         | 
| 16 | 
            +
            [{"success":{"/groups/0/action/on":true}}]
         | 
| 17 | 
            +
            ```
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            all you need are:
         | 
| 20 | 
            +
              - the IP for the Hue Hub plugged in to your network
         | 
| 21 | 
            +
              - a 'whitelisted' token to talk to the API
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            finding the IP should be pretty straight forward, but the nmap output is not very specific:
         | 
| 24 | 
            +
            ```
         | 
| 25 | 
            +
            ~/hue $ nmap 192.168.42.0/24
         | 
| 26 | 
            +
            ...
         | 
| 27 | 
            +
            Nmap scan report for 192.168.42.66
         | 
| 28 | 
            +
            Host is up (0.0063s latency).
         | 
| 29 | 
            +
            Not shown: 65534 closed ports
         | 
| 30 | 
            +
            PORT   STATE SERVICE    VERSION
         | 
| 31 | 
            +
            80/tcp open  tcpwrapped
         | 
| 32 | 
            +
            ...
         | 
| 33 | 
            +
            ```
         | 
| 34 | 
            +
             | 
| 35 | 
            +
            the Hue hub uses DHCP by default, so it likely won't be at that address for you, but you get the idea.
         | 
| 36 | 
            +
             | 
| 37 | 
            +
            now, you need to get a token. to do that, trick the Hue app on your phone/tablet/Echo to send it to us.
         | 
| 38 | 
            +
             | 
| 39 | 
            +
              - stand up a webserver listening for GET of `http://0.0.0.0:80/api/config` on the same network (0/24) your phone/tablet/Echo is on
         | 
| 40 | 
            +
              - `api/config` needs to be JSON that a Hue hub would return (sample included in repo)
         | 
| 41 | 
            +
              - from your phone/tablet/Echo, select `Settings->Find Bridge->Search`
         | 
| 42 | 
            +
                * this works intermittently, as some times the app found the real hub and the imposter, other times it would only find the real hub, but would mostly end up with a 'Specify IP' button
         | 
| 43 | 
            +
              - wait for the app to query your imposter, and you'll have a token
         | 
| 44 | 
            +
             | 
| 45 | 
            +
            by the numbers:
         | 
| 46 | 
            +
             | 
| 47 | 
            +
            ```
         | 
| 48 | 
            +
            ~/hue $ cat api/config
         | 
| 49 | 
            +
            HTTP/1.1 200 OK
         | 
| 50 | 
            +
            Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
         | 
| 51 | 
            +
            Pragma: no-cache
         | 
| 52 | 
            +
            Expires: Mon, 1 Aug 2011 09:00:00 GMT
         | 
| 53 | 
            +
            Connection: close
         | 
| 54 | 
            +
            Access-Control-Max-Age: 3600
         | 
| 55 | 
            +
            Access-Control-Allow-Origin: *
         | 
| 56 | 
            +
            Access-Control-Allow-Credentials: true
         | 
| 57 | 
            +
            Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE, HEAD
         | 
| 58 | 
            +
            Access-Control-Allow-Headers: Content-Type
         | 
| 59 | 
            +
            Content-type: application/json
         | 
| 60 | 
            +
             | 
| 61 | 
            +
            {"name": "Philips hue","swversion": "01032318","apiversion": "1.13.0","mac": "DE:AD:BE:EF:CA:FE","bridgeid": "001788FFFECAFE","factorynew": false,"replacesbridgeid": null,"modelid": "BSB001"}
         | 
| 62 | 
            +
            ~/hue $ while true; do sudo nc -l 80 < api/config; done
         | 
| 63 | 
            +
            ...
         | 
| 64 | 
            +
            GET /api/config HTTP/1.1
         | 
| 65 | 
            +
            Host: 192.168.42.83
         | 
| 66 | 
            +
            Accept: */*
         | 
| 67 | 
            +
            Accept-Language: en-us
         | 
| 68 | 
            +
            Connection: keep-alive
         | 
| 69 | 
            +
            Accept-Encoding: gzip, deflate
         | 
| 70 | 
            +
            User-Agent: Hue/1 CFNetwork/758.4.3 Darwin/15.5.0
         | 
| 71 | 
            +
             | 
| 72 | 
            +
            GET /api/eKpsfhR9K1u32/config HTTP/1.1
         | 
| 73 | 
            +
            Host: 192.168.42.83
         | 
| 74 | 
            +
            Accept: */*
         | 
| 75 | 
            +
            Accept-Language: en-us
         | 
| 76 | 
            +
            Connection: keep-alive
         | 
| 77 | 
            +
            Accept-Encoding: gzip, deflate
         | 
| 78 | 
            +
            User-Agent: Hue/1 CFNetwork/758.4.3 Darwin/15.5.0
         | 
| 79 | 
            +
             | 
| 80 | 
            +
            GET /api/eKpsfhR9K1u32 HTTP/1.1
         | 
| 81 | 
            +
            Host: 192.168.42.83
         | 
| 82 | 
            +
            Accept: */*
         | 
| 83 | 
            +
            Accept-Language: en-us
         | 
| 84 | 
            +
            Connection: keep-alive
         | 
| 85 | 
            +
            Accept-Encoding: gzip, deflate
         | 
| 86 | 
            +
            User-Agent: Hue/1 CFNetwork/758.4.3 Darwin/15.5.0
         | 
| 87 | 
            +
            ```
         | 
| 88 | 
            +
             | 
| 89 | 
            +
            and now we have our token, `eKpsfhR9K1u32`. with that, we can call (all?) API methods
         | 
| 90 | 
            +
             | 
| 91 | 
            +
            # API methods
         | 
| 92 | 
            +
             | 
| 93 | 
            +
            api|description|GET|PUT
         | 
| 94 | 
            +
            ----|-----------|---------------|----------------
         | 
| 95 | 
            +
            `/config/`|set and query existing settings|without token for unauthenticated, basic registration information, with token for light/device/schedule/sensor configuration|JSON matching schema validation|
         | 
| 96 | 
            +
            `/lights/`|scan and query existing lights|JSON scan status|empty body to start a scan
         | 
| 97 | 
            +
            `/sensors/`|scan and query existing sensors|JSON scan status|empty body to start a scan
         | 
| 98 | 
            +
            `/scenes/`|set and query existing scenes|JSON scene list| /`<uuid>/lights/<id>/state => {"on":true,"xy":[0.5804,0.3995],"bri":253}`
         | 
| 99 | 
            +
            `/schedules/`|set and query existing schedules/timers|JSON schedules/timers|`/<uuid> => {"name":"Alarm","autodelete":false,"localtime":"2016-06-20T16:20:00","description":"giants","status":"enabled","command":{"address":"/api/eKpsfhR9K1u32/groups/0/action","body":{"scene":"f55e38250-on-0"},"method":"PUT"}}`
         | 
| 100 | 
            +
            `/groups/`|set and query scene (?) groupings|empty JSON|`/<id>/action => {"scene":"2fc89fcdb-on-0"}`
         | 
| 101 | 
            +
             | 
| 102 | 
            +
            a few example request/responses:
         | 
| 103 | 
            +
             | 
| 104 | 
            +
            ```json
         | 
| 105 | 
            +
            # http://192.168.42.66/api/eKpsfhR9K1u32/scenes
         | 
| 106 | 
            +
            {
         | 
| 107 | 
            +
              "f4750b0cf-off-5": {
         | 
| 108 | 
            +
                "name": "HIDDEN foff 1452936620159",
         | 
| 109 | 
            +
                "lights": [
         | 
| 110 | 
            +
                  "1",
         | 
| 111 | 
            +
                  "2",
         | 
| 112 | 
            +
                  "3",
         | 
| 113 | 
            +
                  "4",
         | 
| 114 | 
            +
                  "5",
         | 
| 115 | 
            +
                  "6",
         | 
| 116 | 
            +
                  "7",
         | 
| 117 | 
            +
                  "8",
         | 
| 118 | 
            +
                  "9",
         | 
| 119 | 
            +
                  "10"
         | 
| 120 | 
            +
                ],
         | 
| 121 | 
            +
                "owner": "eKpsfhR9K1u32",
         | 
| 122 | 
            +
                "recycle": true,
         | 
| 123 | 
            +
                "locked": true,
         | 
| 124 | 
            +
                "appdata": {
         | 
| 125 | 
            +
             | 
| 126 | 
            +
                },
         | 
| 127 | 
            +
                "picture": "",
         | 
| 128 | 
            +
                "lastupdated": "2016-01-16T09:30:21",
         | 
| 129 | 
            +
                "version": 1
         | 
| 130 | 
            +
              },
         | 
| 131 | 
            +
              ...
         | 
| 132 | 
            +
            }  
         | 
| 133 | 
            +
            ```
         | 
| 134 | 
            +
             | 
| 135 | 
            +
            # notes
         | 
| 136 | 
            +
             | 
| 137 | 
            +
            all versions tested are the latest available as of 2016/06/19
         | 
| 138 | 
            +
             | 
| 139 | 
            +
            component|version|notes
         | 
| 140 | 
            +
            ---------|-------|-----
         | 
| 141 | 
            +
            Philips Hue Hub|5.23.1.13452|
         | 
| 142 | 
            +
            Hue mobile App|1.12.1.0|same version reported on both Android and Apple devices
         | 
| 143 | 
            +
             | 
| 144 | 
            +
            TODO
         | 
| 145 | 
            +
            * dig further in api/\<token\>/config
         | 
| 146 | 
            +
              * determine how the hashes are generated. not concatenation of create time / name in any obvious way. different devices seem to come up with hashes in different ways. older iPhone/iPad apps were [A-Z0-9]{16}, while Android ones seem to always have been [A-Z]{32}
         | 
| 147 | 
            +
            * write a client library/binding? or at least some abstraction
         | 
| 148 | 
            +
            * determine the truly necessary pieces of the imposter response, think it really only needs content-type and minimal JSON
         | 
| 149 | 
            +
            * work on SSDP discovery, see [description.xml](resources/api/description.xml)
         | 
    
        data/Rakefile
    ADDED
    
    | @@ -0,0 +1,19 @@ | |
| 1 | 
            +
            require 'jeweler'
         | 
| 2 | 
            +
            require 'rake'
         | 
| 3 | 
            +
            require 'rake/clean'
         | 
| 4 | 
            +
            require 'rake/testtask'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            CLEAN.include('pkg/*')
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            Jeweler::Tasks.new do |gem|
         | 
| 9 | 
            +
              gem.name        = 'hued'
         | 
| 10 | 
            +
              gem.summary     = 'Philips Hue HTTP API bindings'
         | 
| 11 | 
            +
              gem.description = 'interact with Philips Hue Hub to control your devices'
         | 
| 12 | 
            +
              gem.email       = ['conor.code@gmail.com']
         | 
| 13 | 
            +
              gem.homepage    = 'http://github.com/chorankates/hued'
         | 
| 14 | 
            +
              gem.authors     = ['Conor Horan-Kates', 'Maureen Long']
         | 
| 15 | 
            +
              gem.licenses    =  'MIT'
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              gem.executables = ['hued']
         | 
| 18 | 
            +
            end
         | 
| 19 | 
            +
            Jeweler::RubygemsDotOrgTasks.new
         | 
    
        data/VERSION
    ADDED
    
    | @@ -0,0 +1 @@ | |
| 1 | 
            +
            0.0.1
         | 
    
        data/bin/hued
    ADDED
    
    | @@ -0,0 +1,36 @@ | |
| 1 | 
            +
            #!/usr/bin/env ruby
         | 
| 2 | 
            +
            # hued - CLI for Hued module
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            require 'hued'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            def parse_input
         | 
| 7 | 
            +
              options = Hash.new
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              parser = OptionParser.new do |o|
         | 
| 10 | 
            +
                o.on('--ip <ip>', 'IP address of Phillips Hue Hub') do |p|
         | 
| 11 | 
            +
                  options[:ip] = p
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
                o.on('--token <token>', 'whitelisted token') do |p|
         | 
| 14 | 
            +
                  options[:token] = p
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              parser.parse!
         | 
| 19 | 
            +
              options
         | 
| 20 | 
            +
            end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            options = parse_input
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            hub = Hued::Hub.new(options[:ip], options[:token])
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            # TODO this should really be a REPL
         | 
| 27 | 
            +
            off = hub.all_lights_off
         | 
| 28 | 
            +
            puts "off: #{off}"
         | 
| 29 | 
            +
             | 
| 30 | 
            +
            sleep 5
         | 
| 31 | 
            +
             | 
| 32 | 
            +
            on = hub.all_lights_on
         | 
| 33 | 
            +
            puts "on: #{on}"
         | 
| 34 | 
            +
             | 
| 35 | 
            +
            off = hub.all_lights_off
         | 
| 36 | 
            +
            puts "off(2): #{off}"
         | 
    
        data/lib/hued.rb
    ADDED
    
    | @@ -0,0 +1,115 @@ | |
| 1 | 
            +
            #!/usr/bin/env ruby
         | 
| 2 | 
            +
            ## hued.rb Philips Hue HTTP binding
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            require 'json'
         | 
| 5 | 
            +
            require 'net/http'
         | 
| 6 | 
            +
            require 'optparse'
         | 
| 7 | 
            +
            require 'yaml'
         | 
| 8 | 
            +
            require 'uri'
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            module Hued
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              class Hub
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                attr_accessor :lights, :scenes, :schedules
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                def initialize(ip, token)
         | 
| 17 | 
            +
                  @ip    = ip
         | 
| 18 | 
            +
                  @token = token
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                  raise "no IP specified" if @ip.nil?
         | 
| 21 | 
            +
                  raise "no token specified" if @token.nil?
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                  @config = get_config()
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                  @lights    = get_lights()
         | 
| 26 | 
            +
                  @scenes    = get_scenes()
         | 
| 27 | 
            +
                  @schedules = get_schedules()
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                def inspect
         | 
| 31 | 
            +
                  {
         | 
| 32 | 
            +
                    :ip        => @ip,
         | 
| 33 | 
            +
                    :token     => @token,
         | 
| 34 | 
            +
                    :lights    => @lights.size,
         | 
| 35 | 
            +
                    :scenes    => @scenes.size,
         | 
| 36 | 
            +
                    :schedules => @schedules.size,
         | 
| 37 | 
            +
                  }
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                def to_s
         | 
| 41 | 
            +
                  inspect.to_s
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                def get_config
         | 
| 45 | 
            +
                  JSON.parse(get_http(get_url('config')).body)
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                def get_lights(input = nil)
         | 
| 49 | 
            +
                  lights   = Array.new
         | 
| 50 | 
            +
                  response = JSON.parse(get_http(get_url('lights')).body)
         | 
| 51 | 
            +
                  response.each do |_i, hash|
         | 
| 52 | 
            +
                    lights << OpenStruct.new(hash)
         | 
| 53 | 
            +
                  end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                  lights
         | 
| 56 | 
            +
                end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                def get_scenes(input = nil)
         | 
| 59 | 
            +
                  scenes = Array.new
         | 
| 60 | 
            +
                  response = JSON.parse(get_http(get_url('scenes')).body)
         | 
| 61 | 
            +
                  response.each do |_i, hash|
         | 
| 62 | 
            +
                    scenes << OpenStruct.new(hash)
         | 
| 63 | 
            +
                  end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                  scenes
         | 
| 66 | 
            +
                end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                def get_schedules(input = nil)
         | 
| 69 | 
            +
                  schedules = Array.new
         | 
| 70 | 
            +
                  response  = JSON.parse(get_http(get_url('schedules')).body)
         | 
| 71 | 
            +
                  response.each do |_i, hash|
         | 
| 72 | 
            +
                    schedules << OpenStruct.new(hash)
         | 
| 73 | 
            +
                  end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                  schedules
         | 
| 76 | 
            +
                end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                def all_lights_on
         | 
| 79 | 
            +
                  url     = get_url('groups/0/action')
         | 
| 80 | 
            +
                  payload = { :on => true }
         | 
| 81 | 
            +
                  put_http(url, payload)
         | 
| 82 | 
            +
                end
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                def all_lights_off
         | 
| 85 | 
            +
                  url     = get_url('groups/0/action')
         | 
| 86 | 
            +
                  payload = { :on => false }
         | 
| 87 | 
            +
                  put_http(url, payload)
         | 
| 88 | 
            +
                end
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                ## helper functions
         | 
| 91 | 
            +
                def get_url(method)
         | 
| 92 | 
            +
                  sprintf('http://%s/api/%s/%s', @ip, @token, method)
         | 
| 93 | 
            +
                end
         | 
| 94 | 
            +
             | 
| 95 | 
            +
                def get_http(url)
         | 
| 96 | 
            +
                  uri      = URI.parse(url)
         | 
| 97 | 
            +
                  http     = Net::HTTP.new(uri.host, uri.port)
         | 
| 98 | 
            +
                  http.use_ssl = false
         | 
| 99 | 
            +
                  request  = Net::HTTP::Get.new(uri.request_uri)
         | 
| 100 | 
            +
                  http.request(request)
         | 
| 101 | 
            +
                end
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                def put_http(url, body)
         | 
| 104 | 
            +
                  uri     = URI.parse(url)
         | 
| 105 | 
            +
                  http    = Net::HTTP.new(uri.host, uri.port)
         | 
| 106 | 
            +
                  request = Net::HTTP::Put.new(uri.request_uri)
         | 
| 107 | 
            +
             | 
| 108 | 
            +
                  request.add_field('Content-Type', 'application.json')
         | 
| 109 | 
            +
                  request.body = body.to_json
         | 
| 110 | 
            +
                  http.request(request)
         | 
| 111 | 
            +
                end
         | 
| 112 | 
            +
             | 
| 113 | 
            +
              end
         | 
| 114 | 
            +
             | 
| 115 | 
            +
            end
         | 
| @@ -0,0 +1,13 @@ | |
| 1 | 
            +
            HTTP/1.1 200 OK
         | 
| 2 | 
            +
            Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
         | 
| 3 | 
            +
            Pragma: no-cache
         | 
| 4 | 
            +
            Expires: Mon, 1 Aug 2011 09:00:00 GMT
         | 
| 5 | 
            +
            Connection: close
         | 
| 6 | 
            +
            Access-Control-Max-Age: 3600
         | 
| 7 | 
            +
            Access-Control-Allow-Origin: *
         | 
| 8 | 
            +
            Access-Control-Allow-Credentials: true
         | 
| 9 | 
            +
            Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE, HEAD
         | 
| 10 | 
            +
            Access-Control-Allow-Headers: Content-Type
         | 
| 11 | 
            +
            Content-type: application/json
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            {"name": "Philips hue","swversion": "01032318","apiversion": "1.13.0","mac": "DE:AD:BE:EF:CA:FE","bridgeid": "001788FFFECAFE","factorynew": false,"replacesbridgeid": null,"modelid": "BSB001"}
         | 
| @@ -0,0 +1,39 @@ | |
| 1 | 
            +
             | 
| 2 | 
            +
             | 
| 3 | 
            +
            <?xml version="1.0" encoding="UTF-8"?>
         | 
| 4 | 
            +
            <root xmlns="urn:schemas-upnp-org:device-1-0">
         | 
| 5 | 
            +
                <specVersion>
         | 
| 6 | 
            +
                    <major>1</major>
         | 
| 7 | 
            +
                    <minor>0</minor>
         | 
| 8 | 
            +
                </specVersion>
         | 
| 9 | 
            +
                <URLBase>http://192.168.42.66:80/</URLBase>
         | 
| 10 | 
            +
                <device>
         | 
| 11 | 
            +
                    <deviceType>urn:schemas-upnp-org:device:Basic:1</deviceType>
         | 
| 12 | 
            +
                    <friendlyName>Philips hue (192.168.42.66)</friendlyName>
         | 
| 13 | 
            +
                    <manufacturer>Royal Philips Electronics</manufacturer>
         | 
| 14 | 
            +
                    <manufacturerURL>http://www.philips.com</manufacturerURL>
         | 
| 15 | 
            +
                    <modelDescription>Philips hue Personal Wireless Lighting</modelDescription>
         | 
| 16 | 
            +
                    <modelName>Philips hue bridge 2012</modelName>
         | 
| 17 | 
            +
                    <modelNumber>000</modelNumber>
         | 
| 18 | 
            +
                    <modelURL>http://www.meethue.com</modelURL>
         | 
| 19 | 
            +
                    <serialNumber>000</serialNumber>
         | 
| 20 | 
            +
                    <UDN>000</UDN>
         | 
| 21 | 
            +
                    <presentationURL>index.html</presentationURL>
         | 
| 22 | 
            +
                    <iconList>
         | 
| 23 | 
            +
                        <icon>
         | 
| 24 | 
            +
                            <mimetype>image/png</mimetype>
         | 
| 25 | 
            +
                            <height>48</height>
         | 
| 26 | 
            +
                            <width>48</width>
         | 
| 27 | 
            +
                            <depth>24</depth>
         | 
| 28 | 
            +
                            <url>hue_logo_0.png</url>
         | 
| 29 | 
            +
                        </icon>
         | 
| 30 | 
            +
                        <icon>
         | 
| 31 | 
            +
                            <mimetype>image/png</mimetype>
         | 
| 32 | 
            +
                            <height>120</height>
         | 
| 33 | 
            +
                            <width>120</width>
         | 
| 34 | 
            +
                            <depth>24</depth>
         | 
| 35 | 
            +
                            <url>hue_logo_3.png</url>
         | 
| 36 | 
            +
                        </icon>
         | 
| 37 | 
            +
                    </iconList>
         | 
| 38 | 
            +
                </device>
         | 
| 39 | 
            +
            </root>
         | 
    
        metadata
    ADDED
    
    | @@ -0,0 +1,96 @@ | |
| 1 | 
            +
            --- !ruby/object:Gem::Specification
         | 
| 2 | 
            +
            name: hued
         | 
| 3 | 
            +
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            +
              version: 0.0.1
         | 
| 5 | 
            +
            platform: ruby
         | 
| 6 | 
            +
            authors:
         | 
| 7 | 
            +
            - Conor Horan-Kates
         | 
| 8 | 
            +
            - Maureen Long
         | 
| 9 | 
            +
            autorequire: 
         | 
| 10 | 
            +
            bindir: bin
         | 
| 11 | 
            +
            cert_chain: []
         | 
| 12 | 
            +
            date: 2016-06-21 00:00:00.000000000 Z
         | 
| 13 | 
            +
            dependencies:
         | 
| 14 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 15 | 
            +
              name: json
         | 
| 16 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 17 | 
            +
                requirements:
         | 
| 18 | 
            +
                - - '>='
         | 
| 19 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 20 | 
            +
                    version: '1.8'
         | 
| 21 | 
            +
                - - ~>
         | 
| 22 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 23 | 
            +
                    version: 1.8.3
         | 
| 24 | 
            +
              type: :runtime
         | 
| 25 | 
            +
              prerelease: false
         | 
| 26 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 27 | 
            +
                requirements:
         | 
| 28 | 
            +
                - - '>='
         | 
| 29 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 30 | 
            +
                    version: '1.8'
         | 
| 31 | 
            +
                - - ~>
         | 
| 32 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 33 | 
            +
                    version: 1.8.3
         | 
| 34 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 35 | 
            +
              name: jeweler
         | 
| 36 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 37 | 
            +
                requirements:
         | 
| 38 | 
            +
                - - '>='
         | 
| 39 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 40 | 
            +
                    version: 2.0.1
         | 
| 41 | 
            +
                - - ~>
         | 
| 42 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 43 | 
            +
                    version: 2.0.1
         | 
| 44 | 
            +
              type: :development
         | 
| 45 | 
            +
              prerelease: false
         | 
| 46 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 47 | 
            +
                requirements:
         | 
| 48 | 
            +
                - - '>='
         | 
| 49 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 50 | 
            +
                    version: 2.0.1
         | 
| 51 | 
            +
                - - ~>
         | 
| 52 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 53 | 
            +
                    version: 2.0.1
         | 
| 54 | 
            +
            description: interact with Philips Hue Hub to control your devices
         | 
| 55 | 
            +
            email:
         | 
| 56 | 
            +
            - conor.code@gmail.com
         | 
| 57 | 
            +
            executables:
         | 
| 58 | 
            +
            - hued
         | 
| 59 | 
            +
            extensions: []
         | 
| 60 | 
            +
            extra_rdoc_files:
         | 
| 61 | 
            +
            - README.md
         | 
| 62 | 
            +
            files:
         | 
| 63 | 
            +
            - Gemfile
         | 
| 64 | 
            +
            - Gemfile.lock
         | 
| 65 | 
            +
            - README.md
         | 
| 66 | 
            +
            - Rakefile
         | 
| 67 | 
            +
            - VERSION
         | 
| 68 | 
            +
            - bin/hued
         | 
| 69 | 
            +
            - lib/hued.rb
         | 
| 70 | 
            +
            - resources/api/config
         | 
| 71 | 
            +
            - resources/api/description.xml
         | 
| 72 | 
            +
            homepage: http://github.com/chorankates/hued
         | 
| 73 | 
            +
            licenses:
         | 
| 74 | 
            +
            - MIT
         | 
| 75 | 
            +
            metadata: {}
         | 
| 76 | 
            +
            post_install_message: 
         | 
| 77 | 
            +
            rdoc_options: []
         | 
| 78 | 
            +
            require_paths:
         | 
| 79 | 
            +
            - lib
         | 
| 80 | 
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         | 
| 81 | 
            +
              requirements:
         | 
| 82 | 
            +
              - - '>='
         | 
| 83 | 
            +
                - !ruby/object:Gem::Version
         | 
| 84 | 
            +
                  version: '0'
         | 
| 85 | 
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 86 | 
            +
              requirements:
         | 
| 87 | 
            +
              - - '>='
         | 
| 88 | 
            +
                - !ruby/object:Gem::Version
         | 
| 89 | 
            +
                  version: '0'
         | 
| 90 | 
            +
            requirements: []
         | 
| 91 | 
            +
            rubyforge_project: 
         | 
| 92 | 
            +
            rubygems_version: 2.2.2
         | 
| 93 | 
            +
            signing_key: 
         | 
| 94 | 
            +
            specification_version: 4
         | 
| 95 | 
            +
            summary: Philips Hue HTTP API bindings
         | 
| 96 | 
            +
            test_files: []
         |