multi_movingsign 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/.gitignore +21 -0
  2. data/.rspec +2 -0
  3. data/.travis.yml +9 -0
  4. data/.yardopts +1 -0
  5. data/CHANGELOG.md +17 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +22 -0
  8. data/PAGE_DEFINITION.md +115 -0
  9. data/README.md +133 -0
  10. data/Rakefile +1 -0
  11. data/bin/multi_movingsign +5 -0
  12. data/example.jpg +0 -0
  13. data/fonts/7-row-normal.png +0 -0
  14. data/fonts/README.md +1 -0
  15. data/lib/multi_movingsign.rb +9 -0
  16. data/lib/multi_movingsign/cli.rb +81 -0
  17. data/lib/multi_movingsign/errors.rb +10 -0
  18. data/lib/multi_movingsign/page_renderer.rb +223 -0
  19. data/lib/multi_movingsign/server.rb +317 -0
  20. data/lib/multi_movingsign/settings.rb +55 -0
  21. data/lib/multi_movingsign/sign.rb +37 -0
  22. data/lib/multi_movingsign/signs.rb +39 -0
  23. data/lib/multi_movingsign/testrc_loader.rb +17 -0
  24. data/lib/multi_movingsign/version.rb +3 -0
  25. data/multi_movingsign.gemspec +31 -0
  26. data/spec/cli_spec.rb +166 -0
  27. data/spec/noop_movingsign_sign.rb +47 -0
  28. data/spec/noop_movingsign_sign.yml +7 -0
  29. data/spec/page_renderer/example_1/1.yml +16 -0
  30. data/spec/page_renderer/example_1/2.yml +28 -0
  31. data/spec/page_renderer/example_1/4.yml +44 -0
  32. data/spec/page_renderer/example_1/5.json +10 -0
  33. data/spec/page_renderer/example_1/example_spec.rb +23 -0
  34. data/spec/page_renderer/example_1/page.yml +27 -0
  35. data/spec/page_renderer/example_2/1.yml +7 -0
  36. data/spec/page_renderer/example_2/2.yml +8 -0
  37. data/spec/page_renderer/example_2/4.json +9 -0
  38. data/spec/page_renderer/example_2/example_spec.rb +24 -0
  39. data/spec/page_renderer/example_2/page.yml +7 -0
  40. data/spec/page_renderer/example_3/1.yml +9 -0
  41. data/spec/page_renderer/example_3/3.yml +14 -0
  42. data/spec/page_renderer/example_3/example_spec.rb +22 -0
  43. data/spec/page_renderer/example_3/page.yml +12 -0
  44. data/spec/page_renderer/example_4/2.yml +12 -0
  45. data/spec/page_renderer/example_4/4.json +9 -0
  46. data/spec/page_renderer/example_4/example_spec.rb +24 -0
  47. data/spec/page_renderer/example_4/page.yml +12 -0
  48. data/spec/settings_1.yml +3 -0
  49. data/spec/settings_spec.rb +36 -0
  50. data/spec/spec_helper.rb +36 -0
  51. data/spec/support/doubles_support.rb +26 -0
  52. data/spec/support/executable_support.rb +112 -0
  53. metadata +244 -0
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ /temp.rb
2
+ /testrc.yml
3
+ /rspec.log
4
+
5
+ *.gem
6
+ *.rbc
7
+ .bundle
8
+ .config
9
+ .yardoc
10
+ Gemfile.lock
11
+ InstalledFiles
12
+ _yardoc
13
+ coverage
14
+ doc/
15
+ lib/bundler/man
16
+ pkg
17
+ rdoc
18
+ spec/reports
19
+ test/tmp
20
+ test/version_tmp
21
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/.travis.yml ADDED
@@ -0,0 +1,9 @@
1
+ rvm:
2
+ - 1.9.3-p194 # Ruby version on Ubuntu
3
+ - 1.9.3-p484 # Latest in 1.9.3 series
4
+ - 2.0.0-p353 # Latest in 2.0.0 series
5
+ - 2.1.1 # Latest
6
+ before_script:
7
+ - gem install bundler --version "~> 1.3"
8
+ - bundle install
9
+ script: bundle exec rspec -fd
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ - README.md CHANGELOG.md PAGE_DEFINITION.md
data/CHANGELOG.md ADDED
@@ -0,0 +1,17 @@
1
+ # Changelog
2
+
3
+ ## Version 0.0.1 (March 3, 2014)
4
+
5
+ #### Added
6
+
7
+ * Initial working version
8
+ * `multi_movingsign` CLI tool
9
+ * setup
10
+ * `show-identity`
11
+ * `show-page`
12
+ * Server mode
13
+ * start/stop server
14
+ * add/update page
15
+ * delete page
16
+ * display alert
17
+ * stop server
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in multi_movingsign.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Eric Webb
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,115 @@
1
+ # Page Definition Specification
2
+
3
+ A "page definition" is a term used internally to represent a page of information you'd like displayed on multiple LED signs. This page of information likely is both wider and longer than the number of signs you have can accomodate.
4
+
5
+ For example:
6
+
7
+ ``` Text
8
+ RACE RESULTS
9
+ 1. Eric 10 seconds
10
+ 2. Mike 11 seconds
11
+ 3. Justin 15 seconds
12
+ 4. Dan 20 seconds
13
+ ```
14
+
15
+ If you have 4 LED signs arranged vertically:
16
+
17
+ ``` text
18
+ [ ]
19
+ [ ]
20
+ [ ]
21
+ [ ]
22
+ ```
23
+
24
+ The 5 lines on the page above won't fit at one time. So, we need to break things up into lines and screens...which can be rendered into something displayable on the screens.
25
+
26
+ So, for the page above, it might get rendered as follows:
27
+
28
+ ``` text
29
+ # First
30
+ [RACE RESULTS ]
31
+ [1. Eric 10 seconds]
32
+ [2. Mike 11 seconds]
33
+ [3. Justin 15 seconds]
34
+
35
+ # Second
36
+ [4. Dan 20 seconds]
37
+ [ ]
38
+ [ ]
39
+ [ ]
40
+ ```
41
+
42
+ Notice, we broke up the 5 lines into 2 four line screenfulls (with 3 blank lines on the second screenful).
43
+
44
+ To specify this as a page definition YAML, we'd write the following:
45
+
46
+ ``` YAML
47
+ ---
48
+ title: RACE RESULTS
49
+ lines:
50
+ - prefix: '1. '
51
+ content:
52
+ - Eric
53
+ - 10 seconds
54
+ - prefix: '2. '
55
+ content:
56
+ - Mike
57
+ - 11 seconds
58
+ - prefix: '3. '
59
+ content:
60
+ - Justin
61
+ - 15 seconds
62
+ - prefix: '4. '
63
+ content:
64
+ - Dan
65
+ - 20 seconds
66
+ ```
67
+
68
+ A page definition consists of the following:
69
+
70
+ * `title`
71
+ * Title to be displayed when showing this page of the information (it will stick to the stop LED sign)
72
+ * `lines`
73
+ * An array of line definitions
74
+ * `prefix`
75
+ * If the content of one line is too long for a single screen, each screen of information will be prefixed with this text
76
+ * `content`
77
+ * An array of screen fulls of information. Each element of the array will be displayed in it's own screen.
78
+
79
+ Given the page definition above, the page would render as follows:
80
+
81
+ ``` text
82
+ # First
83
+
84
+ [RACE RESULTS ]
85
+ [1. Eric ]
86
+ [2. Mike ]
87
+ [3. Justin ]
88
+
89
+ # Second
90
+
91
+ [RACE RESULTS ]
92
+ [1. 10 seconds ]
93
+ [2. 11 seconds ]
94
+ [3. 15 seconds ]
95
+
96
+ # Third
97
+
98
+ [RACE RESULTS ]
99
+ [4. Dan ]
100
+ [ ]
101
+ [ ]
102
+ [ ]
103
+
104
+ # Fourth
105
+
106
+ [RACE RESULTS ]
107
+ [1. 20 seconds ]
108
+ [ ]
109
+ [ ]
110
+ [ ]
111
+ ```
112
+
113
+ Play around with it and see how things render! The "truth" is in [MultiMovingsign::PageRender page_renderer.rb](lib/multi_movingsign/page_renderer.rb) and in the related [test cases](lib/multi_movingsign/page_renderer.rb).
114
+
115
+ Pull requests and fixes welcome.
data/README.md ADDED
@@ -0,0 +1,133 @@
1
+ # MultiMovingsign
2
+
3
+ Command line tool to drive multiple [`movingsign_api`](https://github.com/webmonarch/movingsign_api) compatible [LED signs](http://www.signsdirect.com/Home/LED-Signs-Programmable/7x80-LED-Indoor-Brightness-Sign-Red.html) in unison.
4
+
5
+ For example: (below) `multi_movingsign` being used to display [Kegbot ](https://kegbot.org) top drinker stats.
6
+
7
+ ![Example](example.jpg)
8
+
9
+
10
+ # Why?
11
+
12
+ It's a fun, low-fi way to display various things. Some examples:
13
+
14
+ * Business Stats
15
+ * Sales
16
+ * Revenue
17
+ * Users
18
+ * Social
19
+ * Tweets
20
+ * Facebook Wall
21
+ * [Kegbot!](https://kegbot.org)
22
+ * Keg Status
23
+ * Drinker Stats
24
+ * Pretty much anything!
25
+
26
+
27
+ # Components
28
+
29
+ This gem comprises of the following main features:
30
+
31
+ * A command line tool `multi_movingsign` (see `multi_movingsign help` or [cli.rb](lib/multi_movingsign/cli.rb))
32
+ * CLI for individual operations
33
+ * setup + configuration
34
+ * displaying a page of information on screen
35
+ * A server mode to continuously alternate between pages of information (see `multi_movingsign server help` or [server.rb](lib/multi_movingsign/server.rb))
36
+ * `server start`
37
+ * `server add-page`
38
+ * adds/updates a page on display rotation
39
+ * `server alert`
40
+ * send a page to be display immediately (on demand) and not put into rotation
41
+ * `server stop`
42
+
43
+ To get help on the CLI tools, run help:
44
+
45
+ ``` bash
46
+ $ multi_movingsign help
47
+ Commands:
48
+ multi_movingsign help [COMMAND] # Describe available commands or one specific command
49
+ multi_movingsign server SUBCOMMAND ...ARGS # Run or manipuate the MultiMovingsign server
50
+ multi_movingsign settings # Prints settings to terminal
51
+ multi_movingsign setup # Setup available Movingsign LED signs and preferences
52
+ multi_movingsign show-identity # Show sign identifying information on all signs
53
+ multi_movingsign show-page --page=PAGE # Renders the specified page to the configured signs
54
+
55
+ Options:
56
+ [--rc=RC] # Path the persistent settings file. Defaults to: ~/.multi_movingsign.yml
57
+ ```
58
+
59
+ # Getting Started
60
+
61
+ ## Requirements
62
+
63
+ To use the `multi_movingsign` gem, you need:
64
+
65
+ * 2 - 4 `movingsign_api` LED signs
66
+ * More signs possible...just not tested
67
+ * Ruby >= 2.0.0 Recommended
68
+ * Ruby 1.9.3 is also tested
69
+ * UNIX-y OS (Linux, Mac)
70
+ * Windows *may* work, but not tested
71
+
72
+ ## Installation
73
+
74
+ Add this line to your application's Gemfile:
75
+
76
+ gem 'multi_movingsign'
77
+
78
+ And then execute:
79
+
80
+ $ bundle
81
+
82
+ Or install it yourself as:
83
+
84
+ $ gem install multi_movingsign
85
+
86
+ ## Usage
87
+
88
+ The workflow is as follows:
89
+
90
+ 1. Configure `multi_movingsign` with the attached LED sign device paths
91
+ 2. Create a page of information to display (see [page definition](PAGE_DEFINITION.md))
92
+ 3. Start the MultiMovingsign server
93
+ 4. Add the page to the server
94
+ 5. Stop the server
95
+
96
+ ``` bash
97
+ $ multi_movingsign setup --signs /dev/ttyUSB0 /dev/ttyUSB1 # Setup the sign device paths
98
+
99
+ $ cat > page.yml <<PAGE # Create page definition in page.yml
100
+ ---
101
+ title: Page Title
102
+ lines:
103
+ - prefix: 'L 1: '
104
+ content:
105
+ - Screen 1
106
+ - Screen 2
107
+ - prefix: 'L 2: '
108
+ content:
109
+ - Screen 1
110
+ - Screen 2
111
+ PAGE
112
+
113
+ $ multi_movingsign server start # Start the sign server
114
+
115
+ $ multi_movingsign server add-page --page page.yml # Add a page to the running server (do in a separate terminal window from the 'server start' above)
116
+
117
+ $ multi_movingsign server stop # Stop the server
118
+ ```
119
+
120
+ For examples on using `multi_movingsign` programmatically, see [cli.rb](lib/multi_movingsign/cli.rb).
121
+
122
+ ## Version History
123
+
124
+ For a complete list of versions, see [CHANGELOG.md](CHANGELOG.md).
125
+
126
+
127
+ # Contributing
128
+
129
+ 1. Fork it
130
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
131
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
132
+ 4. Push to the branch (`git push origin my-new-feature`)
133
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'multi_movingsign'
4
+
5
+ MultiMovingsign::Cli.start(ARGV)
data/example.jpg ADDED
Binary file
Binary file
data/fonts/README.md ADDED
@@ -0,0 +1 @@
1
+ Screenshots of the various MovingSign fonts.
@@ -0,0 +1,9 @@
1
+ require "multi_movingsign/version"
2
+ require "multi_movingsign/errors"
3
+ require "multi_movingsign/page_renderer"
4
+ require "multi_movingsign/cli"
5
+ require "multi_movingsign/settings"
6
+
7
+ module MultiMovingsign
8
+ # Your code goes here...
9
+ end
@@ -0,0 +1,81 @@
1
+ require 'thor'
2
+ require 'multi_movingsign/server'
3
+ require 'multi_movingsign/settings'
4
+ require 'multi_movingsign/signs'
5
+
6
+ module MultiMovingsign
7
+ # Command line interface to MultiMovingsign
8
+ class Cli < Thor
9
+ class_option :rc, :desc => 'Path the persistent settings file. Defaults to: ~/.multi_movingsign.yml'
10
+ class_option :testrc, :desc => 'Path to a script loaded BEFORE execution (used for testing)', :hide => true
11
+
12
+ desc 'setup', "Setup available Movingsign LED signs and preferences"
13
+ option :signs, :type => :array, :desc => "List of Movingsign LED board serial ports"
14
+ def setup
15
+ if signs = options[:signs]
16
+ settings = Settings.load settings_path
17
+ settings.sign_paths = signs
18
+
19
+ settings.dump settings_path
20
+ end
21
+ end
22
+
23
+ desc 'settings', 'Prints settings to terminal'
24
+ def settings
25
+ settings = Settings.load settings_path
26
+
27
+ puts "Signs (#{settings.signs.length}): #{settings.signs.map { |s| s.path }.join(' ')}"
28
+ end
29
+
30
+ desc 'show-identity', 'Show sign identifying information on all signs'
31
+ def show_identity
32
+ TestRCLoader.load(options['testrc']) if options['testrc']
33
+
34
+ settings = Settings.load settings_path
35
+
36
+ # validate we have signs
37
+ raise_no_signs unless settings.signs?
38
+
39
+ signs = Signs.new settings.signs
40
+
41
+ signs.show_identity
42
+ end
43
+
44
+ desc 'show-page', 'Renders the specified page to the configured signs'
45
+ option :page, :required => true, :desc => "YAML containing page definition"
46
+ def show_page
47
+ TestRCLoader.load(options['testrc']) if options['testrc']
48
+
49
+ settings = Settings.load settings_path
50
+ raise_no_signs unless settings.signs?
51
+
52
+ signs = settings.signs
53
+
54
+ page = YAML.load(File.read(options[:page]))
55
+
56
+ renderer = PageRenderer.new
57
+ solution = renderer.render(page, :count => signs.length)
58
+
59
+ threads = []
60
+ solution['signs'].each_with_index do |hash, i|
61
+ threads << Thread.new do
62
+ signs[i].show_text hash['content'], :display_pause => 3
63
+ end
64
+ end
65
+ threads.each { |t| t.join }
66
+ end
67
+
68
+ desc 'server SUBCOMMAND ...ARGS', 'Run or manipuate the MultiMovingsign server'
69
+ subcommand 'server', Server
70
+
71
+ private
72
+
73
+ def settings_path
74
+ options[:rc] || Settings.default_settings_path
75
+ end
76
+
77
+ def raise_no_signs
78
+ raise InvalidInputError, "No signs specified. Please run setup with the --signs option."
79
+ end
80
+ end
81
+ end