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
FULL_LENGTH =
320
SPECIAL_SETS =
[
  Set::RainbowSet,
  Set::RandomSet,
  Set::StrawberrySet,
  Set::WatermelonSet,
  Set::SemolinaSet,
  Set::FlowerbedSet
].freeze
TIMEOUT =

SPECIAL_SETS = [

Set::RainSet,
Set::FairSet,
Set::SunnySet,
Set::CloudySet

].freeze

12
WEATHER_URL =
'http://api.openweathermap.org/data/2.5/weather?q=Hannover,de'.freeze
FRAMES_PER_SECOND =
25

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeStrip

Returns a new instance of Strip.



62
63
64
65
66
67
68
69
70
71
72
# File 'lib/ws_light/strip.rb', line 62

def initialize
  @spi = SPI.new(device: '/dev/spidev0.0')
  @spi.speed = 500_000
  self_test
  @listen_thread = Thread.new { loop { check_timer; sleep 0.5; } }
  @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.



34
35
36
# File 'lib/ws_light/strip.rb', line 34

def current_set
  @current_set
end

#debugObject

Returns the value of attribute debug.



34
35
36
# File 'lib/ws_light/strip.rb', line 34

def debug
  @debug
end

#directionObject

Returns the value of attribute direction.



34
35
36
# File 'lib/ws_light/strip.rb', line 34

def direction
  @direction
end

#last_eventObject

Returns the value of attribute last_event.



34
35
36
# File 'lib/ws_light/strip.rb', line 34

def last_event
  @last_event
end

#stateObject

Returns the value of attribute state.



34
35
36
# File 'lib/ws_light/strip.rb', line 34

def state
  @state
end

Instance Method Details

#animate(animation) ⇒ Object



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/ws_light/strip.rb', line 145

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

  animation.frames.times do |i|
    write(animation.frame_data(current_frame = i))
    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|
      write(animation.frame_data(current_frame - i - 1))
      sleep(1.0 / animation.frames_per_second) if animation.frames_per_second
    end
    false
  else
    true
  end
end

#animation_for(direction) ⇒ Object



135
136
137
138
139
140
141
142
143
# File 'lib/ws_light/strip.rb', line 135

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

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

#check_timerObject



196
197
198
199
# File 'lib/ws_light/strip.rb', line 196

def check_timer
  write([0, 0, 0] * FULL_LENGTH) if @state == :state_off
  off if timeout?
end

#choose_setObject



124
125
126
127
128
129
130
131
132
133
# File 'lib/ws_light/strip.rb', line 124

def choose_set
  return Set::StarSet.new if night?

  return SPECIAL_SETS.sample.new if rand(8).zero?

  set = Set::GradientSet.new
  set.color_from = Color.random_from_set
  set.color_to = Color.random_from_set
  set
end

#night?Boolean

Returns:

  • (Boolean)


177
178
179
180
# File 'lib/ws_light/strip.rb', line 177

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

#off(direction = nil) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/ws_light/strip.rb', line 100

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



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/ws_light/strip.rb', line 74

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

  set = choose_set

  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



186
187
188
189
190
191
192
193
194
# File 'lib/ws_light/strip.rb', line 186

def self_test
  write([0, 0, 255] * FULL_LENGTH)
  sleep 1
  write([0, 255, 0] * FULL_LENGTH)
  sleep 1
  write([255, 0, 0] * FULL_LENGTH)
  sleep 1
  write([0, 0, 0] * FULL_LENGTH)
end

#show(set, start_frame = 0) ⇒ Object



167
168
169
170
171
172
173
174
175
# File 'lib/ws_light/strip.rb', line 167

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

#shutdownObject



182
183
184
# File 'lib/ws_light/strip.rb', line 182

def shutdown
  write([0, 0, 0] * FULL_LENGTH)
end

#timeout?Boolean

Returns:

  • (Boolean)


201
202
203
# File 'lib/ws_light/strip.rb', line 201

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

#write(data) ⇒ Object



205
206
207
# File 'lib/ws_light/strip.rb', line 205

def write(data)
  @spi.xfer(txdata: data)
end