Class: LIFX::Light
- Inherits:
-
Object
- Object
- LIFX::Light
- Includes:
- LightTarget, Seen
- Defined in:
- lib/lifx/light.rb
Overview
LIFX::Light represents a Light device
Defined Under Namespace
Classes: LabelTooLong
Constant Summary collapse
- MAX_LABEL_LENGTH =
32
Constants included from LightTarget
LIFX::LightTarget::MSEC_PER_SEC, LIFX::LightTarget::NSEC_IN_SEC
Instance Attribute Summary collapse
-
#context ⇒ NetworkContext
readonly
NetworkContext the Light belongs to.
-
#id ⇒ String
readonly
Device ID.
Instance Method Summary collapse
-
#<=>(other) ⇒ -1, ...
Compare current Light to another light.
-
#add_hook(payload_class, hook_arg = nil, &hook_block) ⇒ void
private
Adds a block to be run when a payload of class
payload_classis received. -
#add_tag(tag) ⇒ Light
Add tag to the Light.
-
#color(refresh: false, fetch: true) ⇒ Color
Returns the color of the device.
-
#handle_message(message, ip, transport) ⇒ Object
private
Handles updating the internal state of the Light from incoming protocol messages.
-
#initialize(context:, id:, site_id: nil, label: nil) ⇒ Light
constructor
A new instance of Light.
-
#label(refresh: false, fetch: true) ⇒ String
Returns the label of the light.
-
#last_downtime ⇒ Float
private
Return device last downtime.
-
#latency ⇒ Float
Pings the device and measures response time.
-
#mesh_firmware(fetch: true) ⇒ Hash
private
Returns the mesh firmware details.
-
#mesh_info ⇒ Hash
private
Returns mesh network info.
-
#off?(refresh: false, fetch: true) ⇒ Boolean
Returns true if device is off.
-
#on?(refresh: false, fetch: true) ⇒ Boolean
Returns true if device is on.
-
#power(refresh: false, fetch: true) ⇒ :unknown, ...
Light power state.
-
#remove_hook(payload_class, hook) ⇒ void
private
Removes a hook added by #add_hook.
-
#remove_tag(tag) ⇒ Light
Remove tag from the Light.
-
#send_message(payload, acknowledge: true) ⇒ Light
Queues a message to be sent the Light.
-
#send_message!(payload, wait_for:, wait_timeout: 3, timeout_exception: Timeout::Error, &block) ⇒ Object
Queues a message to be sent to the Light and waits for a response.
-
#set_label(label) ⇒ Light
Sets the label of the light.
-
#set_power!(level) ⇒ Light, LightCollection
Set the power state to
levelsynchronously. -
#site_id ⇒ String
private
Returns the
site_idthe Light belongs to. -
#tags ⇒ Array<String>
Returns the tags that are associated with the Light.
-
#tags_field ⇒ Integer
private
Returns the tags uint64 bitfield for protocol use.
-
#temperature ⇒ Float
Returns the temperature of the device.
-
#time ⇒ Time
Returns the local time of the light.
-
#time_delta ⇒ Float
Returns the difference between the device time and time on the current machine Positive values means device time is further in the future.
-
#to_s ⇒ String
(also: #inspect)
Returns a nice string representation of the Light.
-
#turn_off! ⇒ Light, LightCollection
Turns the light(s) off synchronously.
-
#turn_on! ⇒ Light, LightCollection
Turns the light(s) on synchronously.
-
#uptime ⇒ Float
private
Return device uptime.
-
#version ⇒ Hash
private
Returns version info.
-
#wifi_firmware(fetch: true) ⇒ Hash
private
Returns the wifi firmware details.
-
#wifi_info ⇒ Hash
private
Returns wifi network info.
Methods included from LightTarget
#half_sine, #pulse, #reboot!, #refresh, #saw, #set_color, #set_power, #set_site_id, #set_time, #set_waveform, #sine, #triangle, #turn_off, #turn_on
Methods included from Seen
#last_seen, #seconds_since_seen
Constructor Details
#initialize(context:, id:, site_id: nil, label: nil) ⇒ Light
Returns a new instance of Light.
25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/lifx/light.rb', line 25 def initialize(context:, id:, site_id: nil, label: nil) @context = context @id = id @site_id = site_id @label = label @power = nil = Hash.new { |h, k| h[k] = [] } @context.register_device(self) = ConditionVariable.new add_hooks end |
Instance Attribute Details
#context ⇒ NetworkContext (readonly)
Returns NetworkContext the Light belongs to.
16 17 18 |
# File 'lib/lifx/light.rb', line 16 def context @context end |
#id ⇒ String (readonly)
Returns Device ID.
19 20 21 |
# File 'lib/lifx/light.rb', line 19 def id @id end |
Instance Method Details
#<=>(other) ⇒ -1, ...
Compare current Light to another light
338 339 340 341 |
# File 'lib/lifx/light.rb', line 338 def <=>(other) raise ArgumentError.new("Comparison of #{self} with #{other} failed") unless other.is_a?(LIFX::Light) [label, id, 0] <=> [other.label, other.id, 0] end |
#add_hook(payload_class, hook_arg = nil, &hook_block) ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Adds a block to be run when a payload of class payload_class is received
56 57 58 59 60 61 62 |
# File 'lib/lifx/light.rb', line 56 def add_hook(payload_class, hook_arg = nil, &hook_block) hook = block_given? ? hook_block : hook_arg if !hook || !hook.is_a?(Proc) raise "MUst pass a proc either as an argument or a block" end [payload_class] << hook end |
#add_tag(tag) ⇒ Light
Add tag to the Light
309 310 311 312 |
# File 'lib/lifx/light.rb', line 309 def add_tag(tag) context.add_tag_to_device(tag: tag, device: self) self end |
#color(refresh: false, fetch: true) ⇒ Color
Returns the color of the device.
77 78 79 80 81 |
# File 'lib/lifx/light.rb', line 77 def color(refresh: false, fetch: true) @color = nil if refresh (Protocol::Light::Get.new, wait_for: Protocol::Light::Get) if fetch && !@color @color end |
#handle_message(message, ip, transport) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Handles updating the internal state of the Light from incoming protocol messages.
41 42 43 44 45 46 47 48 49 |
# File 'lib/lifx/light.rb', line 41 def (, ip, transport) payload = .payload [payload.class].each do |hook| hook.call(payload) end .broadcast seen! end |
#label(refresh: false, fetch: true) ⇒ String
Returns the label of the light
87 88 89 90 91 |
# File 'lib/lifx/light.rb', line 87 def label(refresh: false, fetch: true) @label = nil if refresh (Protocol::Light::Get.new, wait_for: Protocol::Light::Get) if fetch && !@label @label end |
#last_downtime ⇒ Float
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Return device last downtime
277 278 279 280 281 282 |
# File 'lib/lifx/light.rb', line 277 def last_downtime (Protocol::Device::GetInfo.new, wait_for: Protocol::Device::StateInfo) do |payload| payload.downtime.to_f / NSEC_IN_SEC end end |
#latency ⇒ Float
Pings the device and measures response time.
183 184 185 186 187 |
# File 'lib/lifx/light.rb', line 183 def latency start = Time.now.to_f (Protocol::Device::GetTime.new, wait_for: Protocol::Device::StateTime) Time.now.to_f - start end |
#mesh_firmware(fetch: true) ⇒ Hash
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns the mesh firmware details
192 193 194 195 196 197 198 199 |
# File 'lib/lifx/light.rb', line 192 def mesh_firmware(fetch: true) @mesh_firmware ||= begin (Protocol::Device::GetMeshFirmware.new, wait_for: Protocol::Device::StateMeshFirmware) do |payload| Firmware.new(payload) end if fetch end end |
#mesh_info ⇒ Hash
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns mesh network info
225 226 227 228 229 230 231 232 233 234 |
# File 'lib/lifx/light.rb', line 225 def mesh_info (Protocol::Device::GetMeshInfo.new, wait_for: Protocol::Device::StateMeshInfo) do |payload| { signal: payload.signal, # This is in Milliwatts tx: payload.tx, rx: payload.rx } end end |
#off?(refresh: false, fetch: true) ⇒ Boolean
Returns true if device is off
145 146 147 |
# File 'lib/lifx/light.rb', line 145 def off?(refresh: false, fetch: true) power(refresh: refresh, fetch: fetch) == :off end |
#on?(refresh: false, fetch: true) ⇒ Boolean
Returns true if device is on
139 140 141 |
# File 'lib/lifx/light.rb', line 139 def on?(refresh: false, fetch: true) power(refresh: refresh, fetch: fetch) == :on end |
#power(refresh: false, fetch: true) ⇒ :unknown, ...
Returns Light power state.
152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/lifx/light.rb', line 152 def power(refresh: false, fetch: true) @power = nil if refresh (Protocol::Device::GetPower.new, wait_for: Protocol::Device::StatePower) if !@power && fetch case @power when nil :unknown when 0 :off else :on end end |
#remove_hook(payload_class, hook) ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Removes a hook added by #add_hook
69 70 71 |
# File 'lib/lifx/light.rb', line 69 def remove_hook(payload_class, hook) [payload_class].delete(hook) end |
#remove_tag(tag) ⇒ Light
Remove tag from the Light
317 318 319 320 |
# File 'lib/lifx/light.rb', line 317 def remove_tag(tag) context.remove_tag_from_device(tag: tag, device: self) self end |
#send_message(payload, acknowledge: true) ⇒ Light
Queues a message to be sent the Light
347 348 349 350 |
# File 'lib/lifx/light.rb', line 347 def (payload, acknowledge: true) context.(target: Target.new(device_id: id, site_id: @site_id), payload: payload, acknowledge: acknowledge) self end |
#send_message!(payload, wait_for:, wait_timeout: 3, timeout_exception: Timeout::Error, &block) ⇒ Object
Queues a message to be sent to the Light and waits for a response
359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 |
# File 'lib/lifx/light.rb', line 359 def (payload, wait_for:, wait_timeout: 3, timeout_exception: Timeout::Error, &block) if Thread.current[:sync_enabled] raise "Cannot use synchronous methods inside a sync block" end result = nil begin block ||= Proc.new { |msg| true } proc = -> (payload) { result = block.call(payload) } add_hook(wait_for, proc) try_until -> { result }, signal: , timeout_exception: timeout_exception do (payload) end result ensure remove_hook(wait_for, proc) end end |
#set_label(label) ⇒ Light
Sets the label of the light
100 101 102 103 104 105 106 107 108 |
# File 'lib/lifx/light.rb', line 100 def set_label(label) if label.length > MAX_LABEL_LENGTH raise LabelTooLong.new("Label length must be below or equal to #{MAX_LABEL_LENGTH}") end while self.label != label (Protocol::Device::SetLabel.new(label: label), wait_for: Protocol::Device::StateLabel) end self end |
#set_power!(level) ⇒ Light, LightCollection
Set the power state to level synchronously.
This method cannot guarantee the message was received.
114 115 116 117 118 119 120 121 122 123 |
# File 'lib/lifx/light.rb', line 114 def set_power!(level) (Protocol::Device::SetPower.new(level: level), wait_for: Protocol::Device::StatePower) do |payload| if level.zero? payload.level == 0 else payload.level > 0 end end self end |
#site_id ⇒ String
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns the site_id the Light belongs to.
287 288 289 290 291 292 293 294 |
# File 'lib/lifx/light.rb', line 287 def site_id if @site_id.nil? # FIXME: This is ugly. context.routing_manager.routing_table.site_id_for_device_id(id) else @site_id end end |
#tags ⇒ Array<String>
Returns the tags that are associated with the Light
324 325 326 |
# File 'lib/lifx/light.rb', line 324 def context.(self) end |
#tags_field ⇒ Integer
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns the tags uint64 bitfield for protocol use.
299 300 301 302 303 304 |
# File 'lib/lifx/light.rb', line 299 def try_until -> { } do (Protocol::Device::GetTags.new) end end |
#temperature ⇒ Float
Returns the temperature of the device
215 216 217 218 219 220 |
# File 'lib/lifx/light.rb', line 215 def temperature (Protocol::Light::GetTemperature.new, wait_for: Protocol::Light::StateTemperature) do |payload| payload.temperature / 100.0 end end |
#time ⇒ Time
Returns the local time of the light
167 168 169 170 171 |
# File 'lib/lifx/light.rb', line 167 def time (Protocol::Device::GetTime.new, wait_for: Protocol::Device::StateTime) do |payload| Time.at(payload.time.to_f / NSEC_IN_SEC) end end |
#time_delta ⇒ Float
Returns the difference between the device time and time on the current machine Positive values means device time is further in the future.
176 177 178 179 |
# File 'lib/lifx/light.rb', line 176 def time_delta device_time = time delta = device_time - Time.now end |
#to_s ⇒ String Also known as: inspect
Returns a nice string representation of the Light
330 331 332 |
# File 'lib/lifx/light.rb', line 330 def to_s %Q{#<LIFX::Light id=#{id} label=#{label(fetch: false)} power=#{power(fetch: false)}>}.force_encoding(Encoding.default_external) end |
#turn_off! ⇒ Light, LightCollection
Turns the light(s) off synchronously
133 134 135 |
# File 'lib/lifx/light.rb', line 133 def turn_off! set_power!(0) end |
#turn_on! ⇒ Light, LightCollection
Turns the light(s) on synchronously
127 128 129 |
# File 'lib/lifx/light.rb', line 127 def turn_on! set_power!(1) end |
#uptime ⇒ Float
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Return device uptime
267 268 269 270 271 272 |
# File 'lib/lifx/light.rb', line 267 def uptime (Protocol::Device::GetInfo.new, wait_for: Protocol::Device::StateInfo) do |payload| payload.uptime.to_f / NSEC_IN_SEC end end |
#version ⇒ Hash
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns version info
253 254 255 256 257 258 259 260 261 262 |
# File 'lib/lifx/light.rb', line 253 def version (Protocol::Device::GetVersion.new, wait_for: Protocol::Device::StateVersion) do |payload| { vendor: payload.vendor, product: payload.product, version: payload.version } end end |
#wifi_firmware(fetch: true) ⇒ Hash
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns the wifi firmware details
204 205 206 207 208 209 210 211 |
# File 'lib/lifx/light.rb', line 204 def wifi_firmware(fetch: true) @wifi_firmware ||= begin (Protocol::Device::GetWifiFirmware.new, wait_for: Protocol::Device::StateWifiFirmware) do |payload| Firmware.new(payload) end if fetch end end |
#wifi_info ⇒ Hash
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns wifi network info
239 240 241 242 243 244 245 246 247 248 |
# File 'lib/lifx/light.rb', line 239 def wifi_info (Protocol::Device::GetWifiInfo.new, wait_for: Protocol::Device::StateWifiInfo) do |payload| { signal: payload.signal, # This is in Milliwatts tx: payload.tx, rx: payload.rx } end end |