Class: WSLight::Strip

Inherits:
Object
  • Object
show all
Defined in:
lib/ws_light/strip.rb

Overview

Controls the led strip

Constant Summary collapse

LENGTH =
160
TYPE =
:double
TIMEOUT =
12
WEATHER_URL =
'http://api.openweathermap.org/data/2.5/weather?q=Hannover,de'
FRAMES_PER_SECOND =
25

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeStrip

Returns a new instance of Strip.



41
42
43
44
45
46
47
48
49
50
51
# File 'lib/ws_light/strip.rb', line 41

def initialize
  WS2801.length(Strip::TYPE == :double ? Strip::LENGTH * 2 : Strip::LENGTH)
  WS2801.autowrite(true)
  self_test
  @listen_thread = Thread.new { while true do check_timer; sleep 0.5; end }
  @last_event = Time.now - 3600 # set last event to a longer time ago
  @state = :state_off
  @debug = false
  @current_set = Set::ColorSet.new
  @current_set.color = Color.new(0,0,0)
end

Instance Attribute Details

#current_setObject

Returns the value of attribute current_set.



30
31
32
# File 'lib/ws_light/strip.rb', line 30

def current_set
  @current_set
end

#debugObject

Returns the value of attribute debug.



30
31
32
# File 'lib/ws_light/strip.rb', line 30

def debug
  @debug
end

#directionObject

Returns the value of attribute direction.



30
31
32
# File 'lib/ws_light/strip.rb', line 30

def direction
  @direction
end

#last_eventObject

Returns the value of attribute last_event.



30
31
32
# File 'lib/ws_light/strip.rb', line 30

def last_event
  @last_event
end

#stateObject

Returns the value of attribute state.



30
31
32
# File 'lib/ws_light/strip.rb', line 30

def state
  @state
end

Instance Method Details

#animate(animation) ⇒ Object



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/ws_light/strip.rb', line 130

def animate(animation)
  current_frame = 0
  beginning_state = @state

  animation.frames.times do |i|
    WS2801.strip(animation.frame_data(current_frame = i))
    WS2801.write
    sleep (1.0/animation.frames_per_second) if animation.frames_per_second
    break if @state != beginning_state # Reverse shutting off when a new event is triggered
  end

  # This is run when the animation is reversed
  if (current_frame + 1) < animation.frames
    current_frame.times do |i|
      WS2801.strip(animation.frame_data(current_frame - i - 1))
      WS2801.write
      sleep (1.0/animation.frames_per_second) if animation.frames_per_second
    end
    false
  else
    true
  end
end

#animation_for(direction) ⇒ Object



120
121
122
123
124
125
126
127
128
# File 'lib/ws_light/strip.rb', line 120

def animation_for(direction)
  return Animation::FadeAnimation if night?

  if direction == :direction_left
    Animation::SlideLeftAnimation
  else
    Animation::SlideRightAnimation
  end
end

#check_timerObject



184
185
186
187
# File 'lib/ws_light/strip.rb', line 184

def check_timer
  WS2801.set(r: 0, g: 0, b: 0) if @state == :state_off
  off if timeout?
end

#night?Boolean

Returns:

  • (Boolean)


165
166
167
168
# File 'lib/ws_light/strip.rb', line 165

def night?
  time = Time.now
  time.hour > 22 || time.hour < 6
end

#off(direction = nil) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/ws_light/strip.rb', line 96

def off(direction = nil)
  puts "triggered event 'off': #{Time.now.to_f} during state #{@state}" if @debug
  return if @state != :state_on

  @state = :state_shutting_down
  sleep 0.2
  @direction = direction if direction

  set = Set::ColorSet.new
  set.color = Color.by_name :black

  animation = animation_for(@direction).new(@current_set, set)

  if animate(animation)
    @state = :state_off
    @current_set = set
  else
    @state = :state_on
    Thread.new { show(@current_set, animation.frames) }
  end

  puts "finished shutting off: #{Time.now.to_f}" if @debug
end

#on(direction) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/ws_light/strip.rb', line 53

def on(direction)
  @last_event = Time.now
  puts "triggered event 'on': #{last_event.to_f} from state #{@state}" if @debug
  @state = :state_starting_up if @state == :state_shutting_down
  return if @state != :state_off

  puts 'Loading a new set...' if @debug

  @direction = direction
  @state = :state_starting_up

  case rand(100)
  when 0..3
    set = Set::RainbowSet.new
  when 4..6
    set = Set::RandomSet.new
  when 7..9
    set = Set::StrawberrySet.new
  when 10..12
    set = Set::WatermelonSet.new
  when 13..15
    set = Set::SemolinaSet.new
  else
    set = Set::GradientSet.new
    set.color_from = Color.random_from_set
    set.color_to = Color.random_from_set
  end

  set = Set::StarSet.new if night?

  puts "Set #{set.class}" if @debug

  animation = animation_for(direction).new(@current_set, set)

  animate(animation)
  @current_set = set

  @state = :state_on

  # Move show() into background, so we can accept new events on the main thread
  Thread.new { show(@current_set, animation.frames) }
end

#self_testObject



174
175
176
177
178
179
180
181
182
# File 'lib/ws_light/strip.rb', line 174

def self_test
  WS2801.set(r: 0, g: 0, b: 255)
  sleep 1
  WS2801.set(r: 0, g: 255, b: 0)
  sleep 1
  WS2801.set(r: 255, g: 0, b: 0)
  sleep 1
  WS2801.set(r: 0, g: 0, b: 0)
end

#show(set, start_frame = 0) ⇒ Object



154
155
156
157
158
159
160
161
162
163
# File 'lib/ws_light/strip.rb', line 154

def show(set, start_frame = 0)
  current_state = @state
  i = start_frame
  while @state == current_state
    WS2801.strip(set.frame_data)
    WS2801.write
    sleep 1.0/FRAMES_PER_SECOND.to_f
    i += 1
  end
end

#shutdownObject



170
171
172
# File 'lib/ws_light/strip.rb', line 170

def shutdown
  WS2801.set(r: 0, g: 0, b: 0)
end

#timeout?Boolean

Returns:

  • (Boolean)


189
190
191
# File 'lib/ws_light/strip.rb', line 189

def timeout?
  @last_event < (Time.now - TIMEOUT)
end