multi_movingsign 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.
- 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
|
+

|
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
|