class YeelightCli::Bulb
A bulb wrapper rubocop:disable ClassLength
Constants
- BaseError
- BlankIdError
- BlankLocationError
- ResponseError
- UnsupportedActionError
- WrongDataFormatError
Attributes
id[RW]
logger[RW]
name[R]
specifications[RW]
state[RW]
uri[RW]
Public Class Methods
initialize_from_package(package_body)
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 453 def self.initialize_from_package(package_body) lines = package_body.lines _status_line = lines.shift data = lines .map { |line| line.strip.split(': ', 2) } .select { |processed_line| processed_line.count == 2 } .to_h .symbolize_keys new(data) end
new( data, socket_client: nil, color_processor: ColorProcessor, logger: initialize_default_logger, state_caching: true, args_validator: Bulb::ArgsValidator )
click to toggle source
rubocop:disable ParameterLists
# File lib/yeelight_cli/bulb.rb, line 20 def initialize( data, socket_client: nil, color_processor: ColorProcessor, logger: initialize_default_logger, state_caching: true, args_validator: Bulb::ArgsValidator ) @logger = logger @logger.debug "Initializing new object with data=#{data}" @args_validator = args_validator @args_validator.check_initial_data!(data) initialize_variables_from(data) @state_caching = state_caching fill_state_with(data) if state_caching? @socket_client = socket_client || TCPSocketClient.new(@uri.host, @uri.port) @color_processor = color_processor end
Public Instance Methods
<=>(other)
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 57 def <=>(other) name <=> other.name end
==(other)
click to toggle source
rubocop:enable ParameterLists
# File lib/yeelight_cli/bulb.rb, line 46 def ==(other) return false unless other.is_a?(self.class) id == other.id end
Also aliased as: eql?
adjust(action, prop)
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 375 def adjust(action, prop) @args_validator.check_adjust_action!(action) @args_validator.check_adjust_prop!(prop) perform(:set_adjust, [action, prop]) reload_state! if state_caching? [action, prop] end
adjust_brightness(percentage, duration = 0)
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 385 def adjust_brightness(percentage, duration = 0) @args_validator.check_percentage!(percentage) @args_validator.check_duration!(duration) perform(:adjust_bright, [percentage, duration]) reload_state! if state_caching? off? ? 0 : brightness end
adjust_color(percentage, duration = 0)
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 405 def adjust_color(percentage, duration = 0) @args_validator.check_percentage!(percentage) @args_validator.check_duration!(duration) perform(:adjust_color, [percentage, duration]) reload_state! if state_caching? rgb end
adjust_ct(percentage, duration = 0)
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 395 def adjust_ct(percentage, duration = 0) @args_validator.check_percentage!(percentage) @args_validator.check_duration!(duration) perform(:adjust_ct, [percentage, duration]) reload_state! if state_caching? color_temperature end
brightness()
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 181 def brightness get_prop(:bright).to_i end
brightness=(brightness = 100)
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 174 def brightness=(brightness = 100) @args_validator.check_brightness!(brightness) perform(:set_bright, [brightness, :sudden, 0]) set_prop(:bright, brightness) end
brightness_character()
click to toggle source
rubocop:disable MethodLength
# File lib/yeelight_cli/bulb.rb, line 107 def brightness_character return 'x' if off? case brightness when 100 '●' when 40..99 '◕' when 10..39 '◑' else '○' end end
cancel_delayed_shutdown!()
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 364 def cancel_delayed_shutdown! perform(:cron_del, [0]) return true if !state_caching? || @shutdown_thread.blank? @shutdown_thread.kill @shutdown_thread = nil @logger.info 'The thread to update the power state has been killed' true end
color_mode()
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 206 def color_mode get_prop(:color_mode).to_i end
color_mode_name()
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 210 def color_mode_name return :rgb if rgb_color_mode? return :temperature if temperature_color_mode? return :hsv if hsv_color_mode? end
color_temperature()
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 248 def color_temperature get_prop(:ct).to_i end
color_temperature=(color_temperature = 6500)
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 240 def color_temperature=(color_temperature = 6500) @args_validator.check_color_temperature!(color_temperature) perform(:set_ct_abx, [color_temperature, :sudden, 0]) set_prop(:color_mode, 2) set_prop(:ct, color_temperature) end
current_color_in_rgb()
click to toggle source
rubocop:enable MethodLength
# File lib/yeelight_cli/bulb.rb, line 123 def current_color_in_rgb return 0x888888 if off? case color_mode_name when :hsv @color_processor.huesat_to_rgb(hue, sat) when :temperature @color_processor.color_temperature_to_rgb(color_temperature) else rgb end end
default!()
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 343 def default! perform :set_default end
delayed_shutdown()
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 360 def delayed_shutdown perform(:cron_get, [0]).try(:first).try(:[], 'delay') end
delayed_shutdown_after(minutes)
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 347 def delayed_shutdown_after(minutes) @args_validator.check_timeout!(minutes) return cancel_delayed_shutdown! if minutes.zero? perform(:cron_add, [0, minutes]) start_shutdown_thread_with(minutes * 60) if state_caching? minutes end
Also aliased as: delayed_shutdown=
get_prop(param)
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 74 def get_prop(param) return @state[param] if state_caching? && @state[param] load_props(param)[param] end
group_name(level = 1)
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 85 def group_name(level = 1) return unless level.positive? chunks = name.split('/') return unless chunks.count > level chunks[level - 1] end
hash()
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 53 def hash id.hash end
hsv_color_mode?()
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 224 def hsv_color_mode? color_mode == 3 end
hue()
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 283 def hue get_prop(:hue).to_i end
hue=(hue = 359)
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 265 def hue=(hue = 359) @args_validator.check_hue!(hue) sat = get_prop(:sat) || 100 perform(:set_hsv, [hue, sat, :smooth, 0]) set_prop(:color_mode, 3) set_prop(:hue, hue.to_i) end
load_props(*params)
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 292 def load_props(*params) props = perform(:get_prop, params) params.zip(props).to_h end
name=(name)
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 159 def name=(name) perform(:set_name, [name]) @name = name end
off?()
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 144 def off? !on? end
on?()
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 140 def on? get_prop(:power) == 'on' end
power()
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 202 def power get_prop(:power) end
power=(state = :on)
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 195 def power=(state = :on) @args_validator.check_power_state!(state) perform(:set_power, [state, :sudden, 0]) set_prop(:power, state.to_s) end
random_color!(duration = 0)
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 338 def random_color!(duration = 0) random_color = Random.new.rand(0xffffff) set_rgb(random_color, duration) end
reload_state!()
click to toggle source
rubocop:disable RescueModifier
# File lib/yeelight_cli/bulb.rb, line 298 def reload_state! return false unless state_caching? @logger.info 'Reloading state' actual_props = load_props(*@state.keys) actual_props.each do |prop_key, prop_value| casted_prop_value = Integer(prop_value) rescue nil value = casted_prop_value || prop_value @state[prop_key] = value if value.present? end @state end
rgb()
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 334 def rgb get_prop(:rgb).to_i end
rgb=(rgb_value = 0xffffff)
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 326 def rgb=(rgb_value = 0xffffff) @args_validator.check_rgb!(rgb_value) perform(:set_rgb, [rgb_value, :smooth, 0]) set_prop(:color_mode, 1) set_prop(:rgb, rgb_value) end
rgb_color_mode?()
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 216 def rgb_color_mode? color_mode == 1 end
room()
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 94 def room group_name(1) end
sat()
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 287 def sat get_prop(:sat).to_i @state[:sat] ||= get_prop(:sat).to_i end
sat=(sat = 100)
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 274 def sat=(sat = 100) @args_validator.check_sat!(sat) hue = get_prop(:hue) || 359 perform(:set_hsv, [hue, sat, :smooth, 0]) set_prop(:color_mode, 3) set_prop(:sat, sat.to_i) end
set_brightness(brightness = 100, duration = 0)
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 164 def set_brightness(brightness = 100, duration = 0) @args_validator.check_brightness!(brightness) @args_validator.check_duration!(duration) effect = duration.positive? ? :smooth : :sudden perform(:set_bright, [brightness, effect, duration]) set_prop(:bright, brightness) end
set_color_temperature(color_temperature = 6500, duration = 0)
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 228 def set_color_temperature(color_temperature = 6500, duration = 0) color_temperature = color_temperature.to_i @args_validator.check_color_temperature!(color_temperature) @args_validator.check_duration!(duration) effect = duration.positive? ? :smooth : :sudden perform(:set_ct_abx, [color_temperature, effect, duration]) set_prop(:color_mode, 2) set_prop(:ct, color_temperature) end
set_huesat(hue = 359, sat = 100, duration = 0)
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 252 def set_huesat(hue = 359, sat = 100, duration = 0) @args_validator.check_hue!(hue) @args_validator.check_sat!(sat) @args_validator.check_duration!(duration) effect = duration.positive? ? :smooth : :sudden perform(:set_hsv, [hue, sat, effect, duration]) set_prop(:color_mode, 3) [set_prop(:hue, hue.to_i), set_prop(:sat, sat.to_i)] end
set_music(action, host, port)
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 442 def set_music(action, host, port) @args_validator.check_music_action!(action) @args_validator.check_host!(host) @args_validator.check_port!(port) action_code = action == :on ? 1 : 0 perform(:set_music, [action_code, host, port]) action == :on end
set_power(state = :on, duration = 0)
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 185 def set_power(state = :on, duration = 0) @args_validator.check_duration!(duration) @args_validator.check_power_state!(state) effect = duration.positive? ? :smooth : :sudden perform(:set_power, [state, effect, duration]) set_prop(:power, state.to_s) end
set_prop(param, value)
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 80 def set_prop(param, value) @state[param] = value if state_caching? value end
set_rgb(rgb_value = 0xffffff, duration = 0)
click to toggle source
rubocop:enable RescueModifier
# File lib/yeelight_cli/bulb.rb, line 316 def set_rgb(rgb_value = 0xffffff, duration = 0) @args_validator.check_rgb!(rgb_value) @args_validator.check_duration!(rgb_value) effect = duration.positive? ? :smooth : :sudden perform(:set_rgb, [rgb_value, effect, duration]) set_prop(:color_mode, 1) set_prop(:rgb, rgb_value) end
start_cf(count, action, expression)
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 415 def start_cf(count, action, expression) @args_validator.check_cf_count!(count) @args_validator.check_cf_action!(action) @args_validator.check_cf_expression!(expression) exp_array = expression.is_a?(Array) ? expression : expression.split(',') cancel_cf_thread! if state_caching? perform(:start_cf, [count, action, expression]) start_cf_thread(count, exp_array) if state_caching? && count != 0 true end
state_caching?()
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 102 def state_caching? @state_caching == true end
stop_cf()
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 431 def stop_cf perform :stop_cf return true unless state_caching? reload_state! cancel_cf_thread! true end
support?(method)
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 136 def support?(method) @specifications.include?(method.to_s) || method.to_s == 'set_name' end
temperature_color_mode?()
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 220 def temperature_color_mode? color_mode == 2 end
to_icon()
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 98 def to_icon Paint[brightness_character, current_color_in_rgb.to_s(16)] end
to_s()
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 61 def to_s shutdown_timer = delayed_shutdown shutdown_string = if shutdown_timer Paint[" shutdown_after=#{delayed_shutdown}", 'ff4444'] else '' end "<YeelightCli::Bulb id=#{id} name=#{name} "\ "icon=#{to_icon}#{shutdown_string}>" end
toggle!()
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 148 def toggle! perform :toggle return get_prop(:power) unless state_caching? new_power_state = on? ? 'off' : 'on' set_prop(:power, new_power_state) new_power_state end
Private Instance Methods
calculate_general_duration_from(count, exp_array)
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 508 def calculate_general_duration_from(count, exp_array) res = Array .new(count) .map.with_index { |_, i| exp_array[(i * 4) % exp_array.count].to_i } .sum @logger.debug "The calculated duraion for cf with count=#{count}, "\ "exp_array=#{exp_array} is #{res}" res end
cancel_cf_thread!()
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 534 def cancel_cf_thread! return false if !state_caching? || @cf_thread.blank? @cf_thread.kill @cf_thread = nil @logger.info 'The cf thread to actualize the state has been killed' end
fill_state_with(data)
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 476 def fill_state_with(data) return false unless state_caching? new_state = {} @logger.debug "Filling state with data=#{data}" %i[bright color_mode ct rgb hue sat].each do |prop| new_state[prop] = data.delete(prop).to_i end # the state includes power, bright, color_mode, ct, rgb, hue, sat, name @state = data.merge(new_state) @logger.debug "The state now is #{@state}" @state end
initialize_default_logger()
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 558 def initialize_default_logger logger = Logger.new(STDOUT) logger.level = Logger::WARN logger end
initialize_variables_from(data)
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 468 def initialize_variables_from(data) @id = data.delete(:id).to_i(16) @uri = URI(data.delete(:Location)) @model = data.delete(:model) @name = data.delete(:name) @specifications = data.delete(:support) end
perform(method, params = [])
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 494 def perform(method, params = []) raise UnsupportedActionError unless support?(method) json = JSON.generate(id: 1, method: method, params: params) + "\r\n" @logger.debug "Socket request: #{json}" response = @socket_client.request(json) @logger.debug "Socket response: #{response}" result = response['result'] raise ResponseError unless result result end
start_cf_thread(count, exp_array)
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 520 def start_cf_thread(count, exp_array) return false unless state_caching? timeout = calculate_general_duration_from(count, exp_array).to_f / 1000 @cf_thread = Thread.new do sleep timeout reload_state! end @logger.info 'The cf thread to actualize the state with '\ "timeout=#{timeout} has been created" end
start_shutdown_thread_with(timeout)
click to toggle source
# File lib/yeelight_cli/bulb.rb, line 543 def start_shutdown_thread_with(timeout) return false unless state_caching? @shutdown_thread = Thread.new do sleep timeout @state[:power] = 'off' @logger.info 'The power state has been changed to "off"' end @logger.info 'A thread to update the power state with '\ "timeout=#{timeout} has been created" timeout end