movingsign_api 0.0.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.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/.rspec +2 -0
- data/.travis.yml +8 -0
- data/.yardopts +1 -0
- data/CHANGELOG.md +11 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +60 -0
- data/Rakefile +1 -0
- data/lib/movingsign_api/commands/command.rb +76 -0
- data/lib/movingsign_api/commands/hard_reset_command.rb +16 -0
- data/lib/movingsign_api/commands/internal/align_mode.rb +50 -0
- data/lib/movingsign_api/commands/internal/display_mode.rb +61 -0
- data/lib/movingsign_api/commands/internal/display_pause.rb +33 -0
- data/lib/movingsign_api/commands/internal/display_speed.rb +45 -0
- data/lib/movingsign_api/commands/internal/file_handle.rb +54 -0
- data/lib/movingsign_api/commands/internal/pretty_keyable.rb +50 -0
- data/lib/movingsign_api/commands/internal/sender_receiver_address.rb +82 -0
- data/lib/movingsign_api/commands/internal/utilities.rb +8 -0
- data/lib/movingsign_api/commands/set_clock_command.rb +32 -0
- data/lib/movingsign_api/commands/set_sound_command.rb +21 -0
- data/lib/movingsign_api/commands/software_reset_command.rb +16 -0
- data/lib/movingsign_api/commands/write_control_command.rb +35 -0
- data/lib/movingsign_api/commands/write_text_command.rb +116 -0
- data/lib/movingsign_api/errors.rb +22 -0
- data/lib/movingsign_api/sign.rb +144 -0
- data/lib/movingsign_api/version.rb +3 -0
- data/lib/movingsign_api.rb +13 -0
- data/movingsign_api.gemspec +30 -0
- data/spec/align_mode_spec.rb +28 -0
- data/spec/commands/set_sound_command_spec.rb +19 -0
- data/spec/display_mode_spec.rb +57 -0
- data/spec/display_speed_spec.rb +23 -0
- data/spec/examples/example_A_spec.rb +24 -0
- data/spec/examples/example_C_spec.rb +16 -0
- data/spec/examples/example_D_spec.rb +14 -0
- data/spec/examples/example_K_spec.rb +14 -0
- data/spec/examples/expected.rb +130 -0
- data/spec/file_handle_spec.rb +17 -0
- data/spec/sender_receiver_address_spec.rb +60 -0
- data/spec/spec_helper.rb +19 -0
- data/spec/tutorials/readme_1.rb +5 -0
- data/spec/tutorials/readme_2.rb +5 -0
- data/spec/tutorials/tutorials_spec.rb +14 -0
- metadata +188 -0
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'movingsign_api/commands/write_control_command'
|
2
|
+
|
3
|
+
module MovingsignApi
|
4
|
+
# Performs a soft reset of the sign
|
5
|
+
#
|
6
|
+
# @note The sign will restart after receiving this command.
|
7
|
+
class SoftwareResetCommand < WriteControlCommand
|
8
|
+
def subcommand_code
|
9
|
+
'B'
|
10
|
+
end
|
11
|
+
|
12
|
+
def subcommand_payload_bytes
|
13
|
+
[]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'movingsign_api/commands/command'
|
2
|
+
|
3
|
+
module MovingsignApi
|
4
|
+
# Write control command base class, subclassed by actual implementations
|
5
|
+
#
|
6
|
+
# In subclasses, be sure to implement:
|
7
|
+
# - {#subcommand_code}
|
8
|
+
# - {#subcommand_payload_bytes}
|
9
|
+
class WriteControlCommand < Command
|
10
|
+
def command_code
|
11
|
+
'W'
|
12
|
+
end
|
13
|
+
|
14
|
+
def subcommand_code
|
15
|
+
raise MovingsignApi::NotImplementedError, "Needs to be implemented in subclass."
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def command_payload_bytes
|
21
|
+
bytes = []
|
22
|
+
|
23
|
+
bytes.concat string_to_ascii_bytes subcommand_code
|
24
|
+
bytes.concat subcommand_payload_bytes
|
25
|
+
|
26
|
+
bytes
|
27
|
+
end
|
28
|
+
|
29
|
+
# generates control sub-command specific bytes
|
30
|
+
def subcommand_payload_bytes
|
31
|
+
raise MovingsignApi::NotImplementedError, "Needs to be implemented in subclass."
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
require 'movingsign_api/commands/command'
|
2
|
+
require 'movingsign_api/commands/internal/file_handle'
|
3
|
+
require 'movingsign_api/commands/internal/display_mode'
|
4
|
+
require 'movingsign_api/commands/internal/display_speed'
|
5
|
+
require 'movingsign_api/commands/internal/display_pause'
|
6
|
+
require 'movingsign_api/commands/internal/align_mode'
|
7
|
+
|
8
|
+
module MovingsignApi
|
9
|
+
# Writes text to a sign
|
10
|
+
class WriteTextCommand < MovingsignApi::Command
|
11
|
+
# Index of the file to write to. 0 - 35 (363 total). See {FileHandle}
|
12
|
+
#
|
13
|
+
# @param value [Integer] 0 - 35 (default: 0)
|
14
|
+
attr_accessor :file_handle
|
15
|
+
|
16
|
+
# Display mode to use. See {DisplayMode}
|
17
|
+
#
|
18
|
+
# @param value [Sybol] (default: +:hold+)
|
19
|
+
attr_accessor :display_mode
|
20
|
+
|
21
|
+
# Display speed of effects. See {DisplaySpeed}
|
22
|
+
#
|
23
|
+
# @param value [Symbol] default: +:normal+
|
24
|
+
attr_accessor :display_speed
|
25
|
+
|
26
|
+
# Display pause between screens of information. See {DisplayPause}
|
27
|
+
#
|
28
|
+
# @param value [Integer] default: +2+
|
29
|
+
attr_accessor :display_pause
|
30
|
+
|
31
|
+
# Day of week mask. See specification for an explaination of this parameter
|
32
|
+
#
|
33
|
+
# @param value [String] default: +'7F'+
|
34
|
+
attr_accessor :dayofweek_mask
|
35
|
+
|
36
|
+
# Align mode to use. See {AlignMode}
|
37
|
+
#
|
38
|
+
# @param value [Symbol] One of +:left+ +:right+ +:center+ (default +:left+)
|
39
|
+
attr_accessor :align_mode
|
40
|
+
|
41
|
+
# Display start time
|
42
|
+
# @note work in progress
|
43
|
+
#
|
44
|
+
# @param value [String] default: +'0000'+
|
45
|
+
attr_accessor :start_time
|
46
|
+
|
47
|
+
# Display end time
|
48
|
+
# @note work in progress
|
49
|
+
#
|
50
|
+
# @param value [String] default: +'2359'+
|
51
|
+
attr_accessor :end_time
|
52
|
+
|
53
|
+
# Text to display
|
54
|
+
#
|
55
|
+
# @param value [String] the message to display
|
56
|
+
attr_accessor :text
|
57
|
+
|
58
|
+
def file_handle=(handle)
|
59
|
+
@file_handle = FileHandle.new(handle)
|
60
|
+
end
|
61
|
+
|
62
|
+
def display_mode=(mode)
|
63
|
+
@display_mode = DisplayMode.parse(mode)
|
64
|
+
end
|
65
|
+
|
66
|
+
def display_speed=(speed)
|
67
|
+
@display_speed = DisplaySpeed.parse(speed)
|
68
|
+
end
|
69
|
+
|
70
|
+
def display_pause=(seconds)
|
71
|
+
@display_pause = DisplayPause.new seconds
|
72
|
+
end
|
73
|
+
|
74
|
+
def align_mode=(align)
|
75
|
+
@align_mode = AlignMode.parse(align)
|
76
|
+
end
|
77
|
+
|
78
|
+
# (see Command#command_code)
|
79
|
+
# 'A' for the "Write Text" command
|
80
|
+
def command_code
|
81
|
+
'A'
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def command_payload_bytes
|
87
|
+
# set defaults if needed
|
88
|
+
self.file_handle ||= 0
|
89
|
+
self.display_mode ||= :hold
|
90
|
+
self.display_speed ||= :normal
|
91
|
+
self.display_pause ||= 2
|
92
|
+
self.dayofweek_mask ||= '7F'
|
93
|
+
self.align_mode ||= :left
|
94
|
+
self.start_time ||= '0000'
|
95
|
+
self.end_time ||= '2359'
|
96
|
+
raise InvalidInputError, "text not set" unless self.text
|
97
|
+
|
98
|
+
bytes = []
|
99
|
+
|
100
|
+
bytes.concat self.file_handle.to_bytes # Filename
|
101
|
+
bytes.concat self.display_mode.to_bytes # Display Mode
|
102
|
+
bytes.concat self.display_speed.to_bytes # Display Speed
|
103
|
+
bytes.concat self.display_pause.to_bytes # Display Pause
|
104
|
+
bytes.concat string_to_ascii_bytes(self.dayofweek_mask) # Show Date
|
105
|
+
bytes.concat string_to_ascii_bytes(self.start_time) # Start Time
|
106
|
+
bytes.concat string_to_ascii_bytes(self.end_time) # End Time
|
107
|
+
bytes.concat string_to_ascii_bytes('000') # Reserved
|
108
|
+
bytes.concat self.align_mode.to_bytes # Align Mode
|
109
|
+
#bytes.concat string_to_ascii_bytes("\xFD\x42" + self.text.gsub("\n", "\x7F")) # Text
|
110
|
+
bytes.concat string_to_ascii_bytes(self.text.gsub("\n", "\x7F")) # Text
|
111
|
+
|
112
|
+
bytes
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module MovingsignApi
|
2
|
+
# Base error for all MovingsignApi errors.
|
3
|
+
class Error < StandardError
|
4
|
+
|
5
|
+
end
|
6
|
+
|
7
|
+
# Raised when a method has been be implemented, usually due to improperly subclassed class or code that is in
|
8
|
+
# progress.
|
9
|
+
class NotImplementedError < Error
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
# Raised when an input is invalid in the given context.
|
14
|
+
class InvalidInputError < Error
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
# Raised when there are errors reading/writing to the serial port
|
19
|
+
class IOError < Error
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
require 'serialport'
|
2
|
+
|
3
|
+
module MovingsignApi
|
4
|
+
# Manipulates a Movingsign attached to a serial port
|
5
|
+
#
|
6
|
+
# @example Construct a sign
|
7
|
+
# require 'movingsign_api'
|
8
|
+
#
|
9
|
+
# sign = MovingsignApi::Sign.new('/dev/ttyUSB0')
|
10
|
+
#
|
11
|
+
# @example Show Text
|
12
|
+
# sign.show_text('Hello World!')
|
13
|
+
#
|
14
|
+
# @example Turn Sound Off
|
15
|
+
# sign.set_sound false
|
16
|
+
#
|
17
|
+
class Sign
|
18
|
+
# Serial port device path (ie: /dev/ttyUSB0)
|
19
|
+
attr_accessor :device_path
|
20
|
+
|
21
|
+
# @param device_path [String] the serial port device path (ie: /dev/ttyUSB0, different depending on platform)
|
22
|
+
def initialize(device_path)
|
23
|
+
@device_path = device_path
|
24
|
+
end
|
25
|
+
|
26
|
+
# Show the {#device_path} value on the display (useful for diagnostics)
|
27
|
+
def show_identity
|
28
|
+
cmd = WriteTextCommand.new
|
29
|
+
cmd.text = self.device_path
|
30
|
+
|
31
|
+
send_command cmd
|
32
|
+
end
|
33
|
+
|
34
|
+
# Displays the given text on the board.
|
35
|
+
#
|
36
|
+
# This is short-hand for the {WriteTextCommand}
|
37
|
+
#
|
38
|
+
# @param text [String] the text to display on the sign
|
39
|
+
# @param options [Hash] options for {WriteTextCommand}
|
40
|
+
# @option options [Integer] :display_pause (2) Time to pause (in seconds) between pages of text. See {WriteTextCommand#display_pause}
|
41
|
+
#
|
42
|
+
# @return [self]
|
43
|
+
def show_text(text, options = {})
|
44
|
+
cmd = WriteTextCommand.new
|
45
|
+
cmd.display_pause = options[:display_pause] if options[:display_pause]
|
46
|
+
cmd.text = text
|
47
|
+
|
48
|
+
send_command cmd
|
49
|
+
end
|
50
|
+
alias :write_text :show_text
|
51
|
+
|
52
|
+
# Turns on/off sound when the sign receives a command
|
53
|
+
#
|
54
|
+
# This is a shorthand for {SetSoundCommand}
|
55
|
+
#
|
56
|
+
# @param on [Boolean] true to turn sound on, false otherwise
|
57
|
+
#
|
58
|
+
# @return [self]
|
59
|
+
def set_sound(on)
|
60
|
+
cmd = SetSoundCommand.new on
|
61
|
+
|
62
|
+
send_command cmd
|
63
|
+
end
|
64
|
+
|
65
|
+
# Sends the specified Movingsign command to this sign's serial port
|
66
|
+
#
|
67
|
+
# @param [MovingsignApi::Command] command subclass to send
|
68
|
+
#
|
69
|
+
# @return [self]
|
70
|
+
def send_command(command)
|
71
|
+
SerialPort.open(self.device_path, 9600, 8, 1) do |port|
|
72
|
+
# flush anything existing on the port
|
73
|
+
port.flush
|
74
|
+
flush_read_buffer(port)
|
75
|
+
|
76
|
+
byte_string = command.to_bytes.pack('C*')
|
77
|
+
|
78
|
+
begin
|
79
|
+
while byte_string && byte_string.length != 0
|
80
|
+
count = port.write_nonblock(byte_string)
|
81
|
+
byte_string = byte_string[count,-1]
|
82
|
+
|
83
|
+
port.flush
|
84
|
+
end
|
85
|
+
rescue IO::WaitWritable
|
86
|
+
if IO.select([], [port], [], 5)
|
87
|
+
retry
|
88
|
+
else
|
89
|
+
raise IOError, "Timeout writing command to #{self.device_path}"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# wait for expected confirmation signals
|
94
|
+
got_eot = false
|
95
|
+
got_soh = false
|
96
|
+
loop do
|
97
|
+
begin
|
98
|
+
c = port.read_nonblock(1)
|
99
|
+
|
100
|
+
case c
|
101
|
+
when "\x04"
|
102
|
+
if ! got_eot
|
103
|
+
got_eot = true
|
104
|
+
else
|
105
|
+
raise IOError, "Got EOT reply twice from #{self.device_path}"
|
106
|
+
end
|
107
|
+
when "\x01"
|
108
|
+
if got_eot
|
109
|
+
if ! got_soh
|
110
|
+
got_soh = true
|
111
|
+
|
112
|
+
break
|
113
|
+
else
|
114
|
+
raise IOError, "Got SOH twice from #{self.device_path}"
|
115
|
+
end
|
116
|
+
else
|
117
|
+
raise IOError, "Got SOH before EOT from #{self.device_path}"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
rescue IO::WaitReadable
|
121
|
+
if IO.select([port], [], [], 3)
|
122
|
+
retry
|
123
|
+
else
|
124
|
+
raise IOError, "Timeout waiting for command reply from #{self.device_path}. EOT:#{got_eot} SOH:#{got_soh}"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
self
|
131
|
+
end
|
132
|
+
|
133
|
+
private
|
134
|
+
|
135
|
+
def flush_read_buffer(port)
|
136
|
+
begin
|
137
|
+
while true
|
138
|
+
port.read_nonblock(1024)
|
139
|
+
end
|
140
|
+
rescue IO::WaitReadable
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require "movingsign_api/errors"
|
2
|
+
require "movingsign_api/version"
|
3
|
+
require 'movingsign_api/commands/write_text_command'
|
4
|
+
require 'movingsign_api/commands/set_clock_command'
|
5
|
+
require 'movingsign_api/commands/software_reset_command'
|
6
|
+
require 'movingsign_api/commands/hard_reset_command'
|
7
|
+
require 'movingsign_api/commands/set_clock_command'
|
8
|
+
require 'movingsign_api/commands/set_sound_command'
|
9
|
+
require 'movingsign_api/sign'
|
10
|
+
|
11
|
+
module MovingsignApi
|
12
|
+
# Your code goes here...
|
13
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'movingsign_api/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "movingsign_api"
|
8
|
+
spec.version = MovingsignApi::VERSION
|
9
|
+
spec.authors = ["Eric Webb"]
|
10
|
+
spec.email = ["opensource@collectivegenius.net"]
|
11
|
+
spec.description = "MovingSign Communication Protocol V2.1 Implementation in Ruby"
|
12
|
+
spec.summary = "MovingSign Communication Protocol V2.1 Implementation in Ruby"
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
.reject { |path| path.match /\A\.idea\// } # Ignore .idea/ IntelliJ project directory
|
18
|
+
.reject { |path| path.match /\A[^\/]+\.iml/ } # Ignore *.iml IntelliJ module file
|
19
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
20
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
21
|
+
spec.require_paths = ["lib"]
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
24
|
+
spec.add_development_dependency "rake"
|
25
|
+
spec.add_development_dependency "rspec", "~> 2.14"
|
26
|
+
spec.add_development_dependency "yard", "0.8.7.3"
|
27
|
+
spec.add_development_dependency "wwtd"
|
28
|
+
|
29
|
+
spec.add_runtime_dependency 'serialport', '~> 1.3'
|
30
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
ALIGN_MODES = {
|
5
|
+
:left => '1',
|
6
|
+
:right => '3',
|
7
|
+
:center => '2',
|
8
|
+
}
|
9
|
+
|
10
|
+
describe MovingsignApi::AlignMode do
|
11
|
+
describe '::parse' do
|
12
|
+
it "Symbol" do
|
13
|
+
# valid keys
|
14
|
+
ALIGN_MODES.keys.each do |key|
|
15
|
+
expect(described_class.parse(key).key).to eq key
|
16
|
+
end
|
17
|
+
|
18
|
+
# invalid keys
|
19
|
+
expect {described_class.parse(:invalid).key}.to raise_error(MovingsignApi::InvalidInputError)
|
20
|
+
expect {described_class.parse(nil).key}.to raise_error(MovingsignApi::InvalidInputError)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'Code' do
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MovingsignApi::SetSoundCommand do
|
4
|
+
describe "sound on" do
|
5
|
+
subject { MovingsignApi::SetSoundCommand.new(true) }
|
6
|
+
|
7
|
+
it "#subcommand_payload_bytes" do
|
8
|
+
expect(subject.subcommand_payload_bytes).to eq [0x31]
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "sound off" do
|
13
|
+
subject { MovingsignApi::SetSoundCommand.new(false) }
|
14
|
+
|
15
|
+
it "#subcommand_payload_bytes" do
|
16
|
+
expect(subject.subcommand_payload_bytes).to eq [0x30]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
DISPLAY_MODES = {
|
5
|
+
:auto => 'A',
|
6
|
+
:flash => 'B',
|
7
|
+
:hold => 'C',
|
8
|
+
:interlock => 'D',
|
9
|
+
:rolldown => 'E',
|
10
|
+
:rollup => 'F',
|
11
|
+
:rollin => 'G',
|
12
|
+
:rollout => 'H',
|
13
|
+
:rollleft => 'I',
|
14
|
+
:rollright => 'J',
|
15
|
+
:rotate => 'K',
|
16
|
+
:slide => 'L',
|
17
|
+
:snow => 'M',
|
18
|
+
:sparkle => 'N',
|
19
|
+
:spray => 'O',
|
20
|
+
:starburst => 'P',
|
21
|
+
:switch => 'Q',
|
22
|
+
:twinkle => 'R',
|
23
|
+
:wipedown => 'S',
|
24
|
+
:wipeup => 'T',
|
25
|
+
:wipein => 'U',
|
26
|
+
:wipeout => 'V',
|
27
|
+
:wipeleft => 'W',
|
28
|
+
:wiperight => 'X',
|
29
|
+
:cyclecolor => 'Y',
|
30
|
+
:clock => 'Z',
|
31
|
+
}
|
32
|
+
|
33
|
+
describe MovingsignApi::DisplayMode do
|
34
|
+
describe '::parse' do
|
35
|
+
it "Symbol" do
|
36
|
+
# All valid keys
|
37
|
+
DISPLAY_MODES.keys.each do |key|
|
38
|
+
expect(described_class.parse(key).key).to eq key
|
39
|
+
end
|
40
|
+
|
41
|
+
# invalid keys
|
42
|
+
expect {described_class.parse(:invalid).key}.to raise_error(MovingsignApi::InvalidInputError)
|
43
|
+
expect {described_class.parse(:+).key}.to raise_error(MovingsignApi::InvalidInputError)
|
44
|
+
expect {described_class.parse(nil).key}.to raise_error(MovingsignApi::InvalidInputError)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "ASCII Code" do
|
48
|
+
# All valid ASCII codes
|
49
|
+
DISPLAY_MODES.each_pair do |key, code|
|
50
|
+
expect(described_class.parse(code).key).to eq key
|
51
|
+
end
|
52
|
+
|
53
|
+
expect {described_class.parse('0').key}.to raise_error(MovingsignApi::InvalidInputError)
|
54
|
+
expect {described_class.parse('z').key}.to raise_error(MovingsignApi::InvalidInputError)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
DISPLAY_SPEEDS = {
|
4
|
+
:fastest => '1',
|
5
|
+
:faster => '2',
|
6
|
+
:normal => '3',
|
7
|
+
:slow => '4',
|
8
|
+
:slower => '5',
|
9
|
+
}
|
10
|
+
|
11
|
+
describe MovingsignApi::DisplaySpeed do
|
12
|
+
describe '::parse' do
|
13
|
+
it "Symbol" do
|
14
|
+
DISPLAY_SPEEDS.keys.each do |key|
|
15
|
+
expect(described_class.parse(key).key).to eq key
|
16
|
+
end
|
17
|
+
|
18
|
+
# invalid keys
|
19
|
+
expect {described_class.parse(:invalid).key}.to raise_error(MovingsignApi::InvalidInputError)
|
20
|
+
expect {described_class.parse(nil).key}.to raise_error(MovingsignApi::InvalidInputError)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require_relative 'expected'
|
4
|
+
|
5
|
+
describe "Specification Example A - Write Text File" do
|
6
|
+
it "Generates Expected Output" do
|
7
|
+
command = MovingsignApi::WriteTextCommand.new
|
8
|
+
|
9
|
+
command.sender = :pc
|
10
|
+
command.receiver = 3
|
11
|
+
|
12
|
+
command.file_handle = 'A' # aka 10
|
13
|
+
command.display_mode = :auto
|
14
|
+
command.display_speed = :faster
|
15
|
+
command.display_pause = 2
|
16
|
+
command.dayofweek_mask = '7F' # todo: make this pretty
|
17
|
+
command.start_time = '0100'
|
18
|
+
command.end_time = '1200'
|
19
|
+
command.align_mode = :left
|
20
|
+
command.text = 'HELLO'
|
21
|
+
|
22
|
+
expect(command.to_bytes).to eq EXAMPLE_A_EXPECTED
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require_relative 'expected'
|
4
|
+
|
5
|
+
describe "Specification Example C - Set Clock Command" do
|
6
|
+
it "Generates Expected Output" do
|
7
|
+
command = MovingsignApi::SetClockCommand.new
|
8
|
+
|
9
|
+
command.sender = :pc
|
10
|
+
command.receiver = 34
|
11
|
+
|
12
|
+
command.datetime = Time.new(2004,04,02,12,36,23)
|
13
|
+
|
14
|
+
expect(command.to_bytes).to eq EXAMPLE_C_EXPECTED
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require_relative 'expected'
|
4
|
+
|
5
|
+
describe "Specification Example D - Software Reset Command" do
|
6
|
+
it "Generates Expected Output" do
|
7
|
+
command = MovingsignApi::SoftwareResetCommand.new
|
8
|
+
|
9
|
+
command.sender = :pc
|
10
|
+
command.receiver = 34
|
11
|
+
|
12
|
+
expect(command.to_bytes).to eq EXAMPLE_D_EXPECTED
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require_relative 'expected'
|
4
|
+
|
5
|
+
describe "Specification Example K - Hard Reset Command" do
|
6
|
+
it "Generates Expected Output" do
|
7
|
+
command = MovingsignApi::HardResetCommand.new
|
8
|
+
|
9
|
+
command.sender = :pc
|
10
|
+
command.receiver = 16
|
11
|
+
|
12
|
+
expect(command.to_bytes).to eq EXAMPLE_K_EXPECTED
|
13
|
+
end
|
14
|
+
end
|