Class: Huebot::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/huebot/client.rb

Defined Under Namespace

Classes: Bridge

Constant Summary collapse

DISCOVERY_URI =
URI(ENV["HUE_DISCOVERY_API"] || "https://discovery.meethue.com/")
Error =
Class.new(Error)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config = Huebot::CLI::Config.new) ⇒ Client

Returns a new instance of Client.



13
14
15
16
17
# File 'lib/huebot/client.rb', line 13

def initialize(config = Huebot::CLI::Config.new)
  @config = config
  @ip = config["ip"] # NOTE will usually be null
  @username = nil
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



11
12
13
# File 'lib/huebot/client.rb', line 11

def config
  @config
end

Instance Method Details

#bridgesObject



109
110
111
112
113
114
115
116
117
# File 'lib/huebot/client.rb', line 109

def bridges
  req = Net::HTTP::Get.new(DISCOVERY_URI)
  resp = Net::HTTP.start req.uri.host, req.uri.port, {use_ssl: true} do |http|
    http.request req
  end
  JSON.parse(resp.body).map { |x|
    Bridge.new(x.fetch("id"), x.fetch("internalipaddress"))
  }
end

#connectObject



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/huebot/client.rb', line 19

def connect
  if config["ip"]
    @ip = config["ip"]
  elsif config["id"]
    @ip = bridges.detect { |b| b.id == id }&.ip
    return "Unable to find Hue Bridge '#{config["id"]}' on your network" if @ip.nil?
  else
    bridge = bridges.first
    return "Unable to find a Hue Bridge on your network" if bridge.nil?
    config["id"] = bridge.id
    @ip = bridge.ip
  end

  if config["username"]
    if valid_username? config["username"]
      @username = config["username"]
    else
      return "Invalid Hue Bridge username '#{config["username"]}'"
    end
  else
    username, error = register
    return error if error
    config["username"] = @username = username
  end
  nil
end

#get(path) ⇒ Object



52
53
54
55
56
57
58
# File 'lib/huebot/client.rb', line 52

def get(path)
  url = "http://#{@ip}/api"
  url << "/#{@username}" if @username
  url << path
  req = Net::HTTP::Get.new(URI(url))
  req_json req
end

#get!(path) ⇒ Object

Raises:



46
47
48
49
50
# File 'lib/huebot/client.rb', line 46

def get!(path)
  resp, error = get path
  raise Error, error if error
  resp
end

#post(path, body) ⇒ Object



66
67
68
69
70
71
72
73
74
# File 'lib/huebot/client.rb', line 66

def post(path, body)
  url = "http://#{@ip}/api"
  url << "/#{@username}" if @username
  url << path
  req = Net::HTTP::Post.new(URI(url))
  req["Content-Type"] = "application/json"
  req.body = body.to_json
  req_json req
end

#post!(path, body) ⇒ Object

Raises:



60
61
62
63
64
# File 'lib/huebot/client.rb', line 60

def post!(path, body)
  resp, error = post path, body
  raise Error, error if error
  resp
end

#put(path, body) ⇒ Object



82
83
84
85
86
87
88
89
90
# File 'lib/huebot/client.rb', line 82

def put(path, body)
  url = "http://#{@ip}/api"
  url << "/#{@username}" if @username
  url << path
  req = Net::HTTP::Put.new(URI(url))
  req["Content-Type"] = "application/json"
  req.body = body.to_json
  req_json req
end

#put!(path, body) ⇒ Object

Raises:



76
77
78
79
80
# File 'lib/huebot/client.rb', line 76

def put!(path, body)
  resp, error = put path, body
  raise Error, error if error
  resp
end

#req_json(req) ⇒ Object



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/huebot/client.rb', line 92

def req_json(req)
  resp = Net::HTTP.start req.uri.host, req.uri.port, {use_ssl: false} do |http|
    http.request req
  end
  case resp.code.to_i
  when 200..201
    data = JSON.parse(resp.body)
    if data[0] and (error = data[0]["error"])
      return nil, error.fetch("description")
    else
      return data, nil
    end
  else
    raise Error, "Unexpected response from Bridge (#{resp.code}): #{resp.body}"
  end
end