multi_movingsign 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +21 -0
- data/.rspec +2 -0
- data/.travis.yml +9 -0
- data/.yardopts +1 -0
- data/CHANGELOG.md +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/PAGE_DEFINITION.md +115 -0
- data/README.md +133 -0
- data/Rakefile +1 -0
- data/bin/multi_movingsign +5 -0
- data/example.jpg +0 -0
- data/fonts/7-row-normal.png +0 -0
- data/fonts/README.md +1 -0
- data/lib/multi_movingsign.rb +9 -0
- data/lib/multi_movingsign/cli.rb +81 -0
- data/lib/multi_movingsign/errors.rb +10 -0
- data/lib/multi_movingsign/page_renderer.rb +223 -0
- data/lib/multi_movingsign/server.rb +317 -0
- data/lib/multi_movingsign/settings.rb +55 -0
- data/lib/multi_movingsign/sign.rb +37 -0
- data/lib/multi_movingsign/signs.rb +39 -0
- data/lib/multi_movingsign/testrc_loader.rb +17 -0
- data/lib/multi_movingsign/version.rb +3 -0
- data/multi_movingsign.gemspec +31 -0
- data/spec/cli_spec.rb +166 -0
- data/spec/noop_movingsign_sign.rb +47 -0
- data/spec/noop_movingsign_sign.yml +7 -0
- data/spec/page_renderer/example_1/1.yml +16 -0
- data/spec/page_renderer/example_1/2.yml +28 -0
- data/spec/page_renderer/example_1/4.yml +44 -0
- data/spec/page_renderer/example_1/5.json +10 -0
- data/spec/page_renderer/example_1/example_spec.rb +23 -0
- data/spec/page_renderer/example_1/page.yml +27 -0
- data/spec/page_renderer/example_2/1.yml +7 -0
- data/spec/page_renderer/example_2/2.yml +8 -0
- data/spec/page_renderer/example_2/4.json +9 -0
- data/spec/page_renderer/example_2/example_spec.rb +24 -0
- data/spec/page_renderer/example_2/page.yml +7 -0
- data/spec/page_renderer/example_3/1.yml +9 -0
- data/spec/page_renderer/example_3/3.yml +14 -0
- data/spec/page_renderer/example_3/example_spec.rb +22 -0
- data/spec/page_renderer/example_3/page.yml +12 -0
- data/spec/page_renderer/example_4/2.yml +12 -0
- data/spec/page_renderer/example_4/4.json +9 -0
- data/spec/page_renderer/example_4/example_spec.rb +24 -0
- data/spec/page_renderer/example_4/page.yml +12 -0
- data/spec/settings_1.yml +3 -0
- data/spec/settings_spec.rb +36 -0
- data/spec/spec_helper.rb +36 -0
- data/spec/support/doubles_support.rb +26 -0
- data/spec/support/executable_support.rb +112 -0
- metadata +244 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
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
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.
|
data/PAGE_DEFINITION.md
ADDED
@@ -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"
|
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,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
|