class WSLight::Strip

Controls the led strip

Constants

FRAMES_PER_SECOND
FULL_LENGTH
LENGTH
SPECIAL_SETS
TIMEOUT

SPECIAL_SETS = [

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

].freeze

TYPE
WEATHER_URL

Attributes

current_set[RW]
debug[RW]
direction[RW]
last_event[RW]
state[RW]

Public Class Methods

new() click to toggle source
# 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

Public Instance Methods

animate(animation) click to toggle source
# 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) click to toggle source
# 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_timer() click to toggle source
# 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_set() click to toggle source
# 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?() click to toggle source
# File lib/ws_light/strip.rb, line 177
def night?
  time = Time.now
  time.hour > 22 || time.hour < 6
end
off(direction = nil) click to toggle source
# 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) click to toggle source
# 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_test() click to toggle source
# 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) click to toggle source
# 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
shutdown() click to toggle source
# File lib/ws_light/strip.rb, line 182
def shutdown
  write([0, 0, 0] * FULL_LENGTH)
end
timeout?() click to toggle source
# File lib/ws_light/strip.rb, line 201
def timeout?
  @last_event < (Time.now - TIMEOUT)
end
write(data) click to toggle source
# File lib/ws_light/strip.rb, line 205
def write(data)
  @spi.xfer(txdata: data)
end