lib/ws_light/strip.rb in ws_light-0.3.0 vs lib/ws_light/strip.rb in ws_light-0.4.2
- old
+ new
@@ -1,6 +1,6 @@
-require 'ws2801'
+require 'spi'
require 'ws_light/color'
require 'pp'
require 'date'
require 'json'
require 'open-uri'
@@ -9,19 +9,23 @@
require 'ws_light/animation/slide_right_animation'
require 'ws_light/animation/fade_animation'
require 'ws_light/set/color_set'
require 'ws_light/set/gradient_set'
+require 'ws_light/set/flowerbed_set'
require 'ws_light/set/random_set'
require 'ws_light/set/rainbow_set'
require 'ws_light/set/strawberry_set'
require 'ws_light/set/watermelon_set'
require 'ws_light/set/semolina_set'
require 'ws_light/set/star_set'
+require 'ws_light/set/weather/cloudy_set'
+require 'ws_light/set/weather/fair_set'
+require 'ws_light/set/weather/rain_set'
+require 'ws_light/set/weather/sunny_set'
-
# Ideas
# - Fire?
# Config file
module WSLight
@@ -29,27 +33,44 @@
class Strip
attr_accessor :direction, :last_event, :state, :current_set, :debug
LENGTH = 160
TYPE = :double
+ FULL_LENGTH = 320
+ SPECIAL_SETS = [
+ Set::RainbowSet,
+ Set::RandomSet,
+ Set::StrawberrySet,
+ Set::WatermelonSet,
+ Set::SemolinaSet,
+ Set::FlowerbedSet
+ ].freeze
+
+ # SPECIAL_SETS = [
+ # Set::RainSet,
+ # Set::FairSet,
+ # Set::SunnySet,
+ # Set::CloudySet
+ # ].freeze
+
TIMEOUT = 12
-
- WEATHER_URL = 'http://api.openweathermap.org/data/2.5/weather?q=Hannover,de'
+ WEATHER_URL = 'http://api.openweathermap.org/data/2.5/weather?q=Hannover,de'.freeze
+
FRAMES_PER_SECOND = 25
def initialize
- WS2801.length(Strip::TYPE == :double ? Strip::LENGTH * 2 : Strip::LENGTH)
- WS2801.autowrite(true)
+ @spi = SPI.new(device: '/dev/spidev0.0')
+ @spi.speed = 500_000
self_test
- @listen_thread = Thread.new { while true do check_timer; sleep 0.5; end }
+ @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)
+ @current_set.color = Color.new(0, 0, 0)
end
def on(direction)
@last_event = Time.now
puts "triggered event 'on': #{last_event.to_f} from state #{@state}" if @debug
@@ -59,29 +80,12 @@
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 = choose_set
- set = Set::StarSet.new if night?
-
puts "Set #{set.class}" if @debug
animation = animation_for(direction).new(@current_set, set)
animate(animation)
@@ -115,10 +119,21 @@
end
puts "finished shutting off: #{Time.now.to_f}" if @debug
end
+ 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
+
def animation_for(direction)
return Animation::FadeAnimation if night?
if direction == :direction_left
Animation::SlideLeftAnimation
@@ -130,22 +145,20 @@
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
+ 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|
- WS2801.strip(animation.frame_data(current_frame - i - 1))
- WS2801.write
- sleep (1.0/animation.frames_per_second) if animation.frames_per_second
+ 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
@@ -153,41 +166,44 @@
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
+ write(set.frame_data)
+ sleep 1.0 / FRAMES_PER_SECOND.to_f
i += 1
end
end
def night?
time = Time.now
time.hour > 22 || time.hour < 6
end
def shutdown
- WS2801.set(r: 0, g: 0, b: 0)
+ write([0, 0, 0] * FULL_LENGTH)
end
def self_test
- WS2801.set(r: 0, g: 0, b: 255)
+ write([0, 0, 255] * FULL_LENGTH)
sleep 1
- WS2801.set(r: 0, g: 255, b: 0)
+ write([0, 255, 0] * FULL_LENGTH)
sleep 1
- WS2801.set(r: 255, g: 0, b: 0)
+ write([255, 0, 0] * FULL_LENGTH)
sleep 1
- WS2801.set(r: 0, g: 0, b: 0)
+ write([0, 0, 0] * FULL_LENGTH)
end
def check_timer
- WS2801.set(r: 0, g: 0, b: 0) if @state == :state_off
+ write([0, 0, 0] * FULL_LENGTH) if @state == :state_off
off if timeout?
end
def timeout?
@last_event < (Time.now - TIMEOUT)
+ end
+
+ def write(data)
+ @spi.xfer(txdata: data)
end
end
end