trmnl-api 0.6.1 → 0.7.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5cfbabf5898c2d22a9c6ec94054d5a6aacea3f7f67665075657869a4fb60f5c1
4
- data.tar.gz: 683715537fcbe499691d19cfb4f8fe50a63d2ac9c4783fa82b8a9c44630c096e
3
+ metadata.gz: f9fb20c5a06061df12d534be39e9d165b7774a7854f35c6c3b89ee4021f6831c
4
+ data.tar.gz: 30da4deb5099f07f3c23be8e093cc7e926718545919d2ecdd06c035006649a30
5
5
  SHA512:
6
- metadata.gz: 983d4a70dc3421c50eb008cdcd7784a6c26d03e8e2bc012d50948201073fa3ed887e3bad7d2b4033f9a3067fe32ee003ee8fb34b710c872d4db386cdfd8cd764
7
- data.tar.gz: 42ec614353a7193a95ecdc38400abf95b6cb4d17f54704d6a689b2b5b7a8f05b3593735924df3e7f557388d736037db08547481629818b56047143bbfaed65f8
6
+ metadata.gz: eaa11f3d4ba80ce5eae39682e952536a1b05f1577d856e217028a8164b44b5d123ae188700c3b096205ca743dbb3b291cea7643094678f49f81a28c96bd42719
7
+ data.tar.gz: fd5cb1d4372bbce29288d3d466b730223f51d4fca707ab9b432eb79cb987140a8ac6767ca49d60aa6a2e3100a8a422c3bab77be1137fc6463d1d180d0c49d73d
checksums.yaml.gz.sig CHANGED
Binary file
data/README.adoc CHANGED
@@ -82,6 +82,24 @@ Any/all environment changes will be applied unless you override these settings v
82
82
 
83
83
  === Endpoints
84
84
 
85
+ ==== Categories
86
+
87
+ Allows you to obtain the list of approved plugin categories. Example:
88
+
89
+ [source,ruby]
90
+ ----
91
+ client = TRMNL::API::Client.new
92
+ client.categories
93
+
94
+ # Success(
95
+ # [
96
+ # "analytics",
97
+ # "art",
98
+ # "calendar"
99
+ # ]
100
+ # )
101
+ ----
102
+
85
103
  ==== Current Screen
86
104
 
87
105
  Allows you to obtain current screen being displayed for your device. You must supply your device's API token as the `token`. Example:
@@ -135,6 +153,29 @@ client.firmware
135
153
  # Success(#<data TRMNL::API::Models::Firmware url="https://trmnl-fw.s3.us-east-2.amazonaws.com/FW1.4.8.bin", version="1.4.8">)
136
154
  ----
137
155
 
156
+ ==== IP Addresses
157
+
158
+ Allows you obtain a list of public IP addresses for all TRMNL core servers because plugin poll requests will only originate from these IPs. Example:
159
+
160
+ [source,ruby]
161
+ ----
162
+ client = TRMNL::API::Client.new
163
+ client.ip_addresses
164
+
165
+ # Success(
166
+ # #<data TRMNL::API::Models::IPAddress
167
+ # version_4=[
168
+ # #<IPAddr: IPv4:111.230.59.36/255.255.255.255>,
169
+ # #<IPAddr: IPv4:222.9.106.45/255.255.255.255>
170
+ # ],
171
+ # version_6=[
172
+ # #<IPAddr: IPv6:1:2:0400:00d0:0000:0000:1874:e001/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff>,
173
+ # #<IPAddr: IPv6:1:2:0400:00d1:0000:0001:705e:1001/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff>
174
+ # ]
175
+ # >
176
+ # )
177
+ ----
178
+
138
179
  ==== Log
139
180
 
140
181
  Allows you to create a log entry (which is what the device reports when it captures an error). You must supply your device's API token as the `token`. Example:
@@ -188,6 +229,7 @@ client.models
188
229
  # name="test",
189
230
  # label="Test",
190
231
  # description="A test.",
232
+ # kind="trmnl",
191
233
  # colors=2,
192
234
  # bit_depth=1,
193
235
  # scale_factor=1,
@@ -197,13 +239,66 @@ client.models
197
239
  # height=480,
198
240
  # offset_x=10,
199
241
  # offset_y=15,
200
- # published_at="2025-07-16T18:18:11+00:00"
242
+ # palette_ids=["bw"],
243
+ # css: {
244
+ # classes: {
245
+ # device: "screen--og_png",
246
+ # size: "screen--md"
247
+ # },
248
+ # variables: [
249
+ # [
250
+ # "--screen-w",
251
+ # "800px"
252
+ # ],
253
+ # [
254
+ # "--screen-h",
255
+ # "480px"
256
+ # ],
257
+ # [
258
+ # "--ui-scale",
259
+ # "1.0"
260
+ # ],
261
+ # [
262
+ # "--gap-scale",
263
+ # "1.0"
264
+ # ]
265
+ # ]
266
+ # }
201
267
  # >
202
268
  # )
203
269
  ----
204
270
 
205
271
  ℹ️ The `scale_factor` can be an integer or float.
206
272
 
273
+ ==== Palettes
274
+
275
+ Allows you to obtain palettes details. The IDs correlate to the `palette_ids` as found in the Models API. Example:
276
+
277
+ [source,ruby]
278
+ ----
279
+ client = TRMNL::API::Client.new
280
+ client.palettes
281
+
282
+ Success(
283
+ [
284
+ #<data TRMNL::API::Models::Palette
285
+ id="bw",
286
+ name="Black & White (1-bit)",
287
+ grays=2,
288
+ colors=nil,
289
+ framework_class="screen--1bit"
290
+ >,
291
+ #<data TRMNL::API::Models::Palette
292
+ id="color-24bit",
293
+ name="Color (24-bit)",
294
+ grays=nil,
295
+ colors=nil,
296
+ framework_class=""
297
+ >
298
+ ]
299
+ )
300
+ ----
301
+
207
302
  ==== Setup
208
303
 
209
304
  Allows you to obtain the setup response for when a new device is setup. You must supply your device's MAC Address as the `id`. Example:
@@ -9,20 +9,26 @@ module TRMNL
9
9
  include Dependencies[:settings]
10
10
 
11
11
  include Endpoints::Dependencies[
12
+ endpoint_categories: :categories,
12
13
  endpoint_current_screen: :current_screen,
13
14
  endpoint_display: :display,
14
15
  endpoint_firmware: :firmware,
16
+ endpoint_ip_addresses: :ip_addresses,
15
17
  endpoint_log: :log,
16
18
  endpoint_models: :models,
19
+ endpoint_palettes: :palettes,
17
20
  endpoint_setup: :setup
18
21
  ]
19
22
 
20
23
  include Inspectable[
24
+ endpoint_categories: :class,
21
25
  endpoint_current_screen: :class,
22
26
  endpoint_display: :class,
23
27
  endpoint_firmware: :class,
28
+ endpoint_ip_addresses: :class,
24
29
  endpoint_log: :class,
25
30
  endpoint_models: :class,
31
+ endpoint_palettes: :class,
26
32
  endpoint_setup: :class
27
33
  ]
28
34
 
@@ -31,16 +37,22 @@ module TRMNL
31
37
  yield settings if block_given?
32
38
  end
33
39
 
40
+ def categories = endpoint_categories.call
41
+
34
42
  def current_screen(**) = endpoint_current_screen.call(**)
35
43
 
36
44
  def display(**) = endpoint_display.call(**)
37
45
 
38
46
  def firmware = endpoint_firmware.call
39
47
 
48
+ def ip_addresses = endpoint_ip_addresses.call
49
+
40
50
  def log(**) = endpoint_log.call(**)
41
51
 
42
52
  def models(**) = endpoint_models.call(**)
43
53
 
54
+ def palettes = endpoint_palettes.call
55
+
44
56
  def setup(**) = endpoint_setup.call(**)
45
57
  end
46
58
  end
@@ -20,10 +20,13 @@ module TRMNL
20
20
  end
21
21
 
22
22
  namespace :contracts do
23
+ register :category, Contracts::Category
23
24
  register :current_screen, Contracts::CurrentScreen
24
25
  register :display, Contracts::Display
25
26
  register :firmware, Contracts::Firmware
27
+ register :ip_address, Contracts::IPAddress
26
28
  register :model, Contracts::Model
29
+ register :palette, Contracts::Palette
27
30
  register :setup, Contracts::Setup
28
31
  end
29
32
 
@@ -31,7 +34,9 @@ module TRMNL
31
34
  register :current_screen, Models::CurrentScreen
32
35
  register :display, Models::Display
33
36
  register :firmware, Models::Firmware
37
+ register :ip_address, Models::IPAddress
34
38
  register :model, Models::Model
39
+ register :palette, Models::Palette
35
40
  register :setup, Models::Setup
36
41
  end
37
42
  end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/schema"
4
+
5
+ module TRMNL
6
+ module API
7
+ module Contracts
8
+ # Validates API response.
9
+ Category = Dry::Schema.JSON { required(:data).array(:string) }
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/schema"
4
+
5
+ module TRMNL
6
+ module API
7
+ module Contracts
8
+ # Validates API response.
9
+ IPAddress = Dry::Schema.JSON do
10
+ required(:data).hash do
11
+ required(:ipv4).array(Types::IPAddress)
12
+ required(:ipv6).array(Types::IPAddress)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -21,7 +21,15 @@ module TRMNL
21
21
  required(:height).filled :integer
22
22
  required(:offset_x).filled :integer
23
23
  required(:offset_y).filled :integer
24
- required(:published_at).filled :time
24
+ required(:palette_ids).array(:string)
25
+ optional(:css).hash do
26
+ optional(:classes).hash do
27
+ required(:device).filled :string
28
+ required(:size).filled :string
29
+ end
30
+
31
+ optional(:variables).filled(Types::CSSVariables)
32
+ end
25
33
  end
26
34
  end
27
35
  end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/schema"
4
+
5
+ module TRMNL
6
+ module API
7
+ module Contracts
8
+ # Validates API response.
9
+ Palette = Dry::Schema.JSON do
10
+ required(:data).array(:hash) do
11
+ required(:id).filled :string
12
+ required(:name).filled :string
13
+ optional(:grays).maybe :integer
14
+ optional(:colors).maybe(:array)
15
+ optional(:framework_class).maybe :string
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "inspectable"
4
+ require "pipeable"
5
+
6
+ module TRMNL
7
+ module API
8
+ module Endpoints
9
+ # Handles API request/response.
10
+ class Category
11
+ include TRMNL::API::Dependencies[:requester, contract: "contracts.category"]
12
+
13
+ include Inspectable[contract: :class]
14
+ include Pipeable
15
+
16
+ def call
17
+ pipe(
18
+ requester.get("categories"),
19
+ try(:parse, catch: JSON::ParserError),
20
+ validate(contract, as: :to_h),
21
+ as(:fetch, :data)
22
+ )
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -9,11 +9,14 @@ module TRMNL
9
9
  module Container
10
10
  extend Containable
11
11
 
12
+ register(:categories) { Category.new }
12
13
  register(:current_screen) { CurrentScreen.new }
13
14
  register(:display) { Display.new }
14
15
  register(:firmware) { Firmware.new }
16
+ register(:ip_addresses) { IPAddress.new }
15
17
  register(:log) { Log.new }
16
18
  register(:models) { Model.new }
19
+ register(:palettes) { Palette.new }
17
20
  register(:setup) { Setup.new }
18
21
  end
19
22
  end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "inspectable"
4
+ require "pipeable"
5
+
6
+ module TRMNL
7
+ module API
8
+ module Endpoints
9
+ # Handles API request/response.
10
+ class IPAddress
11
+ include TRMNL::API::Dependencies[
12
+ :requester,
13
+ contract: "contracts.ip_address",
14
+ model: "models.ip_address"
15
+ ]
16
+
17
+ include Inspectable[contract: :class]
18
+ include Pipeable
19
+
20
+ def call
21
+ pipe requester.get("ips"),
22
+ try(:parse, catch: JSON::ParserError),
23
+ validate(contract, as: :to_h),
24
+ as(:fetch, :data),
25
+ to(model, :for)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "inspectable"
4
+ require "pipeable"
5
+
6
+ module TRMNL
7
+ module API
8
+ module Endpoints
9
+ # Handles API request/response.
10
+ class Palette
11
+ include TRMNL::API::Dependencies[
12
+ :requester,
13
+ contract: "contracts.palette",
14
+ model: "models.palette"
15
+ ]
16
+
17
+ include Inspectable[contract: :class]
18
+ include Pipeable
19
+
20
+ def call
21
+ pipe(
22
+ requester.get("palettes"),
23
+ try(:parse, catch: JSON::ParserError),
24
+ validate(contract, as: :to_h),
25
+ as(:fetch, :data),
26
+ map { |data| model.for(**data) }
27
+ )
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TRMNL
4
+ module API
5
+ module Models
6
+ # IPs API response.
7
+ IPAddress = Data.define :version_4, :version_6 do
8
+ def self.for attributes
9
+ new(**attributes.transform_keys(ipv4: :version_4, ipv6: :version_6))
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -18,7 +18,8 @@ module TRMNL
18
18
  :height,
19
19
  :offset_x,
20
20
  :offset_y,
21
- :published_at
21
+ :palette_ids,
22
+ :css
22
23
  ) do
23
24
  def self.for(attributes) = new(**attributes)
24
25
 
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TRMNL
4
+ module API
5
+ module Models
6
+ # IPs API response.
7
+ Palette = Data.define :id, :name, :grays, :colors, :framework_class do
8
+ def self.for(attributes) = new(**attributes)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/types"
4
+ require "ipaddr"
5
+
6
+ module TRMNL
7
+ module API
8
+ # A collection of custom types.
9
+ module Types
10
+ include Dry.Types(default: :strict)
11
+
12
+ CSSVariables = Dry::Types["array"].of(
13
+ Dry::Types["array"].constrained(filled: true, size: 2).of(Dry::Types["coercible.string"])
14
+ )
15
+
16
+ IPAddress = Constructor IPAddr
17
+ end
18
+ end
19
+ end
data/lib/trmnl/api.rb CHANGED
@@ -6,7 +6,7 @@ require "zeitwerk"
6
6
  Dry::Schema.load_extensions :monads
7
7
 
8
8
  Zeitwerk::Loader.new.then do |loader|
9
- loader.inflector.inflect "api" => "API", "trmnl" => "TRMNL"
9
+ loader.inflector.inflect "api" => "API", "ip_address" => "IPAddress", "trmnl" => "TRMNL"
10
10
  loader.tag = "trmnl-api"
11
11
  loader.push_dir "#{__dir__}/.."
12
12
  loader.setup
data/trmnl-api.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = "trmnl-api"
5
- spec.version = "0.6.1"
5
+ spec.version = "0.7.0"
6
6
  spec.authors = ["TRMNL"]
7
7
  spec.email = ["engineering@usetrmnl.com"]
8
8
  spec.homepage = "https://github.com/usetrmnl/trmnl-api"
@@ -27,6 +27,7 @@ Gem::Specification.new do |spec|
27
27
  spec.add_dependency "containable", "~> 1.2"
28
28
  spec.add_dependency "dry-monads", "~> 1.8"
29
29
  spec.add_dependency "dry-schema", "~> 1.14"
30
+ spec.add_dependency "dry-types", "~> 1.8"
30
31
  spec.add_dependency "http", "~> 5.3"
31
32
  spec.add_dependency "infusible", "~> 4.3"
32
33
  spec.add_dependency "inspectable", "~> 0.3"
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trmnl-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - TRMNL
@@ -91,6 +91,20 @@ dependencies:
91
91
  - - "~>"
92
92
  - !ruby/object:Gem::Version
93
93
  version: '1.14'
94
+ - !ruby/object:Gem::Dependency
95
+ name: dry-types
96
+ requirement: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - "~>"
99
+ - !ruby/object:Gem::Version
100
+ version: '1.8'
101
+ type: :runtime
102
+ prerelease: false
103
+ version_requirements: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - "~>"
106
+ - !ruby/object:Gem::Version
107
+ version: '1.8'
94
108
  - !ruby/object:Gem::Dependency
95
109
  name: http
96
110
  requirement: !ruby/object:Gem::Requirement
@@ -190,26 +204,35 @@ files:
190
204
  - lib/trmnl/api/configuration/content.rb
191
205
  - lib/trmnl/api/configuration/loader.rb
192
206
  - lib/trmnl/api/container.rb
207
+ - lib/trmnl/api/contracts/category.rb
193
208
  - lib/trmnl/api/contracts/current_screen.rb
194
209
  - lib/trmnl/api/contracts/display.rb
195
210
  - lib/trmnl/api/contracts/firmware.rb
211
+ - lib/trmnl/api/contracts/ip_address.rb
196
212
  - lib/trmnl/api/contracts/model.rb
213
+ - lib/trmnl/api/contracts/palette.rb
197
214
  - lib/trmnl/api/contracts/setup.rb
198
215
  - lib/trmnl/api/dependencies.rb
216
+ - lib/trmnl/api/endpoints/category.rb
199
217
  - lib/trmnl/api/endpoints/container.rb
200
218
  - lib/trmnl/api/endpoints/current_screen.rb
201
219
  - lib/trmnl/api/endpoints/dependencies.rb
202
220
  - lib/trmnl/api/endpoints/display.rb
203
221
  - lib/trmnl/api/endpoints/firmware.rb
222
+ - lib/trmnl/api/endpoints/ip_address.rb
204
223
  - lib/trmnl/api/endpoints/log.rb
205
224
  - lib/trmnl/api/endpoints/model.rb
225
+ - lib/trmnl/api/endpoints/palette.rb
206
226
  - lib/trmnl/api/endpoints/setup.rb
207
227
  - lib/trmnl/api/models/current_screen.rb
208
228
  - lib/trmnl/api/models/display.rb
209
229
  - lib/trmnl/api/models/firmware.rb
230
+ - lib/trmnl/api/models/ip_address.rb
210
231
  - lib/trmnl/api/models/model.rb
232
+ - lib/trmnl/api/models/palette.rb
211
233
  - lib/trmnl/api/models/setup.rb
212
234
  - lib/trmnl/api/requester.rb
235
+ - lib/trmnl/api/types.rb
213
236
  - trmnl-api.gemspec
214
237
  homepage: https://github.com/usetrmnl/trmnl-api
215
238
  licenses:
@@ -235,7 +258,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
235
258
  - !ruby/object:Gem::Version
236
259
  version: '0'
237
260
  requirements: []
238
- rubygems_version: 3.7.2
261
+ rubygems_version: 4.0.1
239
262
  specification_version: 4
240
263
  summary: A monadic TRMNL API client.
241
264
  test_files: []
metadata.gz.sig CHANGED
Binary file