syncsign 0.3.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -1
- data/lib/syncsign.rb +9 -1
- data/lib/syncsign/node-display.rb +4 -2
- data/lib/syncsign/template.rb +7 -3
- data/lib/syncsign/version.rb +1 -1
- data/lib/syncsign/widget-core.rb +76 -0
- data/lib/syncsign/widgets/buttonlabels.rb +46 -0
- data/lib/syncsign/widgets/circle.rb +62 -0
- data/lib/syncsign/widgets/line.rb +56 -0
- data/lib/syncsign/widgets/qrcode.rb +62 -0
- data/lib/syncsign/widgets/rectangle.rb +57 -0
- data/lib/syncsign/widgets/symbolbox-symbols.rb +1630 -0
- data/lib/syncsign/widgets/symbolbox.rb +79 -0
- data/lib/syncsign/widgets/textbox.rb +100 -0
- metadata +11 -3
- data/lib/syncsign/widgets.rb +0 -378
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ecfc03f1b6335088ff04e9bbe56a78fd1942569b30ffb07e6a5a0094d8451a3e
|
4
|
+
data.tar.gz: cdd719e880cc9117d0dde045956c4e299a8de5c3fb4952a9aff5305c6d1ff1ea
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6e1e58973658b2fcc66b8cf538b123d9554f32966022689bf316f23592acf17241762034fc7c7082063e9099663dd75f55a1beec14e808dbff340e0508840dfc
|
7
|
+
data.tar.gz: 6f5ec20b8eda95908fd34a2012f108b16f623b97dec137a31eff4fca41d87387279ca4196b9f83608e59812ce29ab61d045f363962aec2e76d0f547a3c4c3544
|
data/README.md
CHANGED
@@ -12,7 +12,6 @@ Ruby class/gem to access the [SyncSign](http://sync-sign.com) cloud service to d
|
|
12
12
|
* Support non-display nodes that connect to the SyncSign hub (like temperature or occupancy sensors)
|
13
13
|
* Support display-resident images (item type IMAGE)
|
14
14
|
* Support bitmap images from a URI (item type BITMAP\_URI)
|
15
|
-
* Support icons in text boxes
|
16
15
|
|
17
16
|
## Use
|
18
17
|
|
@@ -48,6 +47,8 @@ Check out the examples/ folder for:
|
|
48
47
|
* nodes.rb - List all nodes on the system and information about them.
|
49
48
|
* hubs.rb - List all hubs on the system and whether we have enough info to support direct rendering.
|
50
49
|
* render.rb - Render a sample screen to the given node.
|
50
|
+
* symbols.rb - Shows how to use the Symbolbox to utilize display-resident symbols.
|
51
|
+
* partial\_update.rb - Perform a screen render, then update that render with extra information.
|
51
52
|
|
52
53
|
## Full Documentation
|
53
54
|
YARD docs included, also available on [RubyDoc.info](https://www.rubydoc.info/github/sarahemm/ruby-syncsign/master)
|
data/lib/syncsign.rb
CHANGED
@@ -6,4 +6,12 @@ require 'syncsign/hub.rb'
|
|
6
6
|
require 'syncsign/node.rb'
|
7
7
|
require 'syncsign/node-display.rb'
|
8
8
|
require 'syncsign/template.rb'
|
9
|
-
require 'syncsign/
|
9
|
+
require 'syncsign/widget-core.rb'
|
10
|
+
require 'syncsign/widgets/symbolbox-symbols.rb'
|
11
|
+
require 'syncsign/widgets/buttonlabels.rb'
|
12
|
+
require 'syncsign/widgets/circle.rb'
|
13
|
+
require 'syncsign/widgets/line.rb'
|
14
|
+
require 'syncsign/widgets/qrcode.rb'
|
15
|
+
require 'syncsign/widgets/rectangle.rb'
|
16
|
+
require 'syncsign/widgets/symbolbox.rb'
|
17
|
+
require 'syncsign/widgets/textbox.rb'
|
@@ -5,8 +5,10 @@ module SyncSign
|
|
5
5
|
##
|
6
6
|
# Render a template to this display.
|
7
7
|
# @param template [Template] Template to render to this display.
|
8
|
-
|
9
|
-
|
8
|
+
# @param partial [Boolean] Specifies that this should be a partial update,
|
9
|
+
# leaving any information already on the screen in place.
|
10
|
+
def render(template: nil, partial: false)
|
11
|
+
@service.api_call(type: :post, path: "/nodes/#{@id}/renders", data: template.to_s(partial: partial), node: self, direct: @service.direct_rendering?)
|
10
12
|
end
|
11
13
|
|
12
14
|
##
|
data/lib/syncsign/template.rb
CHANGED
@@ -37,20 +37,24 @@ module SyncSign
|
|
37
37
|
|
38
38
|
##
|
39
39
|
# Output this template as JSON in the format that the SyncSign service understands.
|
40
|
-
|
40
|
+
# @param partial [Boolean] Whether to omit the background, which leaves
|
41
|
+
# any information already on-screen in place.
|
42
|
+
def to_s(partial: false)
|
41
43
|
background = {
|
42
44
|
bgColor: @bgcolour.to_s.upcase,
|
43
45
|
enableButtonZone: @enable_buttons
|
44
46
|
}
|
45
47
|
items = @items.collect { |item| item.to_a }
|
46
48
|
options = {'pollRate': @pollrate}
|
47
|
-
{
|
49
|
+
tmpl = {
|
48
50
|
layout: {
|
49
51
|
background: background,
|
50
52
|
items: items,
|
51
53
|
options: options
|
52
54
|
}
|
53
|
-
}
|
55
|
+
}
|
56
|
+
tmpl[:layout].delete(:background) if partial
|
57
|
+
tmpl.to_json
|
54
58
|
end
|
55
59
|
end
|
56
60
|
end
|
data/lib/syncsign/version.rb
CHANGED
@@ -0,0 +1,76 @@
|
|
1
|
+
module SyncSign
|
2
|
+
##
|
3
|
+
# Raised when UI elements are not properly aligned.
|
4
|
+
# Several UI elements must be aligned to a multiple of 8 or corruption will
|
5
|
+
# occur on the display.
|
6
|
+
class AlignmentException < StandardError
|
7
|
+
end
|
8
|
+
|
9
|
+
##
|
10
|
+
# Widgets are UI elements that are placed onto a +Template+ for rendering.
|
11
|
+
class Widget
|
12
|
+
##
|
13
|
+
# An item that contains only x/y coordinates. This can't be used on its own, only its
|
14
|
+
# superclasses can be added to templates.
|
15
|
+
class Item
|
16
|
+
# @return [Integer] horizontal position of the item.
|
17
|
+
attr_accessor :x
|
18
|
+
# @return [Integer] vertical position of the item.
|
19
|
+
attr_accessor :y
|
20
|
+
|
21
|
+
##
|
22
|
+
# Initialize a new Item widget.
|
23
|
+
# @param x [Integer] The horizontal position of the item.
|
24
|
+
# @param y [Integer] The vertical position of the item.
|
25
|
+
def initialize(x: nil, y: nil)
|
26
|
+
@x = x
|
27
|
+
@y = y
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
##
|
32
|
+
# A box that contains x/y coordinates, width and height, and colour information.
|
33
|
+
# This can't be used on its own, only its superclasses can be added to templates.
|
34
|
+
# You may be looking for +Rectangle+ if you want to draw rectangles.
|
35
|
+
class Box < Item
|
36
|
+
# @return [Integer] the width of the box.
|
37
|
+
attr_accessor :width
|
38
|
+
# @return [Integer] the height of the box.
|
39
|
+
attr_accessor :height
|
40
|
+
# @return [Symbol] the stroke or foreground colour of the box.
|
41
|
+
attr_accessor :colour
|
42
|
+
# @return [Symbol] the background colour of the box.
|
43
|
+
attr_accessor :bgcolour
|
44
|
+
|
45
|
+
def initialize(x: nil, y: nil, width: nil, height: nil, colour: :black, bgcolour: :white)
|
46
|
+
Widget::check_colours [colour, bgcolour]
|
47
|
+
@colour = colour
|
48
|
+
@bgcolour = bgcolour
|
49
|
+
@width = width
|
50
|
+
@height = height
|
51
|
+
super(x: x, y: y)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
##
|
56
|
+
# Check a set of colours to make sure they're all valid.
|
57
|
+
# Will raise ArgumentError if any elements are not valid colours.
|
58
|
+
# @param colours [Array] An array of symbols to check.
|
59
|
+
def self.check_colours(colours)
|
60
|
+
colours.each do |colour|
|
61
|
+
next if [:white, :black, :red].include? colour
|
62
|
+
raise ArgumentError, "Colour must be :white, :black, or :red."
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Check a set of patterns to make sure they're all valid.
|
67
|
+
# Will raise ArgumentError if any elements are not valid patterns.
|
68
|
+
# @param patterns [Array] An array of symbols to check.
|
69
|
+
def self.check_patterns(patterns)
|
70
|
+
patterns.each do |pattern|
|
71
|
+
next if [:solid, :interleave, :dash_tiny, :dash_medium, :dash_wide, :none].include? pattern
|
72
|
+
raise ArgumentError, "Pattern must be :solid, :interleave, :dash_tiny, :dash_medium, :dash_wide, or :none."
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module SyncSign
|
2
|
+
class Widget
|
3
|
+
##
|
4
|
+
# A widget that draws button labels for the 4.2" display.
|
5
|
+
class ButtonLabels
|
6
|
+
# @return [Array] Up to 4 strings of 17 characters each, to label the buttons with.
|
7
|
+
attr_accessor :labels
|
8
|
+
# @return [Array] Up to 4 boolean values showing whether each button should be reverse colours.
|
9
|
+
attr_accessor :reversed
|
10
|
+
|
11
|
+
##
|
12
|
+
# Initialize a new Button Labels widget.
|
13
|
+
# @param labels [Array] Up to 4 strings of 17 characters each, to label the buttons with.
|
14
|
+
# @param reversed [Array] Up to 4 boolean values showing whether each button should be reverse colours (white on black). Default is black on white.
|
15
|
+
def initialize(labels: [], reversed: [])
|
16
|
+
# TODO: validate <= 17 characters in each label
|
17
|
+
@labels = labels
|
18
|
+
@reversed = reversed
|
19
|
+
end
|
20
|
+
|
21
|
+
##
|
22
|
+
# Convert the widget into an array for sending to the SyncSign service.
|
23
|
+
def to_a
|
24
|
+
label_arr = []
|
25
|
+
(0..3).each do |idx|
|
26
|
+
label_arr[idx] = {
|
27
|
+
:title => @labels[idx] || "",
|
28
|
+
:style => @reversed[idx] || 'DISABLED'
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
{
|
33
|
+
'type': 'BOTTOM_CUSTOM_BUTTONS',
|
34
|
+
'data': {
|
35
|
+
'list': label_arr
|
36
|
+
}
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
def ==(other)
|
41
|
+
@labels == other.labels &&
|
42
|
+
@reversed == other.reversed
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module SyncSign
|
2
|
+
class Widget
|
3
|
+
##
|
4
|
+
# A widget that draws a circle.
|
5
|
+
class Circle < Item
|
6
|
+
attr_accessor :radius, :bgcolour, :colour, :fillpattern, :strokepattern
|
7
|
+
|
8
|
+
##
|
9
|
+
# Initialize a new circle widget.
|
10
|
+
# @param x [Integer] horizontal position of the centre of the circle.
|
11
|
+
# @param y [Integer] vertical position of the centre of the circle
|
12
|
+
# @param radius [Integer] The radius of the circle in pixels.
|
13
|
+
# @param colour [Symbol] The stroke colour used for the circle
|
14
|
+
# (either black, white, or red).
|
15
|
+
# @param bgcolour [Symbol] The fill colour used for the circle
|
16
|
+
# (either black, white, or red).
|
17
|
+
# @param fillpattern [Symbol] The fill pattern to use when filling the circle.
|
18
|
+
# @param strokepattern [Symbol] The stroke pattern to use when drawing the circle.
|
19
|
+
# @param pen_width [Integer] The thickness in pixels of the stroke.
|
20
|
+
def initialize(x: nil, y: nil, radius: nil, bgcolour: :white, colour: :black, fillpattern: :none, strokepattern: :solid, pen_width: 1)
|
21
|
+
Widget::check_colours [colour, bgcolour]
|
22
|
+
Widget::check_patterns [fillpattern, strokepattern]
|
23
|
+
@radius = radius
|
24
|
+
@colour = colour
|
25
|
+
@bgcolour = bgcolour
|
26
|
+
@fillpattern = fillpattern
|
27
|
+
@strokepattern = strokepattern
|
28
|
+
@pen_width = pen_width
|
29
|
+
super(x: x, y:y)
|
30
|
+
end
|
31
|
+
|
32
|
+
##
|
33
|
+
# Convert the widget into an array for sending to the SyncSign service.
|
34
|
+
def to_a
|
35
|
+
{
|
36
|
+
'type': 'CIRCLE',
|
37
|
+
'data': {
|
38
|
+
'center': {x: @x, y: @y},
|
39
|
+
'fillColor': @bgcolour.to_s.upcase,
|
40
|
+
'fillPattern': @fillpattern.to_s.upcase,
|
41
|
+
'strokeColor': @colour.to_s.upcase,
|
42
|
+
'strokePattern': @strokepattern.to_s.upcase,
|
43
|
+
'strokeThickness': @pen_width
|
44
|
+
}
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
def ==(other)
|
49
|
+
@x == other.x &&
|
50
|
+
@y == other.x &&
|
51
|
+
@width == other.width &&
|
52
|
+
@height == other.height &&
|
53
|
+
@radius == other.radius &&
|
54
|
+
@bgcolour == other.bgcolour &&
|
55
|
+
@colour == other.colour &&
|
56
|
+
@fillpattern == other.fillpattern &&
|
57
|
+
@strokepattern == other.strokepattern &&
|
58
|
+
@pen_width == other.pen_width
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module SyncSign
|
2
|
+
class Widget
|
3
|
+
##
|
4
|
+
# A widget that draws a line.
|
5
|
+
class Line
|
6
|
+
attr_accessor :x0, :y0, :x1, :y1, :bgcolour, :colour, :pattern
|
7
|
+
|
8
|
+
##
|
9
|
+
# Initialize a new line widget.
|
10
|
+
# @param x0 [Integer] horizontal position of the starting point of the line.
|
11
|
+
# @param y0 [Integer] vertical position of the starting point of the line.
|
12
|
+
# @param x1 [Integer] horizontal position of the ending point of the line.
|
13
|
+
# @param y1 [Integer] vertical position of the ending point of the line.
|
14
|
+
# @param colour [Symbol] The stroke colour used for the rectangle
|
15
|
+
# (either black, white, or red).
|
16
|
+
# @param bgcolour [Symbol] The fill colour used for the rectangle
|
17
|
+
# (either black, white, or red).
|
18
|
+
# @param pattern [Symbol] The linestyle to use when drawing the line, one of solid, interleave, dash_tiny, dash_mid, or dash_wide.
|
19
|
+
def initialize(x0: nil, y0: nil, x1: nil, y1: nil, bgcolour: :white, colour: :black, pattern: :solid)
|
20
|
+
Widget::check_colours [colour, bgcolour]
|
21
|
+
Widget::check_patterns [pattern]
|
22
|
+
@x0 = x0
|
23
|
+
@y0 = y0
|
24
|
+
@x1 = x1
|
25
|
+
@y1 = y1
|
26
|
+
@colour = colour
|
27
|
+
@bgcolour = bgcolour
|
28
|
+
@pattern = pattern
|
29
|
+
end
|
30
|
+
|
31
|
+
##
|
32
|
+
# Convert the widget into an array for sending to the SyncSign service.
|
33
|
+
def to_a
|
34
|
+
{
|
35
|
+
'type': 'LINE',
|
36
|
+
'data': {
|
37
|
+
'block': {x0: @x0, y0: @y0, x1: @x1, y1: @y1},
|
38
|
+
'backgroundColor': @bgcolour.to_s.upcase,
|
39
|
+
'lineColor': @colour.to_s.upcase,
|
40
|
+
'linePattern': @pattern.to_s.upcase
|
41
|
+
}
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
def ==(other)
|
46
|
+
@x0 == other.x0 &&
|
47
|
+
@y0 == other.y0 &&
|
48
|
+
@x1 == other.x1 &&
|
49
|
+
@y1 == other.y1 &&
|
50
|
+
@bgcolour == other.bgcolour &&
|
51
|
+
@colour == other.colour &&
|
52
|
+
@pattern == other.pattern
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module SyncSign
|
2
|
+
class Widget
|
3
|
+
# A widget that draws a QR code.
|
4
|
+
class QRCode < Item
|
5
|
+
# @return [Integer] scale of the QR code (how many pixels to use to
|
6
|
+
# represent each base pixel).
|
7
|
+
attr_accessor :scale
|
8
|
+
# @return [Integer] the version (which is actually size, in QR-speak)
|
9
|
+
# of this QR code.
|
10
|
+
attr_accessor :version
|
11
|
+
# @return [Symbol] the level of error checking code for this QR code,
|
12
|
+
# either :low, :medium, :quartile, or :high.
|
13
|
+
attr_accessor :ecclevel
|
14
|
+
# @return [String] the text to encode in this QR code.
|
15
|
+
attr_accessor :text
|
16
|
+
|
17
|
+
##
|
18
|
+
# Initialize a new QR code widget.
|
19
|
+
# @param x [Integer] horizontal position of the left side of the QR code.
|
20
|
+
# @param y [Integer] vertical position of the top of the QR code.
|
21
|
+
# @param scale [Integer] scale of the QR code (how many pixels to use to
|
22
|
+
# represent each base pixel).
|
23
|
+
# @param version [Integer] the version (which is actually size, in QR-speak)
|
24
|
+
# of this QR code.
|
25
|
+
# @param ecclevel [Symbol] the level of error checking code for this QR code,
|
26
|
+
# either :low, :medium, :quartile, or :high.
|
27
|
+
# @param text [String] the text to encode in this QR code.
|
28
|
+
def initialize(x: nil, y: nil, scale: 4, version: 2, ecclevel: :medium, text: nil)
|
29
|
+
@scale = scale
|
30
|
+
@version = version
|
31
|
+
@ecclevel = ecclevel
|
32
|
+
@text = text
|
33
|
+
|
34
|
+
super(x: x, y: y)
|
35
|
+
end
|
36
|
+
|
37
|
+
##
|
38
|
+
# Convert the widget into an array for sending to the SyncSign service.
|
39
|
+
def to_a
|
40
|
+
{
|
41
|
+
'type': 'QRCODE',
|
42
|
+
'data': {
|
43
|
+
'scale': @scale,
|
44
|
+
'eccLevel': @ecclevel.to_s.upcase,
|
45
|
+
'version': @version,
|
46
|
+
'position': {x: @x, y: @y},
|
47
|
+
'text': @text
|
48
|
+
}
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
def ==(other)
|
53
|
+
@x == other.x &&
|
54
|
+
@y == other.y &&
|
55
|
+
@scale == other.scale &&
|
56
|
+
@version == other.version &&
|
57
|
+
@ecclevel == other.ecclevel &&
|
58
|
+
@text == other.text
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module SyncSign
|
2
|
+
class Widget
|
3
|
+
##
|
4
|
+
# A widget that draws a rectangle.
|
5
|
+
class Rectangle < Box
|
6
|
+
attr_accessor :pen_width
|
7
|
+
|
8
|
+
##
|
9
|
+
# Initialize a new rectangle widget.
|
10
|
+
# @param x [Integer] horizontal position of the left side of the rectangle.
|
11
|
+
# @param y [Integer] vertical position of the top of the rectangle.
|
12
|
+
# @param width [Integer] how wide the rectangle should be.
|
13
|
+
# @param height [Integer] how tall the rectangle should be.
|
14
|
+
# @param colour [Symbol] The stroke colour used for the rectangle
|
15
|
+
# (either black, white, or red).
|
16
|
+
# @param bgcolour [Symbol] The fill colour used for the rectangle
|
17
|
+
# (either black, white, or red).
|
18
|
+
# @param pen_width [Integer] The width in pixels of the stroke.
|
19
|
+
def initialize(x: nil, y: nil, width: nil, height: nil, colour: :black, bgcolour: :white, pen_width: 1, fillpattern: :none, strokepattern: :solid)
|
20
|
+
Widget::check_patterns [fillpattern, strokepattern]
|
21
|
+
raise(AlignmentException, "Rect: x and width must both be a multiple of 8") if x % 8 != 0 or width % 8 != 0
|
22
|
+
@pen_width = pen_width
|
23
|
+
@fillpattern = fillpattern
|
24
|
+
@strokepattern = strokepattern
|
25
|
+
super(x: x, y: y, width: width, height: height, colour: colour, bgcolour: bgcolour)
|
26
|
+
end
|
27
|
+
|
28
|
+
##
|
29
|
+
# Convert the widget into an array for sending to the SyncSign service.
|
30
|
+
def to_a
|
31
|
+
{
|
32
|
+
'type': 'RECTANGLE',
|
33
|
+
'data': {
|
34
|
+
'block': {x: @x, y: @y, w: @width, h: @height},
|
35
|
+
'fillColor': @bgcolour.to_s.upcase,
|
36
|
+
'fillPattern': @fillpattern.to_s.upcase,
|
37
|
+
'strokeColor': @colour.to_s.upcase,
|
38
|
+
'strokePattern': @strokepattern.to_s.upcase,
|
39
|
+
'strokeThickness': @pen_width
|
40
|
+
}
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
def ==(other)
|
45
|
+
@x == other.x &&
|
46
|
+
@y == other.y &&
|
47
|
+
@width == other.width &&
|
48
|
+
@height == other.height &&
|
49
|
+
@colour == other.colour &&
|
50
|
+
@bgcolour == other.bgcolour &&
|
51
|
+
@pen_width == other.pen_width &&
|
52
|
+
@fillpattern == other.fillpattern &&
|
53
|
+
@strokepattern == other.strokepattern
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|