betabrite 0.0.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. data/.autotest +7 -0
  2. data/EXAMPLES +28 -73
  3. data/History.txt +16 -0
  4. data/Manifest.txt +35 -0
  5. data/{README → README.txt} +58 -52
  6. data/Rakefile +11 -0
  7. data/lib/betabrite.rb +6 -120
  8. data/lib/betabrite/autotest.rb +43 -0
  9. data/lib/betabrite/base.rb +86 -0
  10. data/lib/betabrite/files.rb +4 -0
  11. data/lib/betabrite/files/dots.rb +24 -0
  12. data/lib/betabrite/files/file_dsl.rb +18 -0
  13. data/lib/betabrite/files/string.rb +22 -0
  14. data/lib/betabrite/files/text.rb +122 -0
  15. data/lib/{memory → betabrite}/memory.rb +27 -5
  16. data/lib/betabrite/serial.rb +28 -0
  17. data/lib/{string.rb → betabrite/string.rb} +41 -15
  18. data/lib/betabrite/usb.rb +64 -0
  19. data/script/alloc.rb +21 -0
  20. data/script/clear_memory.rb +16 -0
  21. data/script/client.rb +39 -0
  22. data/script/dots_file.rb +35 -0
  23. data/script/server.rb +12 -0
  24. data/script/sign_test.rb +17 -0
  25. data/script/stock_alloc.rb +81 -0
  26. data/script/stock_client.rb +40 -0
  27. data/script/stockdata.rb +65 -0
  28. data/test/helper.rb +6 -0
  29. data/test/{tc_many_mem.rb → test_many_mem.rb} +6 -10
  30. data/test/{tc_memory.rb → test_memory.rb} +11 -24
  31. data/test/{tc_set_string.rb → test_set_string.rb} +5 -9
  32. data/test/test_string.rb +34 -0
  33. data/test/test_text_file.rb +19 -0
  34. data/test/test_usb_betabrite.rb +94 -0
  35. metadata +94 -60
  36. data/CHANGELOG +0 -10
  37. data/NOTES +0 -29
  38. data/lib/bb_version.rb +0 -3
  39. data/lib/files/dotsfile.rb +0 -24
  40. data/lib/files/stringfile.rb +0 -22
  41. data/lib/files/textfile.rb +0 -114
  42. data/test/bb_override.rb +0 -5
  43. data/test/tc_string.rb +0 -20
  44. data/test/tc_text_file.rb +0 -18
  45. data/test/ts_bb.rb +0 -7
@@ -0,0 +1,43 @@
1
+ require 'betabrite'
2
+
3
+ module Autotest::BetaBrite
4
+ @@first_run = true
5
+
6
+ def self.hook(klass, *args, &block)
7
+ Autotest.add_hook :ran_command do |at|
8
+ if at.results.last =~ /^.* (\d+) failures, (\d+) errors$/
9
+ bb = klass.new(*args) do |sign|
10
+ sign.allocate do |memory|
11
+ memory.text('A', 4096)
12
+ memory.string('0', 128)
13
+ memory.string('1', 128)
14
+ end
15
+
16
+ failures = BetaBrite::String.new("#{$1} failures").red
17
+ errors = BetaBrite::String.new("#{$2} errors").red
18
+ failures.green if $1 == '0'
19
+ errors.green if $2 == '0'
20
+ block.call(failures, errors) if block
21
+
22
+ sign.stringfile('0') do
23
+ print failures
24
+ end
25
+ sign.stringfile('1') do
26
+ print errors
27
+ end
28
+
29
+ if @@first_run
30
+ sign.textfile do
31
+ print stringfile('0')
32
+ print " "
33
+ print stringfile('1')
34
+ end
35
+ end
36
+ end
37
+ bb.write_memory! if @@first_run
38
+ bb.write!
39
+ @@first_run = false if @@first_run
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,86 @@
1
+ module BetaBrite
2
+ VERSION = '1.0.0'
3
+
4
+ class Base
5
+ include BetaBrite::Files
6
+
7
+ # = Synopsis
8
+ # This class assembles all packets (different files) and yields the data
9
+ # that needs to be written back to the caller of the BetaBrite#write method.
10
+ HEADER = [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 ]
11
+ STX = 0x02.chr
12
+ ETX = 0x03.chr
13
+ EOT = 0x04.chr
14
+ ESC = 0x1b.chr
15
+ DLE = 0x10.chr
16
+ STRING = 0x14.chr
17
+ CR = 0x0d.chr
18
+ MEMORY_CODE = "E$"
19
+
20
+ # Beta Brite sign
21
+ SIGN_TYPE = 0x5a.chr
22
+
23
+ attr_accessor :sleep_time
24
+ attr_reader :string_files, :text_files, :dots_files, :memory
25
+
26
+ def initialize
27
+ # Default address is "00" which means broadcast to all signs
28
+ @sign_address = [ 0x30, 0x30 ]
29
+ @string_files = []
30
+ @text_files = []
31
+ @dots_files = []
32
+ @memory = []
33
+
34
+ # This shouldn't change except for unit testing
35
+ @sleep_time = 0
36
+ yield self if block_given?
37
+ end
38
+
39
+ def textfile(label = 'A', &block)
40
+ @text_files << Text.new(label, &block)
41
+ end
42
+
43
+ def stringfile(label, message = nil, &block)
44
+ @string_files << Files::String.new(label, message, &block)
45
+ end
46
+
47
+ def dotsfile(label, rows = nil, columns = nil, picture = nil, &block)
48
+ @dots_files << Dots.new(label, rows, columns, picture,&block)
49
+ end
50
+
51
+ def allocate(&block)
52
+ @memory.push(*(BetaBrite::Memory::Factory.find(&block)))
53
+ end
54
+
55
+ def clear_memory!
56
+ @memory = []
57
+ self.write_memory!
58
+ end
59
+
60
+ # Get the message to be sent to the sign
61
+ def message
62
+ header +
63
+ @text_files.each { |tf| tf.to_s }.join('') +
64
+ @string_files.each { |tf| tf.to_s }.join('') +
65
+ @dots_files.each { |tf| tf.to_s }.join('') +
66
+ tail
67
+ end
68
+
69
+ def memory_message
70
+ "#{header}#{STX}#{MEMORY_CODE}#{@memory.map { |packet| packet.to_s }.join('')}#{tail}"
71
+ end
72
+
73
+ private
74
+
75
+ def header
76
+ header_str = HEADER.collect { |a| a.chr }.join
77
+ "#{header_str}#{SIGN_TYPE}#{@sign_address.collect { |a| a.chr }.join}"
78
+ end
79
+ alias :inspect :header
80
+ public :inspect
81
+
82
+ def tail
83
+ EOT
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,4 @@
1
+ require 'betabrite/files/file_dsl'
2
+ require 'betabrite/files/string'
3
+ require 'betabrite/files/text'
4
+ require 'betabrite/files/dots'
@@ -0,0 +1,24 @@
1
+ module BetaBrite
2
+ module Files
3
+ class Dots
4
+ COMMAND_CODE = 0x49.chr
5
+
6
+ attr_accessor :label, :rows, :columns, :picture
7
+
8
+ def initialize(label, rows, columns, picture, &block)
9
+ @label = label
10
+ @rows = rows
11
+ @columns = columns
12
+ @picture = picture
13
+ instance_eval(&block) if block
14
+ end
15
+
16
+ def to_s
17
+ string = "#{BetaBrite::Base::STX}#{COMMAND_CODE}#{@label.to_s}" +
18
+ "#{sprintf('%02x', @rows)}#{sprintf('%02x', @columns)}" +
19
+ "#{picture.join(BetaBrite::Base::CR)}#{BetaBrite::Base::CR}"
20
+ end
21
+ alias :to_str :to_s
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,18 @@
1
+ module BetaBrite
2
+ module FileDSL
3
+ def print(some_string)
4
+ @message = @message ? @message + some_string : some_string
5
+ end
6
+
7
+ def string(some_string)
8
+ BetaBrite::String.new(some_string)
9
+ end
10
+
11
+ ::BetaBrite::String.constants.each do |constant|
12
+ next unless constant =~ /^[A-Z_]*$/
13
+ define_method(:"#{constant.downcase}") do
14
+ ::BetaBrite::String.const_get(constant)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,22 @@
1
+ module BetaBrite
2
+ module Files
3
+ class String
4
+ COMMAND_CODE = 'G'
5
+
6
+ attr_accessor :label, :message
7
+ include BetaBrite::FileDSL
8
+
9
+ def initialize(label = nil, message = nil, &block)
10
+ @label = label
11
+ @message = message
12
+ instance_eval(&block) if block
13
+ end
14
+
15
+ def to_s
16
+ "#{BetaBrite::Base::STX}#{COMMAND_CODE}#{@label.to_s}" +
17
+ "#{@message.to_s}#{BetaBrite::Base::ETX}"
18
+ end
19
+ alias :to_str :to_s
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,122 @@
1
+ module BetaBrite
2
+ module Files
3
+ class Text
4
+ WRITE = 0x41.chr
5
+ READ = 0x42.chr
6
+
7
+ class Position
8
+ MIDDLE = 0x20.chr
9
+ TOP = 0x22.chr
10
+ BOTTOM = 0x26.chr
11
+ FILL = 0x30.chr
12
+ LEFT = 0x31.chr
13
+ RIGHT = 0x32.chr
14
+ end
15
+
16
+ class Mode
17
+ # Standard Modes
18
+ ROTATE = 0x61.chr # Message travels right to left
19
+ HOLD = 0x62.chr # Message remains stationary
20
+ FLASH = 0x63.chr # Message remains stationary and flashes
21
+ ROLL_UP = 0x65.chr # Message is pushed up by new message
22
+ ROLL_DOWN = 0x66.chr # Message is pushed down by new message
23
+ ROLL_LEFT = 0x67.chr # Message is pushed left by a new message
24
+ ROLL_RIGHT = 0x68.chr # Message is pushed right by a new message
25
+ WIPE_UP = 0x69.chr # Message is wiped over bottom to top
26
+ WIPE_DOWN = 0x6A.chr # Message is wiped over top to bottom
27
+ WIPE_LEFT = 0x6B.chr # Message is wiped over right to left
28
+ WIPE_RIGHT = 0x6C.chr # Message is wiped over left to right
29
+ SCROLL = 0x6D.chr # New message pushes up if 2 line sign
30
+ AUTOMODE = 0x6F.chr # Various modes are called automatically
31
+ ROLL_IN = 0x70.chr # Message pushed toward center of display
32
+ ROLL_OUT = 0x71.chr # Message pushed away from center of display
33
+ WIPE_IN = 0x72.chr # Message wiped over in inward motion
34
+ WIPE_OUT = 0x73.chr # Message wiped over in outward motion
35
+ COMPRESSED_ROTATE = 0x74.chr # Left to right, chars half normal width
36
+ EXPLODE = 0x75.chr # Message flies apart (Alpha 3.0)
37
+ CLOCK = 0x76.chr # Wipe in clockwise direction (Alpha 3.0)
38
+
39
+ # Special Modes
40
+ TWINKLE = 0x6E.chr << 0x30.chr # Message will twinkle
41
+ SPARKLE = 0x6E.chr << 0x31.chr # Message will sparkle
42
+ SNOW = 0x6E.chr << 0x32.chr # Message will snow
43
+ INTERLOCK = 0x6E.chr << 0x33.chr # Message will interlock
44
+ SWITCH = 0x6E.chr << 0x34.chr # Message will switch
45
+ SLIDE = 0x6E.chr << 0x35.chr # Message will slide
46
+ SPRAY = 0x6E.chr << 0x36.chr # Message will spray across
47
+ STARBURST = 0x6E.chr << 0x37.chr # Explodes message to screen
48
+ WELCOME = 0x6E.chr << 0x38.chr # The world "Welcome" is written
49
+ SLOT_MACHINE= 0x6E.chr << 0x39.chr # Slot Machine shows up
50
+ NEWS_FLASH = 0x6E.chr << 0x3A.chr # News flash animation
51
+ TRUMPET = 0x6E.chr << 0x3B.chr # Trumpet animation
52
+ CYCLE_COLORS= 0x6E.chr << 0x43.chr # Color changes from one to another
53
+
54
+ # Special Graphics
55
+ THANK_YOU = [0x6E, 0x53].pack('C*') # "Thank You" in script
56
+ FLAG = [0x6E, 0x54].pack('C*') # American Flag
57
+ NO_SMOKING = [0x6E, 0x55].pack('C*') # No smoking
58
+ DRINK_DRIVE = [0x6E, 0x56].pack('C*') # Don't drink and drive
59
+ ANIMAL_ANIM = [0x6E, 0x57].pack('C*') # Animal animation
60
+ FIREWORKS = [0x6E, 0x58].pack('C*') # Fireworks animation
61
+ BALLOONS = [0x6E, 0x59].pack('C*') # Balloon animation
62
+ CHERRY_BOMB = [0x6E, 0x5A].pack('C*') # A bomb animation or a smile
63
+ SMILE = [0x6E, 0x5A].pack('C*') # A bomb animation or a smile
64
+ end
65
+
66
+ attr_accessor :label, :position, :mode, :message
67
+
68
+ include BetaBrite::FileDSL
69
+
70
+ def initialize(label = 'A', &block)
71
+ @position = Position::MIDDLE
72
+ @label = label
73
+ @message = nil
74
+ @mode = Mode::ROTATE
75
+ instance_eval(&block) if block
76
+ end
77
+
78
+ def stringfile(label)
79
+ "#{BetaBrite::Base::DLE}#{label}"
80
+ end
81
+
82
+ def dotsfile(label)
83
+ "#{BetaBrite::Base::STRING}#{label}"
84
+ end
85
+
86
+ def to_s
87
+ "#{combine}#{checksum(combine)}"
88
+ end
89
+
90
+ def checksum(string)
91
+ total = 0
92
+ 0.upto(string.length - 1) do |i|
93
+ total += string[i]
94
+ end
95
+
96
+ sprintf("%04x", total).upcase
97
+ end
98
+
99
+ Mode.constants.each do |constant|
100
+ next unless constant =~ /^[A-Z_]*$/
101
+ define_method(:"#{constant.downcase}") do
102
+ @mode = Mode.const_get(constant)
103
+ self
104
+ end
105
+ end
106
+
107
+ Position.constants.each do |constant|
108
+ next unless constant =~ /^[A-Z_]*$/
109
+ define_method(:"#{constant.downcase}") do
110
+ @position = Position.const_get(constant)
111
+ self
112
+ end
113
+ end
114
+
115
+ private
116
+ def combine
117
+ "#{BetaBrite::Base::STX}#{WRITE}#{@label}#{BetaBrite::Base::ESC}" +
118
+ "#{@position}#{@mode}#{@message}#{BetaBrite::Base::ETX}"
119
+ end
120
+ end
121
+ end
122
+ end
@@ -1,4 +1,4 @@
1
- class BetaBrite
1
+ module BetaBrite
2
2
  class Memory
3
3
  COMMAND_CODE = "E$"
4
4
  TEXT = 'A'
@@ -7,7 +7,7 @@ class BetaBrite
7
7
  LOCKED = 'L'
8
8
  UNLOCKED = 'U'
9
9
  def self.clear
10
- BetaBrite::STX << COMMAND_CODE
10
+ BetaBrite::Base::STX << COMMAND_CODE
11
11
  end
12
12
 
13
13
  attr_accessor :label, :type, :locked, :size, :time
@@ -27,12 +27,34 @@ class BetaBrite
27
27
  end
28
28
 
29
29
  def format
30
- #BetaBrite::STX << COMMAND_CODE << @label << @type << @locked <<
31
- @label << @type << @locked << @size.upcase << @time
30
+ "#{@label}#{@type}#{@locked}#{@size.upcase}#{@time}"
32
31
  end
33
32
 
34
33
  alias :to_s :format
35
34
 
35
+ class Factory
36
+ attr_reader :memory_list
37
+ class << self
38
+ def find(&block)
39
+ @memory_list = []
40
+ instance_eval(&block)
41
+ @memory_list
42
+ end
43
+
44
+ def string(label, size)
45
+ @memory_list << String.new(label, size)
46
+ end
47
+
48
+ def text(label, size)
49
+ @memory_list << Text.new(label, size)
50
+ end
51
+
52
+ def dots(label, rows, columns)
53
+ @memory_list << Dots.new(label, rows, columns)
54
+ end
55
+ end
56
+ end
57
+
36
58
  class String < Memory
37
59
  def initialize(label, size)
38
60
  super( :label => label,
@@ -69,7 +91,7 @@ class BetaBrite
69
91
 
70
92
  class Clear < Memory
71
93
  def to_s
72
- "#{BetaBrite::STX}#{COMMAND_CODE}"
94
+ "#{BetaBrite::Base::STX}#{COMMAND_CODE}"
73
95
  end
74
96
  end
75
97
  end
@@ -0,0 +1,28 @@
1
+ module BetaBrite
2
+ class Serial < Base
3
+ def initialize(serialport)
4
+ @serialport = serialport
5
+ super()
6
+ end
7
+
8
+ def write_memory!
9
+ sp = SerialPort.new(@serialport, 9600, 8, 1, SerialPort::NONE)
10
+ characters = 0
11
+ memory_message.split(//).each do |chr|
12
+ sleep 1 if characters < 6
13
+ sp.write chr
14
+ characters += 1
15
+ end
16
+ end
17
+
18
+ def write!
19
+ sp = SerialPort.new(@serialport, 9600, 8, 1, SerialPort::NONE)
20
+ characters = 0
21
+ message.split(//).each do |chr|
22
+ sleep 1 if characters < 6
23
+ sp.write chr
24
+ characters += 1
25
+ end
26
+ end
27
+ end
28
+ end
@@ -1,4 +1,4 @@
1
- class BetaBrite
1
+ module BetaBrite
2
2
  # This class encapsulates a string and attributes about the string such as
3
3
  # color, character set, and also contains special characters.
4
4
  class String
@@ -54,6 +54,18 @@ class BetaBrite
54
54
  end
55
55
  attr_accessor :color, :charset, :string
56
56
 
57
+ class << self
58
+ # Break up a string into betabrite strings
59
+ def parse(string)
60
+ string.split(/#{0x1a.chr}/).select { |s|
61
+ s.length > 0
62
+ }.map { |s|
63
+ data = /(.)#{0x1c.chr}Z?([^Z]{6}|[^Z])(.*)$/.match(s)
64
+ new(data[3], :color => data[2], :charset => data[1])
65
+ }
66
+ end
67
+ end
68
+
57
69
  def initialize(string, opts = {})
58
70
  args = { :color => Color::GREEN,
59
71
  :charset => CharSet::SEVEN_HIGH
@@ -64,25 +76,39 @@ class BetaBrite
64
76
  yield self if block_given?
65
77
  end
66
78
 
67
- def to_s
68
- "#{0x1a.chr}#{@charset}#{0x1c.chr}#{@color}#{@string}"
79
+ def +(other)
80
+ self.to_s + other.to_s
69
81
  end
70
82
 
71
- def method_missing(sym, *args)
72
- if args.length > 0 && sym.to_s =~ /^set_(color|charset)$/
73
- class_name = $1
83
+ def rgb(rgb_color)
84
+ self.color = "#{rgb_color}"
85
+ self
86
+ end
74
87
 
75
- const_sym = class_name == 'color' ? :Color : :CharSet
88
+ def to_s
89
+ "#{0x1a.chr}#{@charset}#{0x1c.chr}" +
90
+ (@color.length > 1 ? "Z#{@color}" : "#{@color}") +
91
+ "#{@string}"
92
+ end
93
+ alias :to_str :to_s
94
+
95
+ Color.constants.each do |constant|
96
+ next unless constant =~ /^[A-Z_]*$/
97
+ define_method(:"#{constant.downcase}") do
98
+ @color = Color.const_get(constant)
99
+ self
100
+ end
101
+ define_method(:"#{constant.downcase}?") do
102
+ @color == Color.const_get(constant)
103
+ end
104
+ end
76
105
 
77
- klass = self.class.const_get const_sym
78
- if klass.const_defined? args.first.upcase.to_sym
79
- return send("#{class_name}=".to_sym,
80
- klass.const_get(args.first.upcase.to_sym))
81
- else
82
- raise ArgumentError, "no constant #{args.first.upcase}", caller
83
- end
106
+ CharSet.constants.each do |constant|
107
+ next unless constant =~ /^[A-Z_]*$/
108
+ define_method(:"#{constant.downcase}") do
109
+ @charset = CharSet.const_get(constant)
110
+ self
84
111
  end
85
- super
86
112
  end
87
113
  end
88
114
  end