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