trmnl-api 0.0.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 +7 -0
- checksums.yaml.gz.sig +0 -0
- data/LICENSE +21 -0
- data/README.adoc +211 -0
- data/lib/trmnl/api/client.rb +39 -0
- data/lib/trmnl/api/configuration/content.rb +12 -0
- data/lib/trmnl/api/configuration/loader.rb +26 -0
- data/lib/trmnl/api/container.rb +36 -0
- data/lib/trmnl/api/contracts/current_screen.rb +16 -0
- data/lib/trmnl/api/contracts/display.rb +20 -0
- data/lib/trmnl/api/contracts/firmware.rb +15 -0
- data/lib/trmnl/api/contracts/setup.rb +17 -0
- data/lib/trmnl/api/dependencies.rb +10 -0
- data/lib/trmnl/api/endpoints/current_screen.rb +27 -0
- data/lib/trmnl/api/endpoints/display.rb +22 -0
- data/lib/trmnl/api/endpoints/firmware.rb +22 -0
- data/lib/trmnl/api/endpoints/log.rb +14 -0
- data/lib/trmnl/api/endpoints/setup.rb +22 -0
- data/lib/trmnl/api/models/current_screen.rb +12 -0
- data/lib/trmnl/api/models/display.rb +39 -0
- data/lib/trmnl/api/models/firmware.rb +12 -0
- data/lib/trmnl/api/models/setup.rb +12 -0
- data/lib/trmnl/api.rb +22 -0
- data/trmnl-api.gemspec +37 -0
- data.tar.gz.sig +0 -0
- metadata +207 -0
- metadata.gz.sig +0 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 0ba1eee66530c227b2e43b24de28e6913753d4f627af3d979c3add5cbba3846c
|
4
|
+
data.tar.gz: da5463562b79f6b883f90925cb61ffc44b357c3e64eec615f5cbb0a433f3a36a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 03430a130bfa5a302b67c674ece3951b88e0629f256c7937351d562a7f52117b7b0a0704817fbda6a4d771ee0ddd59542f80e9cccd5970c6ab5a8dfe1e9be0ba
|
7
|
+
data.tar.gz: 71d6d93f75797dad4ef0ae37e6b454d65adcff265149de1f6e32175ae7d5970b4aa590283eed5d95ae93ccfad89672c1a835ce4529af8e1ea5d53a4844a5f532
|
checksums.yaml.gz.sig
ADDED
Binary file
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2025 TRMNL
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.adoc
ADDED
@@ -0,0 +1,211 @@
|
|
1
|
+
:toc: macro
|
2
|
+
:toclevels: 5
|
3
|
+
:figure-caption!:
|
4
|
+
|
5
|
+
:trmnl_link: link:https://usetrmnl.com[TRMNL]
|
6
|
+
:dry_monads_link: link:https://dry-rb.org/gems/dry-monads[Dry Monads]
|
7
|
+
|
8
|
+
= TRMNL API
|
9
|
+
|
10
|
+
A monadic {trmnl_link} API client. You can use this client in your own code to interact with our APIs for any/all devices that you own.
|
11
|
+
|
12
|
+
toc::[]
|
13
|
+
|
14
|
+
== Features
|
15
|
+
|
16
|
+
* Provides {trmnl_link} API access.
|
17
|
+
|
18
|
+
== Requirements
|
19
|
+
|
20
|
+
. link:https://www.ruby-lang.org[Ruby].
|
21
|
+
. A {trmnl_link} device (physical or virtual).
|
22
|
+
|
23
|
+
== Setup
|
24
|
+
|
25
|
+
To install, run:
|
26
|
+
|
27
|
+
[source,bash]
|
28
|
+
----
|
29
|
+
gem install trmnl-api
|
30
|
+
----
|
31
|
+
|
32
|
+
You can also add the gem directly to your project:
|
33
|
+
|
34
|
+
[source,bash]
|
35
|
+
----
|
36
|
+
bundle add trmnl-api
|
37
|
+
----
|
38
|
+
|
39
|
+
Once the gem is installed, you only need to require it:
|
40
|
+
|
41
|
+
[source,ruby]
|
42
|
+
----
|
43
|
+
require "trmnl/api"
|
44
|
+
----
|
45
|
+
|
46
|
+
== Usage
|
47
|
+
|
48
|
+
This client provides access to multiple endpoints. Each endpoint will answer either a `Success` or `Failure` (as provided by {dry_monads_link}) based on result of the API call. This allows you pattern match in your own code when using each endpoint. Example:
|
49
|
+
|
50
|
+
``` ruby
|
51
|
+
case endpoint.call token: "secret"
|
52
|
+
in Success(payload) then puts payload
|
53
|
+
in Failure(response) then puts response
|
54
|
+
else puts "Unknown HTTP response."
|
55
|
+
end
|
56
|
+
```
|
57
|
+
|
58
|
+
See each endpoint for further details.
|
59
|
+
|
60
|
+
=== Environment
|
61
|
+
|
62
|
+
You can configure the client via the following environment variables:
|
63
|
+
|
64
|
+
* `TRMNL_API_CONTENT_TYPE`: Defines the HTTP `Content-Type` header. You shouldn't need to change this but is here if you need it. Default: "application/json".
|
65
|
+
* `TRMNL_API_URI`: Defines the API URI. Default: "https://trmnl.app/api".
|
66
|
+
|
67
|
+
Any/all environment changes will be applied to all endpoint objects.
|
68
|
+
|
69
|
+
=== Current Screen
|
70
|
+
|
71
|
+
Allows you to obtain current screen being displayed for your device. You must supply your device's API token as the `token`. Example:
|
72
|
+
|
73
|
+
[source,ruby]
|
74
|
+
----
|
75
|
+
endpoint = TRMNL::API::Endpoints::CurrentScreen.new
|
76
|
+
endpoint.call token: "secret"
|
77
|
+
|
78
|
+
# Success(
|
79
|
+
# #<data TRMNL::API::Models::CurrentScreen
|
80
|
+
# refresh_rate=1773,
|
81
|
+
# image_url="https://usetrmnl.com/plugin-2025-04-10T11-34-38Z-380c77",
|
82
|
+
# filename="plugin-2025-04-10T11-34-38Z-380c77"
|
83
|
+
# >
|
84
|
+
# )
|
85
|
+
----
|
86
|
+
|
87
|
+
=== Display
|
88
|
+
|
89
|
+
Allows you to obtain current screen being displayed for your device. You must supply your device's API token as the `token`. Example:
|
90
|
+
|
91
|
+
[source,ruby]
|
92
|
+
----
|
93
|
+
endpoint = TRMNL::API::Endpoints::Display.new
|
94
|
+
endpoint.call token: "secret"
|
95
|
+
|
96
|
+
# Success(
|
97
|
+
# #<struct TRMNL::API::Models::Display
|
98
|
+
# filename="plugin-1745348489",
|
99
|
+
# firmware_url="https://trmnl-fw.s3.us-east-2.amazonaws.com/FW1.4.8.bin",
|
100
|
+
# image_url="https://trmnl.s3.us-east-2.amazonaws.com/plugin-1745348489",
|
101
|
+
# image_url_timeout=0,
|
102
|
+
# refresh_rate=1771,
|
103
|
+
# reset_firmware=false,
|
104
|
+
# special_function="restart_playlist",
|
105
|
+
# update_firmware=true
|
106
|
+
# >
|
107
|
+
# )
|
108
|
+
----
|
109
|
+
|
110
|
+
=== Firmware
|
111
|
+
|
112
|
+
Allows you to obtain the current stable firmware version. Example:
|
113
|
+
|
114
|
+
[source,ruby]
|
115
|
+
----
|
116
|
+
endpoint = TRMNL::API::Endpoints::Firmware.new
|
117
|
+
endpoint.call
|
118
|
+
|
119
|
+
# Success(#<data TRMNL::API::Models::Firmware url="https://trmnl-fw.s3.us-east-2.amazonaws.com/FW1.4.8.bin", version="1.4.8">)
|
120
|
+
----
|
121
|
+
|
122
|
+
=== Log
|
123
|
+
|
124
|
+
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:
|
125
|
+
|
126
|
+
[source,ruby]
|
127
|
+
----
|
128
|
+
endpoint = TRMNL::API::Endpoints::Log.new
|
129
|
+
endpoint.call token: "secret",
|
130
|
+
log: {
|
131
|
+
logs_array: [
|
132
|
+
{
|
133
|
+
log_id: 1,
|
134
|
+
creation_timestamp: 1742022124,
|
135
|
+
log_message: "returned code is not OK: 404",
|
136
|
+
log_codeline: 597,
|
137
|
+
device_status_stamp: {
|
138
|
+
wifi_status: "connected",
|
139
|
+
wakeup_reason: "timer",
|
140
|
+
current_fw_version: "1.4.7",
|
141
|
+
free_heap_size: 160656,
|
142
|
+
special_function: "none",
|
143
|
+
refresh_rate: 30,
|
144
|
+
battery_voltage: 4.772,
|
145
|
+
time_since_last_sleep_start: 31,
|
146
|
+
wifi_rssi_level: -54
|
147
|
+
},
|
148
|
+
additional_info: {
|
149
|
+
retry_attempt: 1
|
150
|
+
},
|
151
|
+
log_sourcefile: "src/bl.cpp"
|
152
|
+
}
|
153
|
+
]
|
154
|
+
}
|
155
|
+
|
156
|
+
# Success(#<HTTP::Response/1.1 204 No Content...)
|
157
|
+
----
|
158
|
+
|
159
|
+
You'll either get a 204 No Content or 200 OK response depending on if the device exists or not.
|
160
|
+
|
161
|
+
=== Setup
|
162
|
+
|
163
|
+
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:
|
164
|
+
|
165
|
+
|
166
|
+
[source,ruby]
|
167
|
+
----
|
168
|
+
endpoint = TRMNL::API::Endpoints::Setup.new
|
169
|
+
endpoint.call id: "B0:81:84:22:BD:E8"
|
170
|
+
|
171
|
+
# Success(
|
172
|
+
# #<data TRMNL::API::Models::Setup
|
173
|
+
# api_key="secret",
|
174
|
+
# friendly_id="40DEF8",
|
175
|
+
# image_url="https://usetrmnl.com/images/setup/setup-logo.bmp",
|
176
|
+
# message="Register at usetrmnl.com/signup with Device ID '40DEF8'"
|
177
|
+
# >
|
178
|
+
# )
|
179
|
+
----
|
180
|
+
|
181
|
+
== Development
|
182
|
+
|
183
|
+
To contribute, run:
|
184
|
+
|
185
|
+
[source,bash]
|
186
|
+
----
|
187
|
+
git clone https://github.com/usetrmnl/trmnl-api
|
188
|
+
cd trmnl-api
|
189
|
+
bin/setup
|
190
|
+
----
|
191
|
+
|
192
|
+
You can also use the IRB console for direct access to all objects:
|
193
|
+
|
194
|
+
[source,bash]
|
195
|
+
----
|
196
|
+
bin/console
|
197
|
+
----
|
198
|
+
|
199
|
+
== Tests
|
200
|
+
|
201
|
+
To test, run:
|
202
|
+
|
203
|
+
[source,bash]
|
204
|
+
----
|
205
|
+
bin/rake
|
206
|
+
----
|
207
|
+
|
208
|
+
== Credits
|
209
|
+
|
210
|
+
* Built with link:https://alchemists.io/projects/gemsmith[Gemsmith].
|
211
|
+
* Engineered by link:https://usetrmnl.com/developers[TRMNL].
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/monads"
|
4
|
+
require "http"
|
5
|
+
|
6
|
+
module TRMNL
|
7
|
+
module API
|
8
|
+
# Provides a low level configurable and monadic API client.
|
9
|
+
# :reek:DataClump
|
10
|
+
class Client
|
11
|
+
include Dry::Monads[:result]
|
12
|
+
|
13
|
+
HEADERS = {}.freeze
|
14
|
+
|
15
|
+
def initialize settings: TRMNL::API::Configuration::Loader.new.call, http: HTTP
|
16
|
+
@settings = settings
|
17
|
+
@http = http
|
18
|
+
|
19
|
+
yield settings if block_given?
|
20
|
+
end
|
21
|
+
|
22
|
+
def get(path, headers: HEADERS, **params) = call(__method__, path, headers, params:)
|
23
|
+
|
24
|
+
def post(path, headers: HEADERS, **json) = call(__method__, path, headers, json:)
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
attr_reader :settings, :http
|
29
|
+
|
30
|
+
# rubocop:todo Metrics/ParameterLists
|
31
|
+
def call method, path, headers, **options
|
32
|
+
http.headers(settings.headers.merge(headers))
|
33
|
+
.public_send(method, "#{settings.uri}/#{path}", options)
|
34
|
+
.then { |response| response.status.success? ? Success(response) : Failure(response) }
|
35
|
+
end
|
36
|
+
# rubocop:enable Metrics/ParameterLists
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TRMNL
|
4
|
+
module API
|
5
|
+
module Configuration
|
6
|
+
# Provides API client configuration content.
|
7
|
+
Content = Struct.new :content_type, :uri do
|
8
|
+
def headers = {"Content-Type" => content_type}.compact
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TRMNL
|
4
|
+
module API
|
5
|
+
module Configuration
|
6
|
+
# Loads configuration based on environment or falls back to defaults.
|
7
|
+
class Loader
|
8
|
+
def initialize model: Content, environment: ENV
|
9
|
+
@model = model
|
10
|
+
@environment = environment
|
11
|
+
end
|
12
|
+
|
13
|
+
def call
|
14
|
+
model[
|
15
|
+
content_type: environment.fetch("TRMNL_API_CONTENT_TYPE", "application/json"),
|
16
|
+
uri: environment.fetch("TRMNL_API_URI", "https://trmnl.app/api")
|
17
|
+
]
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
attr_reader :model, :environment
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "cogger"
|
4
|
+
require "containable"
|
5
|
+
require "http"
|
6
|
+
|
7
|
+
module TRMNL
|
8
|
+
module API
|
9
|
+
# Registers application dependencies.
|
10
|
+
module Container
|
11
|
+
extend Containable
|
12
|
+
|
13
|
+
register(:client) { API::Client.new }
|
14
|
+
register(:logger) { Cogger.new id: "trmnl-api", formatter: :json }
|
15
|
+
|
16
|
+
register :http do
|
17
|
+
HTTP.default_options = ::HTTP::Options.new features: {logging: {logger: self[:logger]}}
|
18
|
+
HTTP
|
19
|
+
end
|
20
|
+
|
21
|
+
namespace :contracts do
|
22
|
+
register :current_screen, Contracts::CurrentScreen
|
23
|
+
register :display, Contracts::Display
|
24
|
+
register :firmware, Contracts::Firmware
|
25
|
+
register :setup, Contracts::Setup
|
26
|
+
end
|
27
|
+
|
28
|
+
namespace :models do
|
29
|
+
register :current_screen, Models::CurrentScreen
|
30
|
+
register :display, Models::Display
|
31
|
+
register :firmware, Models::Firmware
|
32
|
+
register :setup, Models::Setup
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,16 @@
|
|
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
|
+
CurrentScreen = Dry::Schema.JSON do
|
10
|
+
required(:refresh_rate).filled :integer
|
11
|
+
required(:image_url).filled :string
|
12
|
+
required(:filename).filled :string
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
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
|
+
Display = Dry::Schema.JSON do
|
10
|
+
required(:filename).filled :string
|
11
|
+
required(:firmware_url).filled :string
|
12
|
+
required(:image_url).filled :string
|
13
|
+
required(:refresh_rate).filled :integer
|
14
|
+
required(:reset_firmware).filled :bool
|
15
|
+
required(:special_function).filled :string
|
16
|
+
required(:update_firmware).filled :bool
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,15 @@
|
|
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
|
+
Firmware = Dry::Schema.JSON do
|
10
|
+
required(:url).filled :string
|
11
|
+
required(:version).filled :string
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
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
|
+
Setup = Dry::Schema.JSON do
|
10
|
+
required(:api_key).filled :string
|
11
|
+
required(:friendly_id).filled :string
|
12
|
+
required(:image_url).filled :string
|
13
|
+
required(:message).filled :string
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pipeable"
|
4
|
+
|
5
|
+
module TRMNL
|
6
|
+
module API
|
7
|
+
module Endpoints
|
8
|
+
# Handles API request/response.
|
9
|
+
class CurrentScreen
|
10
|
+
include Dependencies[
|
11
|
+
:client,
|
12
|
+
contract: "contracts.current_screen",
|
13
|
+
model: "models.current_screen"
|
14
|
+
]
|
15
|
+
|
16
|
+
include Pipeable
|
17
|
+
|
18
|
+
def call token:
|
19
|
+
pipe client.get("current_screen", headers: {"Access-Token" => token}),
|
20
|
+
try(:parse, catch: JSON::ParserError),
|
21
|
+
validate(contract, as: :to_h),
|
22
|
+
to(model, :for)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pipeable"
|
4
|
+
|
5
|
+
module TRMNL
|
6
|
+
module API
|
7
|
+
module Endpoints
|
8
|
+
# Handles API request/response.
|
9
|
+
class Display
|
10
|
+
include Dependencies[:client, contract: "contracts.display", model: "models.display"]
|
11
|
+
include Pipeable
|
12
|
+
|
13
|
+
def call token:
|
14
|
+
pipe client.get("display", headers: {"Access-Token" => token}),
|
15
|
+
try(:parse, catch: JSON::ParserError),
|
16
|
+
validate(contract, as: :to_h),
|
17
|
+
to(model, :for)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pipeable"
|
4
|
+
|
5
|
+
module TRMNL
|
6
|
+
module API
|
7
|
+
module Endpoints
|
8
|
+
# Handles API request/response.
|
9
|
+
class Firmware
|
10
|
+
include Dependencies[:client, contract: "contracts.firmware", model: "models.firmware"]
|
11
|
+
include Pipeable
|
12
|
+
|
13
|
+
def call
|
14
|
+
pipe client.get("firmware/latest"),
|
15
|
+
try(:parse, catch: JSON::ParserError),
|
16
|
+
validate(contract, as: :to_h),
|
17
|
+
to(model, :for)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TRMNL
|
4
|
+
module API
|
5
|
+
module Endpoints
|
6
|
+
# Handles API request/response.
|
7
|
+
class Log
|
8
|
+
include Dependencies[:client]
|
9
|
+
|
10
|
+
def call(token:, **) = client.post("log", headers: {"Access-Token" => token}, **)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pipeable"
|
4
|
+
|
5
|
+
module TRMNL
|
6
|
+
module API
|
7
|
+
module Endpoints
|
8
|
+
# Handles API request/response.
|
9
|
+
class Setup
|
10
|
+
include Dependencies[:client, contract: "contracts.setup", model: "models.setup"]
|
11
|
+
include Pipeable
|
12
|
+
|
13
|
+
def call id:
|
14
|
+
pipe client.get("setup", headers: {"ID" => id}),
|
15
|
+
try(:parse, catch: JSON::ParserError),
|
16
|
+
validate(contract, as: :to_h),
|
17
|
+
to(model, :for)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TRMNL
|
4
|
+
module API
|
5
|
+
module Models
|
6
|
+
# Models data for API display responses.
|
7
|
+
Display = Struct.new(
|
8
|
+
:filename,
|
9
|
+
:firmware_url,
|
10
|
+
:image_url,
|
11
|
+
:image_url_timeout,
|
12
|
+
:refresh_rate,
|
13
|
+
:reset_firmware,
|
14
|
+
:special_function,
|
15
|
+
:update_firmware
|
16
|
+
) do
|
17
|
+
def self.for(attributes) = new(**attributes)
|
18
|
+
|
19
|
+
def initialize(**)
|
20
|
+
super
|
21
|
+
apply_defaults
|
22
|
+
freeze
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_json(*) = to_h.to_json(*)
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def apply_defaults
|
30
|
+
self[:image_url_timeout] ||= 0
|
31
|
+
self[:refresh_rate] ||= 300
|
32
|
+
self[:reset_firmware] ||= false
|
33
|
+
self[:update_firmware] ||= false
|
34
|
+
self[:special_function] ||= "sleep"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/trmnl/api.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/schema"
|
4
|
+
require "zeitwerk"
|
5
|
+
|
6
|
+
Dry::Schema.load_extensions :monads
|
7
|
+
|
8
|
+
Zeitwerk::Loader.new.then do |loader|
|
9
|
+
loader.inflector.inflect "api" => "API", "trmnl" => "TRMNL"
|
10
|
+
loader.tag = "trmnl-api"
|
11
|
+
loader.push_dir "#{__dir__}/.."
|
12
|
+
loader.setup
|
13
|
+
end
|
14
|
+
|
15
|
+
module TRMNL
|
16
|
+
# Main namespace.
|
17
|
+
module API
|
18
|
+
def self.loader registry = Zeitwerk::Registry
|
19
|
+
@loader ||= registry.loaders.find { |loader| loader.tag == "trmnl-api" }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/trmnl-api.gemspec
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = "trmnl-api"
|
5
|
+
spec.version = "0.0.0"
|
6
|
+
spec.authors = ["TRMNL"]
|
7
|
+
spec.email = ["support@usetrmnl.com"]
|
8
|
+
spec.homepage = "https://github.com/usetrmnl/trmnl-api"
|
9
|
+
spec.summary = "A monadic TRMNL API client."
|
10
|
+
spec.license = "MIT"
|
11
|
+
|
12
|
+
spec.metadata = {
|
13
|
+
"bug_tracker_uri" => "https://github.com/usetrmnl/trmnl-api/issues",
|
14
|
+
"changelog_uri" => "https://github.com/usetrmnl/trmnl-api/tags",
|
15
|
+
"homepage_uri" => "https://github.com/usetrmnl/trmnl-api",
|
16
|
+
"label" => "TRMNL API",
|
17
|
+
"rubygems_mfa_required" => "true",
|
18
|
+
"source_code_uri" => "https://github.com/usetrmnl/trmnl-api"
|
19
|
+
}
|
20
|
+
|
21
|
+
spec.signing_key = Gem.default_key_path
|
22
|
+
spec.cert_chain = [Gem.default_cert_path]
|
23
|
+
|
24
|
+
spec.required_ruby_version = "~> 3.4"
|
25
|
+
|
26
|
+
spec.add_dependency "cogger", "~> 1.2"
|
27
|
+
spec.add_dependency "containable", "~> 1.2"
|
28
|
+
spec.add_dependency "dry-monads", "~> 1.8"
|
29
|
+
spec.add_dependency "dry-schema", "~> 1.14"
|
30
|
+
spec.add_dependency "http", "~> 5.2"
|
31
|
+
spec.add_dependency "infusible", "~> 4.3"
|
32
|
+
spec.add_dependency "pipeable", "~> 1.3"
|
33
|
+
spec.add_dependency "zeitwerk", "~> 2.7"
|
34
|
+
|
35
|
+
spec.extra_rdoc_files = Dir["README*", "LICENSE*"]
|
36
|
+
spec.files = Dir["*.gemspec", "lib/**/*"]
|
37
|
+
end
|
data.tar.gz.sig
ADDED
Binary file
|
metadata
ADDED
@@ -0,0 +1,207 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: trmnl-api
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- TRMNL
|
8
|
+
bindir: bin
|
9
|
+
cert_chain:
|
10
|
+
- |
|
11
|
+
-----BEGIN CERTIFICATE-----
|
12
|
+
MIIENjCCAp6gAwIBAgIBAjANBgkqhkiG9w0BAQsFADBBMQ8wDQYDVQQDDAZicm9v
|
13
|
+
a2UxGjAYBgoJkiaJk/IsZAEZFgphbGNoZW1pc3RzMRIwEAYKCZImiZPyLGQBGRYC
|
14
|
+
aW8wHhcNMjUwMzIyMTQ1NDE3WhcNMjYwMzIyMTQ1NDE3WjBBMQ8wDQYDVQQDDAZi
|
15
|
+
cm9va2UxGjAYBgoJkiaJk/IsZAEZFgphbGNoZW1pc3RzMRIwEAYKCZImiZPyLGQB
|
16
|
+
GRYCaW8wggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCro8tj5/E1Hg88
|
17
|
+
f4qfiwPVd2zJQHvdYt4GHVvuHRRgx4HGhJuNp+4BId08RBn7V6V1MW6MY3kezRBs
|
18
|
+
M+7QOQ4b1xNLTvY7FYQB1wGK5a4x7TTokDrPYQxDB2jmsdDYCzVbIMrAvUfcecRi
|
19
|
+
khyGZCdByiiCl4fKv77P12tTT+NfsvXkLt/AYCGwjOUyGKTQ01Z6eC09T27GayPH
|
20
|
+
QQvIkakyFgcJtzSyGzs8bzK5q9u7wQ12MNTjJoXzW69lqp0oNvDylu81EiSUb5S6
|
21
|
+
QzzPxZBiRB1sgtbt1gUbVI262ZDq1gR+HxPFmp+Cgt7ZLIJZAtesQvtcMzseXpfn
|
22
|
+
hpmm0Sw22KGhRAy/mqHBRhDl5HqS1SJp2Ko3lcnpXeFResp0HNlt8NSu13vhC08j
|
23
|
+
GUHU9MyIXbFOsnp3K3ADrAVjPWop8EZkmUR3MV/CUm00w2cZHCSGiXl1KMpiVKvk
|
24
|
+
Ywr1gd2ZME4QLSo+EXUtLxDUa/W3xnBS8dBOuMMz02FPWYr3PN8CAwEAAaM5MDcw
|
25
|
+
CQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFAFgmv0tYMZnItuPycSM
|
26
|
+
F5wykJEVMA0GCSqGSIb3DQEBCwUAA4IBgQBlzRfyAYx/fCFjizS0Npxw4+4T3aYL
|
27
|
+
hbXoDqQRWjxuhFZcXUymhz3r8/Ltyri9lSof8grzB+8/+mrMVms7Gwt5qolk6zdn
|
28
|
+
FkySGy/jmpN12ldOHFbBEnyVBZNBvOBVb8zkkw8PhiHdBdXOUm4Jy39yJvBLfjcC
|
29
|
+
iM1aeWPmgPy1GbvZU+leRGZLt6dRIR9oCDXcWLRjha8xLMoz6Yn9fJBYexBA3iEz
|
30
|
+
h5S7pn4AX/JhVRiSyl8pAy4jEKydpyQrliH3gHkpNmUS/XDczP+9xX1bAB4BvqL2
|
31
|
+
NCxMcQ+hiJNqCKpPgHxaOOHZfIxV33logIuPEQ8NryHAwZ9ZWnwtYDE8kQGGKskI
|
32
|
+
Kkm6QT474hZl7MpwiJjWgW313CR7jUEekQahX1QxCxHPI7LSrKpno0plH3uWIOQp
|
33
|
+
KUlkb9uyACBgyRO52ZHiDVI8YvtU5O/j9pSes9/3XgvBeC1onx4qWp+uRX7eVsYS
|
34
|
+
GiijocTc3enZVrXERetaXj8/9XWs3fB3HWY=
|
35
|
+
-----END CERTIFICATE-----
|
36
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
37
|
+
dependencies:
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: cogger
|
40
|
+
requirement: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - "~>"
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '1.2'
|
45
|
+
type: :runtime
|
46
|
+
prerelease: false
|
47
|
+
version_requirements: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - "~>"
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '1.2'
|
52
|
+
- !ruby/object:Gem::Dependency
|
53
|
+
name: containable
|
54
|
+
requirement: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - "~>"
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '1.2'
|
59
|
+
type: :runtime
|
60
|
+
prerelease: false
|
61
|
+
version_requirements: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - "~>"
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '1.2'
|
66
|
+
- !ruby/object:Gem::Dependency
|
67
|
+
name: dry-monads
|
68
|
+
requirement: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - "~>"
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '1.8'
|
73
|
+
type: :runtime
|
74
|
+
prerelease: false
|
75
|
+
version_requirements: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - "~>"
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '1.8'
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: dry-schema
|
82
|
+
requirement: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - "~>"
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '1.14'
|
87
|
+
type: :runtime
|
88
|
+
prerelease: false
|
89
|
+
version_requirements: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - "~>"
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '1.14'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: http
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - "~>"
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '5.2'
|
101
|
+
type: :runtime
|
102
|
+
prerelease: false
|
103
|
+
version_requirements: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - "~>"
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '5.2'
|
108
|
+
- !ruby/object:Gem::Dependency
|
109
|
+
name: infusible
|
110
|
+
requirement: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - "~>"
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '4.3'
|
115
|
+
type: :runtime
|
116
|
+
prerelease: false
|
117
|
+
version_requirements: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
119
|
+
- - "~>"
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '4.3'
|
122
|
+
- !ruby/object:Gem::Dependency
|
123
|
+
name: pipeable
|
124
|
+
requirement: !ruby/object:Gem::Requirement
|
125
|
+
requirements:
|
126
|
+
- - "~>"
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '1.3'
|
129
|
+
type: :runtime
|
130
|
+
prerelease: false
|
131
|
+
version_requirements: !ruby/object:Gem::Requirement
|
132
|
+
requirements:
|
133
|
+
- - "~>"
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: '1.3'
|
136
|
+
- !ruby/object:Gem::Dependency
|
137
|
+
name: zeitwerk
|
138
|
+
requirement: !ruby/object:Gem::Requirement
|
139
|
+
requirements:
|
140
|
+
- - "~>"
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: '2.7'
|
143
|
+
type: :runtime
|
144
|
+
prerelease: false
|
145
|
+
version_requirements: !ruby/object:Gem::Requirement
|
146
|
+
requirements:
|
147
|
+
- - "~>"
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '2.7'
|
150
|
+
email:
|
151
|
+
- support@usetrmnl.com
|
152
|
+
executables: []
|
153
|
+
extensions: []
|
154
|
+
extra_rdoc_files:
|
155
|
+
- LICENSE
|
156
|
+
- README.adoc
|
157
|
+
files:
|
158
|
+
- LICENSE
|
159
|
+
- README.adoc
|
160
|
+
- lib/trmnl/api.rb
|
161
|
+
- lib/trmnl/api/client.rb
|
162
|
+
- lib/trmnl/api/configuration/content.rb
|
163
|
+
- lib/trmnl/api/configuration/loader.rb
|
164
|
+
- lib/trmnl/api/container.rb
|
165
|
+
- lib/trmnl/api/contracts/current_screen.rb
|
166
|
+
- lib/trmnl/api/contracts/display.rb
|
167
|
+
- lib/trmnl/api/contracts/firmware.rb
|
168
|
+
- lib/trmnl/api/contracts/setup.rb
|
169
|
+
- lib/trmnl/api/dependencies.rb
|
170
|
+
- lib/trmnl/api/endpoints/current_screen.rb
|
171
|
+
- lib/trmnl/api/endpoints/display.rb
|
172
|
+
- lib/trmnl/api/endpoints/firmware.rb
|
173
|
+
- lib/trmnl/api/endpoints/log.rb
|
174
|
+
- lib/trmnl/api/endpoints/setup.rb
|
175
|
+
- lib/trmnl/api/models/current_screen.rb
|
176
|
+
- lib/trmnl/api/models/display.rb
|
177
|
+
- lib/trmnl/api/models/firmware.rb
|
178
|
+
- lib/trmnl/api/models/setup.rb
|
179
|
+
- trmnl-api.gemspec
|
180
|
+
homepage: https://github.com/usetrmnl/trmnl-api
|
181
|
+
licenses:
|
182
|
+
- MIT
|
183
|
+
metadata:
|
184
|
+
bug_tracker_uri: https://github.com/usetrmnl/trmnl-api/issues
|
185
|
+
changelog_uri: https://github.com/usetrmnl/trmnl-api/tags
|
186
|
+
homepage_uri: https://github.com/usetrmnl/trmnl-api
|
187
|
+
label: TRMNL API
|
188
|
+
rubygems_mfa_required: 'true'
|
189
|
+
source_code_uri: https://github.com/usetrmnl/trmnl-api
|
190
|
+
rdoc_options: []
|
191
|
+
require_paths:
|
192
|
+
- lib
|
193
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
194
|
+
requirements:
|
195
|
+
- - "~>"
|
196
|
+
- !ruby/object:Gem::Version
|
197
|
+
version: '3.4'
|
198
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
199
|
+
requirements:
|
200
|
+
- - ">="
|
201
|
+
- !ruby/object:Gem::Version
|
202
|
+
version: '0'
|
203
|
+
requirements: []
|
204
|
+
rubygems_version: 3.6.8
|
205
|
+
specification_version: 4
|
206
|
+
summary: A monadic TRMNL API client.
|
207
|
+
test_files: []
|
metadata.gz.sig
ADDED
Binary file
|