awtrix_control 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/lib/awtrix_control/app.rb +471 -0
- data/lib/awtrix_control/device.rb +195 -0
- data/lib/awtrix_control/request.rb +33 -0
- data/lib/awtrix_control.rb +35 -0
- data/lib/spec/awtrix_control/app_spec.rb +661 -0
- data/lib/spec/awtrix_control/device_spec.rb +246 -0
- data/lib/spec/awtrix_control_spec.rb +6 -0
- data/lib/spec/spec_helper.rb +33 -0
- metadata +65 -0
@@ -0,0 +1,246 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe AwtrixControl::Device do
|
6
|
+
before do
|
7
|
+
@device = AwtrixControl::Device.new(DEFAULT_HOST)
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '#initialize' do
|
11
|
+
it 'initializes instance variables' do
|
12
|
+
expect(@device.host).to eq(DEFAULT_HOST)
|
13
|
+
expect(@device.apps).to eq({})
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#<<' do
|
18
|
+
it 'adds an app instance to the device' do
|
19
|
+
app = AwtrixControl::App.new(:test_app)
|
20
|
+
@device << app
|
21
|
+
actual = @device.apps[:test_app]
|
22
|
+
expect(actual).to eq(app)
|
23
|
+
expect(app.device).to eq(@device)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#[]' do
|
28
|
+
it 'returns an app instance' do
|
29
|
+
@device.new_app(:test_app)
|
30
|
+
app = @device[:test_app]
|
31
|
+
expect(app.name).to eq(:test_app)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'returns nil if the app does not exist' do
|
35
|
+
app = @device[:test_app]
|
36
|
+
expect(app).to be_nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '#effects' do
|
41
|
+
it 'makes a call to the effects endpoint of the device' do
|
42
|
+
actual = JSON.parse(@device.effects)
|
43
|
+
expect(actual.first).to eq('Fade')
|
44
|
+
expect_request(method: :get, path: 'effects')
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe '#indicator' do
|
49
|
+
it 'renders a white indicator by default' do
|
50
|
+
@device.indicator(:top)
|
51
|
+
expect_request(method: :post, path: 'indicator1', body: { color: '#ffffff' })
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'tells the device to show a given indicator in a given color' do
|
55
|
+
@device.indicator(:bottom, '#00FF00')
|
56
|
+
expect_request(method: :post, path: 'indicator3', body: { color: '#00FF00' })
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'works with shorthand color symbols' do
|
60
|
+
@device.indicator(:top, :red)
|
61
|
+
expect_request(method: :post, path: 'indicator1', body: { color: '#ff0000' })
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'with effects' do
|
66
|
+
it 'renders a blinking indicator' do
|
67
|
+
@device.indicator(:center, :red, effect: :blink)
|
68
|
+
expect_request(method: :post, path: 'indicator2', body: { color: '#ff0000', blink: 500 })
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'renders a pulsing indicator' do
|
72
|
+
@device.indicator(:center, :red, effect: :pulse)
|
73
|
+
expect_request(method: :post, path: 'indicator2', body: { color: '#ff0000', fade: 2000 })
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'renders a blinking indicator with a custom frequency' do
|
77
|
+
@device.indicator(:center, :red, effect: :blink, frequency: 1000)
|
78
|
+
expect_request(method: :post, path: 'indicator2', body: { color: '#ff0000', blink: 1000 })
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'renders a pulsing indicator with a custom frequency' do
|
82
|
+
@device.indicator(:center, :red, effect: :pulse, frequency: 5000)
|
83
|
+
expect_request(method: :post, path: 'indicator2', body: { color: '#ff0000', fade: 5000 })
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe '#loop' do
|
88
|
+
it 'makes a call to the loop endpoint of the device' do
|
89
|
+
actual = @device.loop
|
90
|
+
expect(actual).to eq({ "Hello" => 1, "Time" => 0, "World" => 2 })
|
91
|
+
expect_request(method: :get, path: 'loop')
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe '#new_app' do
|
96
|
+
it 'instantiates a new app and adds it to the device' do
|
97
|
+
@device.new_app('test_app')
|
98
|
+
actual = @device.apps['test_app']
|
99
|
+
expect(actual.name).to eq('test_app')
|
100
|
+
expect(actual.payload).to eq(AwtrixControl::App.new('test_app').default_payload)
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'overwrites an existing app' do
|
104
|
+
@device.new_app('test_app')
|
105
|
+
second_app = @device.new_app('test_app')
|
106
|
+
actual = @device.apps['test_app']
|
107
|
+
expect(actual).to eq(second_app)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe '#notify' do
|
112
|
+
it 'makes a call to the notify endpoint of the device' do
|
113
|
+
@device.notify('test_notification', color: :red)
|
114
|
+
expect_request(method: :post, path: 'notify', body: { text: 'test_notification', color: "#ff0000" })
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
describe '#power' do
|
119
|
+
it 'makes a call to the power endpoint of the device' do
|
120
|
+
@device.power(true)
|
121
|
+
expect_request(method: :post, path: 'power', body: { power: true })
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe '#remove_indicator' do
|
126
|
+
it 'removes an indicator from the device' do
|
127
|
+
@device.remove_indicator(:top)
|
128
|
+
expect_request(method: :post, path: 'indicator1', body: { color: '#000000' })
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
describe '#remove_indicators' do
|
133
|
+
it 'removes all indicators from the device' do
|
134
|
+
@device.remove_indicators
|
135
|
+
expect_request(method: :post, path: 'indicator1', body: { color: '#000000' })
|
136
|
+
expect_request(method: :post, path: 'indicator2', body: { color: '#000000' })
|
137
|
+
expect_request(method: :post, path: 'indicator3', body: { color: '#000000' })
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
describe '#reset' do
|
142
|
+
it 'makes the device sleep for 1 second' do
|
143
|
+
@device.reset
|
144
|
+
expect_request(method: :post, path: 'sleep', body: { sleep: 1 })
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
describe '#rtttl' do
|
149
|
+
it 'makes a call to the rtttl endpoint of the device' do
|
150
|
+
@device.rtttl('test_rtttl')
|
151
|
+
expect_request(method: :post, path: 'rtttl', body: '"test_rtttl"')
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
describe '#screen' do
|
156
|
+
it 'makes a call to the screen endpoint of the device' do
|
157
|
+
actual = JSON.parse(@device.screen)
|
158
|
+
expect(actual).to start_with(0, 0, 0, 0, 0)
|
159
|
+
expect_request(method: :get, path: 'screen')
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
describe '#sleep' do
|
164
|
+
it 'makes the device sleep for a number of seconds' do
|
165
|
+
@device.sleep(5)
|
166
|
+
expect_request(method: :post, path: 'sleep', body: { sleep: 5 })
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'makes the device sleep indefinitely when no seconds are provided' do
|
170
|
+
@device.sleep
|
171
|
+
expect_request(method: :post, path: 'sleep', body: {})
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
describe '#sound' do
|
176
|
+
it 'makes a call to the sound endpoint of the device' do
|
177
|
+
@device.sound('test_sound')
|
178
|
+
expect_request(method: :post, path: 'sound', body: { sound: 'test_sound' })
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
describe '#stats' do
|
183
|
+
it 'makes a call to the status endpoint of the device' do
|
184
|
+
actual = JSON.parse(@device.stats)["version"]
|
185
|
+
expect(actual).to eq('0.96')
|
186
|
+
expect_request(method: :get, path: 'stats')
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
describe '#transitions' do
|
191
|
+
it 'makes a call to the transitions endpoint of the device' do
|
192
|
+
actual = JSON.parse(@device.transitions).first
|
193
|
+
expect(actual).to eq('Random')
|
194
|
+
expect_request(method: :get, path: 'transitions')
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
describe '#delete_app' do
|
199
|
+
it 'deletes an app by name' do
|
200
|
+
app = AwtrixControl::App.new('test_app')
|
201
|
+
@device << app
|
202
|
+
@device.delete_app('test_app')
|
203
|
+
expect(@device.apps).to eq({})
|
204
|
+
expect_request(method: :post, path: 'custom?name=test_app', body: {})
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
describe '#delete_all_apps' do
|
209
|
+
it 'deletes all apps from the device and device, even if they do not match' do
|
210
|
+
app1 = AwtrixControl::App.new('test_app1')
|
211
|
+
@device << app1
|
212
|
+
@device.delete_all_apps
|
213
|
+
expect_request(method: :get, path: 'loop')
|
214
|
+
# The loop endpoint is mocked with the following apps:
|
215
|
+
expect_request(method: :post, path: 'custom?name=Time')
|
216
|
+
expect_request(method: :post, path: 'custom?name=Hello')
|
217
|
+
expect_request(method: :post, path: 'custom?name=World')
|
218
|
+
expect(@device.apps).to eq({})
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
def expect_request(method:, path:, host: DEFAULT_HOST, body: {})
|
223
|
+
expect(WebMock)
|
224
|
+
.to have_requested(method, "http://#{host}/api/#{path}")
|
225
|
+
.with(body: body)
|
226
|
+
end
|
227
|
+
|
228
|
+
describe '#push_app' do
|
229
|
+
it 'pushes an app to the device by name' do
|
230
|
+
app = @device.new_app(:test_app)
|
231
|
+
@device.push_app(:test_app)
|
232
|
+
expect_request(method: :post,
|
233
|
+
path: 'custom?name=test_app',
|
234
|
+
body: { "name": "test_app" }.merge(app.default_payload))
|
235
|
+
|
236
|
+
end
|
237
|
+
|
238
|
+
it 'does not push apps from other devices' do
|
239
|
+
other_device = AwtrixControl::Device.new('192.168.0.2')
|
240
|
+
app = other_device.new_app(:test_app)
|
241
|
+
@device.push_app(:test_app)
|
242
|
+
|
243
|
+
expect(WebMock).not_to have_requested(:post, "http://#{DEFAULT_HOST}/api/custom")
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
Bundler.setup
|
3
|
+
|
4
|
+
require 'awtrix_control'
|
5
|
+
require 'webmock/rspec'
|
6
|
+
|
7
|
+
# Disable external requests
|
8
|
+
WebMock.disable_net_connect!(allow_localhost: true)
|
9
|
+
|
10
|
+
DEFAULT_HOST = '1.1.1.1'
|
11
|
+
|
12
|
+
# Global stubs
|
13
|
+
RSpec.configure do |config|
|
14
|
+
config.before(:each) do
|
15
|
+
stub_request(:get, %r{http://#{DEFAULT_HOST}/api/.*})
|
16
|
+
.to_return do |request|
|
17
|
+
path = request.uri.path.split('/').last
|
18
|
+
file_path = File.join('spec', 'fixtures', "get_#{path}.json")
|
19
|
+
{
|
20
|
+
status: 200,
|
21
|
+
body: File.read(file_path),
|
22
|
+
headers: { 'Content-Type' => 'application/json' }
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
stub_request(:post, %r{http://#{DEFAULT_HOST}/api/.*})
|
27
|
+
.to_return(
|
28
|
+
status: 200,
|
29
|
+
body: "OK",
|
30
|
+
headers: { 'Content-Type' => 'application/json' }
|
31
|
+
)
|
32
|
+
end
|
33
|
+
end
|
metadata
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: awtrix_control
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Francois Gaspard
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-09-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.0'
|
27
|
+
description: A gem to control AWTRIX 3 devices from Ruby
|
28
|
+
email:
|
29
|
+
- fr@ncois.email
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- lib/awtrix_control.rb
|
35
|
+
- lib/awtrix_control/app.rb
|
36
|
+
- lib/awtrix_control/device.rb
|
37
|
+
- lib/awtrix_control/request.rb
|
38
|
+
- lib/spec/awtrix_control/app_spec.rb
|
39
|
+
- lib/spec/awtrix_control/device_spec.rb
|
40
|
+
- lib/spec/awtrix_control_spec.rb
|
41
|
+
- lib/spec/spec_helper.rb
|
42
|
+
homepage: https://github.com/Francois-gaspard/awtrix
|
43
|
+
licenses:
|
44
|
+
- MIT
|
45
|
+
metadata: {}
|
46
|
+
post_install_message:
|
47
|
+
rdoc_options: []
|
48
|
+
require_paths:
|
49
|
+
- lib
|
50
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.3'
|
55
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '0'
|
60
|
+
requirements: []
|
61
|
+
rubygems_version: 3.5.17
|
62
|
+
signing_key:
|
63
|
+
specification_version: 4
|
64
|
+
summary: Control AWTRIX 3 devices
|
65
|
+
test_files: []
|