alphasign 0.2.0 → 0.3.1

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.
data/CHANGELOG CHANGED
@@ -1,4 +1,8 @@
1
- * 0.2.0 (pre)
1
+ * 0.3.0
2
+ Implement fixed set of memory files
3
+ Implement string file write and call
4
+ Add examples/alphaclock.rb usage example
5
+ * 0.2.0
2
6
  write method now takes STRING and HASH of options (this is
3
7
  incompatible with older positional args)
4
8
  move constants into modules
data/Rakefile CHANGED
@@ -19,11 +19,14 @@ Jeweler::Tasks.new do |gem|
19
19
  gem.license = "MIT"
20
20
  gem.summary = "A gem for communicating with LED signs using Alpha Sign Protocol "
21
21
  gem.description = <<-EOF
22
- Alphasign is handles communication with LED signs using the Alpha Sign Protocol.
23
- These include Alpha signs and Betabrite signs by Adaptive Micro Systems, maybe
24
- others too, YMMV.
25
-
26
- Initial release only handles writing text to the sign over rs232 serial port.
22
+ Alphasign is handles communication with LED signs using the
23
+ Alpha Sign Protocol. These include Alpha signs and Betabrite signs
24
+ by Adaptive Micro Systems, maybe others too, YMMV.
25
+
26
+ This release handles writing "text files" and "string" files to the
27
+ sign over rs232 serial port, using a fixed memory configuration. Upcoming
28
+ releases will add "dots picture" files and memory user accesable memory
29
+ file configuration.
27
30
  EOF
28
31
  gem.email = "jon@jonproulx.com"
29
32
  gem.authors = ["Jon Proulx"]
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.3.1
@@ -5,16 +5,19 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{alphasign}
8
- s.version = "0.2.0"
8
+ s.version = "0.3.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Jon Proulx"]
12
12
  s.date = %q{2012-03-10}
13
- s.description = %q{Alphasign is handles communication with LED signs using the Alpha Sign Protocol.
14
- These include Alpha signs and Betabrite signs by Adaptive Micro Systems, maybe
15
- others too, YMMV.
13
+ s.description = %q{Alphasign is handles communication with LED signs using the
14
+ Alpha Sign Protocol. These include Alpha signs and Betabrite signs
15
+ by Adaptive Micro Systems, maybe others too, YMMV.
16
16
 
17
- Initial release only handles writing text to the sign over rs232 serial port.
17
+ This release handles writing "text files" and "string" files to the
18
+ sign over rs232 serial port, using a fixed memory configuration. Upcoming
19
+ releases will add "dots picture" files and memory user accesable memory
20
+ file configuration.
18
21
  }
19
22
  s.email = %q{jon@jonproulx.com}
20
23
  s.extra_rdoc_files = [
@@ -31,6 +34,7 @@ Initial release only handles writing text to the sign over rs232 serial port.
31
34
  "Rakefile",
32
35
  "VERSION",
33
36
  "alphasign.gemspec",
37
+ "examples/alphaclock.rb",
34
38
  "lib/alphasign.rb",
35
39
  "lib/alphasign/format.rb",
36
40
  "lib/alphasign/protocol.rb",
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This program display a clock on your alpha sign
4
+ #
5
+ # It uses a "String" file to hold the formatted time. String files
6
+ # use buffered writes so the display doesn't blank like it does when
7
+ # writing "text" files, but they are limited to 125 bytes each max
8
+ #
9
+ # File types need to be set in memory before they can used, both their
10
+ # type and size. For simplicity we use the default memory setup
11
+ # provided by AlphaSign.new :default is a text file of 256 bytes max
12
+ # and :str2 is a string file of 80 bytes max
13
+ require 'rubygems'
14
+ require 'alphasign'
15
+
16
+ # use second of the two default string files
17
+ stringfile=:str2
18
+ sign=AlphaSign.new
19
+ #seconds to sleep before refresh (signs can only handle updates every
20
+ #2 sec or so)
21
+ interval=5
22
+
23
+ # write our message to the default text file
24
+ #
25
+ # setting color, fixed text, and call our variable string file
26
+ sign.write(AlphaSign::Color[:amber] +
27
+ "the time is " + sign.callstr(stringfile))
28
+
29
+ #update stringfile every interval seconds
30
+ while 1
31
+ time = Time.new
32
+ # put time in our stringfile
33
+ # use fixed width so line doesn't squirm around when digits change
34
+ # this does force left justification rather than center
35
+ # set color, then write time
36
+ sign.writestr(AlphaSign::FixWidth + AlphaSign::Color[:green] +
37
+ time.strftime("%I:%M:%S %p"),stringfile)
38
+ sleep interval - time.sec.modulo(interval)
39
+ end
@@ -12,55 +12,108 @@ class AlphaSign
12
12
  # @param [String] device the serial device the sign is connected to
13
13
  # for now we only speak rs232
14
14
  def initialize (device = "/dev/ttyS0")
15
- @device= device
15
+ @device=SerialPort.new(device, Baud, DataBits, StopBits, Parity)
16
+ @memsync=false
17
+ # default file setup, we should read this from the device, for now
18
+ # just enforce our own & hope no other process is messing with it
19
+ # (that's why we're 0.x.x)
20
+ @files={
21
+ # 256 byte text file always displayed
22
+ :default => AlphaFile.new(:txt, "A", "0100", "FF00"),
23
+ # 80 byte string file
24
+ :str1 => AlphaFile.new(:str, "B", "0050", "0000"),
25
+ # another string file
26
+ :str2 => AlphaFile.new(:str, "C", "0050", "0000"),
27
+ # 16 (0x10) row by 120 (0x78) column dots file in 3 colors
28
+ # not sure why but htat's what "2000" means in this context
29
+ :dot1 => AlphaFile.new(:dot, "D", "1078", "2000"),
30
+ # another dots file
31
+ :dot2 => AlphaFile.new(:dot, "E", "1078", "2000"),
32
+ }
16
33
 
17
34
  # Protocol allows multiple signs on the same port, we are not
18
35
  # going to expose that possibility yet but we will recognize this
19
- # as an instance variable Where "Z" all units, "00" first unit or
20
- # broadcast?
21
- @addr = [ 'Z00' ].pack('A3')
22
-
36
+ # as an instance variable Where "Z" all unit types, "00" is broadcast
37
+ @addr = 'Z00'
38
+
39
+ # write out initial memory config to sign
40
+ writemem
23
41
  end
24
42
 
25
- # we don't have an open yet so this still kludgey and enfoces using
26
- # only :wtxt command as thats the only one we know we can do @param
27
- # @param [STRING] msg the message (text file in Alpha parlance) @see AlphaSign::Format
28
- # for control characters for color, font, etc.
43
+ # This is for writing "txt" files
44
+ # @param [STRING] msg the message (text file in Alpha parlance)
45
+ # @see AlphaSign::Format for control characters for color, font, etc.
29
46
  # @param [HASH] opts the write options
30
47
  # @option opts [Symbol] :position display position @see AlphaSign::Format::Position
31
48
  # @options opts [Symbol] :mode display mode @see AlphaSign::Format::Mode
32
- # @options opts [Integer] or [Nil] :fileLabel file label to write to
33
- # or nil (for comand modes that don't use it) any value from 0x20
34
- # to 0x75 except 0x30 which is reserved
49
+ # @options opts [Symbol] :filename a key from @files hash for a configured :txt file
35
50
  def write (msg, opts={ })
36
- opts[:position]=:middle unless opts[:position] # default to middle position
37
- opts[:mode]=:hold unless opts[:mode] #default to static display
38
- opts[:fileLabel] = 0x41 unless opts[:fileLabel] #this was default in exampelso why not..
39
51
 
40
- raise ArgumentError.new("unkown position #{opts[:position]}") unless Position.has_key?(opts[:position])
41
- raise ArgumentError.new("unkown mode #{opts[:mode]}") unless Mode.has_key?(opts[:mode])
42
- raise ArgumentError.new("invalid File Label specification") unless (opts[:fileLabel] == nil) or ((opts[:fileLabel].kind_of? Integer) and ( opts[:fileLabel] >= 0x20 and opts[:fileLabel] <= 0x75 and opts[:fileLabel] != 0x30))
43
- if opts[:fileLabel] == nil
44
- @filelabel=""
45
- else
46
- @filelabel=[opts[:fileLabel]].pack("C")
47
- end
52
+ # default to middle position
53
+ opts[:position]=:middle unless opts[:position]
54
+
55
+ #default to static display
56
+ opts[:mode]=:hold unless opts[:mode]
48
57
 
49
- @alphaFormat = StartMode + Position[opts[:position]] + Mode[opts[:mode]]
50
- @alphaHeader = StartHeader + @addr + StartCMD[:wtxt] + @filelabel + @alphaFormat
51
- sp=SerialPort.new(@device,
52
- Baud, DataBits, StopBits, Parity)
53
- sp.write @alphaHeader
54
- sp.write msg
55
- sp.write Footer
56
- sp.close
58
+ # sign file to write to, carefule these need to be setup before
59
+ # they can be written to...
60
+ opts[:filename]=:default unless opts [:filename]
61
+ raise ArgumentError.new(":filename must be a preconfigured as a txt file in momory")unless @files[opts[:filename]].type == :txt
62
+
63
+ @format = StartMode + Position[opts[:position]] + Mode[opts[:mode]]
64
+
65
+ rawwrite StartCMD[:wtxt]+ @files[opts[:filename]].label + @format + msg
57
66
  end
67
+
68
+ # write to a string file (this must then be called from a text file
69
+ # for display, but string files are buffered so good for frequent
70
+ # updates without flashing screen like txt files do
71
+ # @param [STRING] msg the message string
72
+ # @see AlphaSign::Format for control characters for color, font, etc.
73
+ # @param [Symbol] filename a key from @files hash for a configure :txt file
74
+ # defaults to ":str1" part of default memory config
75
+
76
+ def writestr (msg,filename=:str1)
77
+ raise ArgumentError.new("filename must be a preconfigured as a string file in momory")unless @files[filename].type == :str
78
+ rawwrite StartCMD[:wstr] + @files[filename].label + msg
79
+ end
58
80
 
59
- #raw serial port for testing this will go away (or atleast become private)
81
+ # this returns code to insert a named string file in txt file
82
+ def callstr (filename=:str1)
83
+ raise ArgumentError.new("filename must be a preconfigured as a string file in momory")unless @files[filename].type == :str
84
+ CallString + @files[filename].label
85
+ end
86
+
87
+ # write a memory config. This is all at once can't add files even if
88
+ # there's unassigned memory, so what ever is written overwrites
89
+ # previous config
90
+ private
91
+ def writemem
92
+ #reset memorystring
93
+ @memorystring=StartCMD[:wfctn]+"$" # "$" is the memory function
94
+ locked="U"
95
+ # rebuld memory string from our current files hash damn this is
96
+ # ugly maybe I do want files to be a Class not a Struct...
97
+ @files.keys.each do |file|
98
+ if @files[file].type == :str
99
+ locked="L"
100
+ else
101
+ locked="U"
102
+ end
103
+ @memorystring=@memorystring +
104
+ @files[file].label +
105
+ FileType[@files[file].type] + locked +
106
+ @files[file].size_spec + @files[file].time_spec
107
+ end
108
+ rawwrite @memorystring
109
+ @memsync=true
110
+ end
111
+
112
+ # the most generic write function
113
+ private
60
114
  def rawwrite (msg)
61
- sp=SerialPort.new(@device,
62
- Baud, DataBits, StopBits, Parity)
63
- sp.write msg
64
- sp.close
115
+ @device.write StartHeader + @addr + msg + Footer
65
116
  end
117
+
118
+
66
119
  end
@@ -89,13 +89,15 @@ module AlphaSign::Format
89
89
  [0x18].pack("C"), [0x19].pack("C") ]
90
90
 
91
91
  #Control Codes (for insertion in text file data)
92
+ CallString = [0x10].pack("C") # call a saved string file, must be followed but filelabel for a string file...
93
+ CallDots = [0x14].pack("C") # call a saved Dots Picture file, must be followed but filelabel for a dots file...
92
94
  DoubleHighOn = [0x05,0x31].pack("C2") # not supported on all units
93
95
  DoubleHighOff= [0x05,0x30].pack("C2") # default
94
96
  TrueDecendersOn = [0x06,0x31].pack("C2") # not supported on all units
95
97
  TrueDecendersOff= [0x06,0x30].pack("C2") # default
96
98
  FlashCharOn = [0x07,0x31].pack("C2") # not supported on all units
97
99
  FlashCharOff= [0x07,0x30].pack("C2") # default
98
-
100
+ FixWidth=[0x1E,0x31].pack("C2") # set fixed width useful for string files
99
101
  Extended=[0x08].pack("C") # access extended ascci of following char for example Extended + "I" would put a degree symbol on the display, see docs
100
102
 
101
103
  TempF=[0x08,0x1C].pack("C2") #only available on incandescent message centers
@@ -30,6 +30,25 @@ module AlphaSign::Protocol
30
30
  :radots => [ 0x02, 'N' ].pack('CA'), # read ALPHAVISON DOTS picture file
31
31
  :bulletin => [ 0x02, 'O' ].pack('CA'), # write bulletin message
32
32
  }
33
+
34
+ # FileType is used in allocating sign memory
35
+ FileType = {
36
+ :txt => "A", # Text file
37
+ :str => "B", # String file
38
+ :dot => "D", # Dots picture file
39
+ }
40
+
41
+ # @param [Synmbol] type file type must be a key of
42
+ # AlphaSign::Protocol::FileType
43
+ # @param [String] label, file label to assign 0x20 to 0x75 (0x30 is
44
+ # reserver for "priority text file"
45
+ # @param [String] file size, 4 char uppercase ASCII hex
46
+ # representation
47
+ # @param [String] time spec, 4 char uppercase ASCII hex
48
+ # representation. First two char represent start time code, second
49
+ # two end time code "FF00" == always, see docs for full spec, it's
50
+ # wierd...
51
+ AlphaFile=Struct.new(:type,:label,:size_spec,:time_spec)
33
52
 
34
53
  Footer = [0x04].pack("C") # EOT end of transmission
35
54
 
@@ -2,37 +2,49 @@ require 'helper'
2
2
 
3
3
  class TestAlphasign < Test::Unit::TestCase
4
4
  def setup
5
+ # this test *will* fail if you don't have serialport on /dev/ttyS0
5
6
  @sign=AlphaSign.new()
6
- @notsign=AlphaSign.new('/dev/null')
7
7
  end
8
8
 
9
9
  def test_simple_write
10
- assert_nil( @sign.write("foo" )) # this test *will* fail if you don't have serialport on /dev/ttyS0
11
- exception=assert_raise(ArgumentError) { @notsign.write("foo" ) }
10
+ assert_nothing_raised { @sign.write("foo" ) }
11
+ exception=assert_raise(ArgumentError) {
12
+ @notsign=AlphaSign.new('/dev/null')
13
+ }
12
14
  assert_equal("not a serial port",exception.message)
13
15
  end
14
16
 
15
17
  def test_write_modes
16
- AlphaSign::Mode.keys.each do |mode|
17
- assert_nil(@sign.write("foo", :mode => mode.to_sym))
18
+ assert_nothing_raised do
19
+ AlphaSign::Mode.keys.each do |mode|
20
+ @sign.write("foo", :mode => mode.to_sym)
21
+ end
18
22
  end
19
23
  end
20
24
 
21
25
  def test_write_positions
22
- AlphaSign::Position.keys.each do |pos|
23
- assert_nil(@sign.write("foo", :position => pos.to_sym))
26
+ assert_nothing_raised do
27
+ AlphaSign::Position.keys.each do |pos|
28
+ @sign.write("foo", :position => pos.to_sym)
29
+ end
24
30
  end
25
31
  end
26
32
 
27
- def test_write_to_file_label
28
- assert_nil(@sign.write("foo", :fileLabel=>nil))
29
- assert_nil(@sign.write("foo", :fileLabel=>0x20))
30
- assert_nil(@sign.write("foo", :fileLabel=>0x29))
31
- assert_nil(@sign.write("foo", :fileLabel=>0x31))
32
- assert_nil(@sign.write("foo", :fileLabel=>0x75))
33
- assert_raise(ArgumentError) {@sign.write("foo", :fileLabel=>"foo")}
34
- assert_raise(ArgumentError) {@sign.write("foo", :fileLabel=>0x19)}
35
- assert_raise(ArgumentError) {@sign.write("foo", :fileLabel=>0x30)}
36
- assert_raise(ArgumentError) {@sign.write("foo", :fileLabel=>0x76)}
33
+ def test_sting_files
34
+ assert_nothing_raised do
35
+ @sign.writestr("foo")
36
+ @sign.writestr("foo",:str1)
37
+ @sign.writestr("foo",:str2)
38
+ @sign.callstr
39
+ @sign.callstr(:str1)
40
+ @sign.callstr(:str2)
41
+ end
42
+ assert_raise(ArgumentError) do
43
+ @sign.writestr("foo",:default)
44
+ @sign.writestr("foo",:nonesuch)
45
+ @sign.callstr(:default)
46
+ @sign.callstr(:nonesuch)
47
+ end
37
48
  end
38
49
  end
50
+
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alphasign
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 17
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 2
9
- - 0
10
- version: 0.2.0
8
+ - 3
9
+ - 1
10
+ version: 0.3.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jon Proulx
@@ -109,11 +109,14 @@ dependencies:
109
109
  version: "0"
110
110
  requirement: *id006
111
111
  description: |
112
- Alphasign is handles communication with LED signs using the Alpha Sign Protocol.
113
- These include Alpha signs and Betabrite signs by Adaptive Micro Systems, maybe
114
- others too, YMMV.
112
+ Alphasign is handles communication with LED signs using the
113
+ Alpha Sign Protocol. These include Alpha signs and Betabrite signs
114
+ by Adaptive Micro Systems, maybe others too, YMMV.
115
115
 
116
- Initial release only handles writing text to the sign over rs232 serial port.
116
+ This release handles writing "text files" and "string" files to the
117
+ sign over rs232 serial port, using a fixed memory configuration. Upcoming
118
+ releases will add "dots picture" files and memory user accesable memory
119
+ file configuration.
117
120
 
118
121
  email: jon@jonproulx.com
119
122
  executables: []
@@ -133,6 +136,7 @@ files:
133
136
  - Rakefile
134
137
  - VERSION
135
138
  - alphasign.gemspec
139
+ - examples/alphaclock.rb
136
140
  - lib/alphasign.rb
137
141
  - lib/alphasign/format.rb
138
142
  - lib/alphasign/protocol.rb