prusalink 0.1.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
- data/CHANGELOG.md +5 -0
- data/LICENSE.txt +21 -0
- data/README.md +170 -0
- data/lib/prusalink/auto_initializable.rb +224 -0
- data/lib/prusalink/base_resource.rb +92 -0
- data/lib/prusalink/client.rb +190 -0
- data/lib/prusalink/deserializable.rb +491 -0
- data/lib/prusalink/digest_auth.rb +80 -0
- data/lib/prusalink/exceptions.rb +36 -0
- data/lib/prusalink/files/file.rb +87 -0
- data/lib/prusalink/files/folder.rb +84 -0
- data/lib/prusalink/files/refs.rb +36 -0
- data/lib/prusalink/files.rb +184 -0
- data/lib/prusalink/info.rb +82 -0
- data/lib/prusalink/job/file.rb +70 -0
- data/lib/prusalink/job.rb +191 -0
- data/lib/prusalink/server_version.rb +70 -0
- data/lib/prusalink/status/camera.rb +26 -0
- data/lib/prusalink/status/job.rb +41 -0
- data/lib/prusalink/status/printer.rb +136 -0
- data/lib/prusalink/status/storage.rb +40 -0
- data/lib/prusalink/status/transfer.rb +40 -0
- data/lib/prusalink/status.rb +64 -0
- data/lib/prusalink/storage.rb +87 -0
- data/lib/prusalink/transfer.rb +108 -0
- data/lib/prusalink/types.rb +27 -0
- data/lib/prusalink/version.rb +7 -0
- data/lib/prusalink.rb +77 -0
- data/lib/tapioca/dsl/compilers/auto_initializable.rb +88 -0
- metadata +158 -0
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Prusalink
|
|
5
|
+
# The printer's current job.
|
|
6
|
+
#
|
|
7
|
+
# @example Inspect and control the current job
|
|
8
|
+
# job = Prusalink::Job.get # => nil when the printer is idle
|
|
9
|
+
# job.state # => "PRINTING"
|
|
10
|
+
# job.progress # => 42.0
|
|
11
|
+
# job.file.full_path # => "/usb/SPICE~1.gco"
|
|
12
|
+
# job.pause
|
|
13
|
+
#
|
|
14
|
+
# @example Control a job by id
|
|
15
|
+
# Prusalink::Job.stop(420)
|
|
16
|
+
class Job < BaseResource
|
|
17
|
+
extend T::Sig
|
|
18
|
+
include AutoInitializable
|
|
19
|
+
include Deserializable
|
|
20
|
+
|
|
21
|
+
resource_path("/api/v1/job")
|
|
22
|
+
|
|
23
|
+
# @!attribute [r] id
|
|
24
|
+
# @return [Integer] The job's id
|
|
25
|
+
auto_attr :id, type: Integer
|
|
26
|
+
|
|
27
|
+
# @!attribute [r] state
|
|
28
|
+
# @return [String] One of "PRINTING", "PAUSED", "FINISHED", "STOPPED" or "ERROR"
|
|
29
|
+
auto_attr :state, type: String
|
|
30
|
+
|
|
31
|
+
# @!attribute [r] progress
|
|
32
|
+
# @return [Float] Completion, in percent
|
|
33
|
+
auto_attr :progress, type: Float
|
|
34
|
+
|
|
35
|
+
# @!attribute [r] time_remaining
|
|
36
|
+
# @return [Integer, nil] Estimated time left, in seconds
|
|
37
|
+
auto_attr :time_remaining, type: Integer
|
|
38
|
+
|
|
39
|
+
# @!attribute [r] time_printing
|
|
40
|
+
# @return [Integer] Time spent printing, in seconds
|
|
41
|
+
auto_attr :time_printing, type: Integer
|
|
42
|
+
|
|
43
|
+
# @!attribute [r] inaccurate_estimates
|
|
44
|
+
# @return [Boolean, nil] Whether the time estimates are inaccurate
|
|
45
|
+
auto_attr :inaccurate_estimates, type: T::Boolean
|
|
46
|
+
|
|
47
|
+
# @!attribute [r] serial_print
|
|
48
|
+
# @return [Boolean, nil] Whether the printer is printing from the serial line (no file is then available)
|
|
49
|
+
auto_attr :serial_print, type: T::Boolean
|
|
50
|
+
|
|
51
|
+
# @!attribute [r] file
|
|
52
|
+
# @return [Job::File, nil] The file being printed, absent for serial prints
|
|
53
|
+
auto_attr :file, type: File
|
|
54
|
+
|
|
55
|
+
# @!attribute [r] extra
|
|
56
|
+
# @return [Hash] Any additional fields returned by the API
|
|
57
|
+
auto_attr :extra, type: Hash
|
|
58
|
+
|
|
59
|
+
auto_initialize!
|
|
60
|
+
|
|
61
|
+
deserialize_config do
|
|
62
|
+
nested :file, File
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
class << self
|
|
66
|
+
extend T::Sig
|
|
67
|
+
|
|
68
|
+
# Retrieve the current job.
|
|
69
|
+
#
|
|
70
|
+
# @return [Job, nil] nil when there is no job (the printer answers 204 No Content)
|
|
71
|
+
# @raise [Prusalink::Exceptions::Error] if the request fails
|
|
72
|
+
sig { returns(T.nilable(Job)) }
|
|
73
|
+
def get
|
|
74
|
+
fetch_resource
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Stop the job with the given id.
|
|
78
|
+
#
|
|
79
|
+
# @param id [Integer] The job's id
|
|
80
|
+
# @return [Boolean] true on success
|
|
81
|
+
# @raise [Prusalink::Exceptions::NotFoundError] if no job has this id
|
|
82
|
+
# @raise [Prusalink::Exceptions::ConflictError] if the job can't be stopped in its current state
|
|
83
|
+
sig { params(id: Integer).returns(T::Boolean) }
|
|
84
|
+
def stop(id)
|
|
85
|
+
delete(path: job_path(id))
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Pause the job with the given id.
|
|
89
|
+
#
|
|
90
|
+
# @param id [Integer] The job's id
|
|
91
|
+
# @return [Boolean] true on success
|
|
92
|
+
# @raise [Prusalink::Exceptions::NotFoundError] if no job has this id
|
|
93
|
+
# @raise [Prusalink::Exceptions::ConflictError] if the job can't be paused in its current state
|
|
94
|
+
sig { params(id: Integer).returns(T::Boolean) }
|
|
95
|
+
def pause(id)
|
|
96
|
+
put(path: job_path(id, "pause"))
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Resume the paused job with the given id.
|
|
100
|
+
#
|
|
101
|
+
# @param id [Integer] The job's id
|
|
102
|
+
# @return [Boolean] true on success
|
|
103
|
+
# @raise [Prusalink::Exceptions::NotFoundError] if no job has this id
|
|
104
|
+
# @raise [Prusalink::Exceptions::ConflictError] if the job isn't paused
|
|
105
|
+
sig { params(id: Integer).returns(T::Boolean) }
|
|
106
|
+
def resume(id)
|
|
107
|
+
put(path: job_path(id, "resume"))
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Continue the job with the given id after a timelapse capture.
|
|
111
|
+
#
|
|
112
|
+
# @param id [Integer] The job's id
|
|
113
|
+
# @return [Boolean] true on success
|
|
114
|
+
# @raise [Prusalink::Exceptions::NotFoundError] if no job has this id
|
|
115
|
+
# @raise [Prusalink::Exceptions::ConflictError] if the job isn't waiting to continue
|
|
116
|
+
sig { params(id: Integer).returns(T::Boolean) }
|
|
117
|
+
def continue(id)
|
|
118
|
+
put(path: job_path(id, "continue"))
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
private
|
|
122
|
+
|
|
123
|
+
sig { params(id: Integer, action: T.nilable(String)).returns(String) }
|
|
124
|
+
def job_path(id, action = nil)
|
|
125
|
+
["/api/v1/job", id, action].compact.join("/")
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Stop this job. See {Job.stop}.
|
|
130
|
+
#
|
|
131
|
+
# @return [Boolean] true on success
|
|
132
|
+
sig { returns(T::Boolean) }
|
|
133
|
+
def stop
|
|
134
|
+
self.class.stop(T.must(id))
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# Pause this job. See {Job.pause}.
|
|
138
|
+
#
|
|
139
|
+
# @return [Boolean] true on success
|
|
140
|
+
sig { returns(T::Boolean) }
|
|
141
|
+
def pause
|
|
142
|
+
self.class.pause(T.must(id))
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Resume this job. See {Job.resume}.
|
|
146
|
+
#
|
|
147
|
+
# @return [Boolean] true on success
|
|
148
|
+
sig { returns(T::Boolean) }
|
|
149
|
+
def resume
|
|
150
|
+
self.class.resume(T.must(id))
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# Continue this job after a timelapse capture. See {Job.continue}.
|
|
154
|
+
#
|
|
155
|
+
# @return [Boolean] true on success
|
|
156
|
+
sig { returns(T::Boolean) }
|
|
157
|
+
def continue
|
|
158
|
+
self.class.continue(T.must(id))
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# @return [Boolean] whether the job is printing
|
|
162
|
+
sig { returns(T::Boolean) }
|
|
163
|
+
def printing?
|
|
164
|
+
state == "PRINTING"
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
# @return [Boolean] whether the job is paused
|
|
168
|
+
sig { returns(T::Boolean) }
|
|
169
|
+
def paused?
|
|
170
|
+
state == "PAUSED"
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# @return [Boolean] whether the job has finished
|
|
174
|
+
sig { returns(T::Boolean) }
|
|
175
|
+
def finished?
|
|
176
|
+
state == "FINISHED"
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
# @return [Boolean] whether the job was stopped
|
|
180
|
+
sig { returns(T::Boolean) }
|
|
181
|
+
def stopped?
|
|
182
|
+
state == "STOPPED"
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# @return [Boolean] whether the job ended in error
|
|
186
|
+
sig { returns(T::Boolean) }
|
|
187
|
+
def error?
|
|
188
|
+
state == "ERROR"
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Prusalink
|
|
5
|
+
# Version information about the PrusaLink server and the printer's firmware.
|
|
6
|
+
#
|
|
7
|
+
# @example
|
|
8
|
+
# version = Prusalink::ServerVersion.get
|
|
9
|
+
# version.text # => "PrusaLink 0.7.0"
|
|
10
|
+
# version.firmware # => "6.1.3+8098"
|
|
11
|
+
# version.upload_by_put? # => true
|
|
12
|
+
class ServerVersion < BaseResource
|
|
13
|
+
extend T::Sig
|
|
14
|
+
include AutoInitializable
|
|
15
|
+
include Deserializable
|
|
16
|
+
|
|
17
|
+
resource_path("/api/version")
|
|
18
|
+
|
|
19
|
+
# @!attribute [r] api
|
|
20
|
+
# @return [String] The API version
|
|
21
|
+
auto_attr :api, type: String
|
|
22
|
+
|
|
23
|
+
# @!attribute [r] version
|
|
24
|
+
# @return [String] The PrusaLink version
|
|
25
|
+
auto_attr :version, type: String
|
|
26
|
+
|
|
27
|
+
# @!attribute [r] printer
|
|
28
|
+
# @return [String] The printer's version
|
|
29
|
+
auto_attr :printer, type: String
|
|
30
|
+
|
|
31
|
+
# @!attribute [r] text
|
|
32
|
+
# @return [String] Server version including the "PrusaLink" prefix
|
|
33
|
+
auto_attr :text, type: String
|
|
34
|
+
|
|
35
|
+
# @!attribute [r] firmware
|
|
36
|
+
# @return [String] The printer's firmware version
|
|
37
|
+
auto_attr :firmware, type: String
|
|
38
|
+
|
|
39
|
+
# @!attribute [r] sdk
|
|
40
|
+
# @return [String] The PrusaLink SDK version
|
|
41
|
+
auto_attr :sdk, type: String
|
|
42
|
+
|
|
43
|
+
# @!attribute [r] capabilities
|
|
44
|
+
# @return [Hash] Optional capabilities, e.g. { upload_by_put: true }
|
|
45
|
+
auto_attr :capabilities, type: Hash
|
|
46
|
+
|
|
47
|
+
# @!attribute [r] extra
|
|
48
|
+
# @return [Hash] Any additional fields returned by the API
|
|
49
|
+
auto_attr :extra, type: Hash
|
|
50
|
+
|
|
51
|
+
auto_initialize!
|
|
52
|
+
|
|
53
|
+
# Retrieve information regarding server and API version.
|
|
54
|
+
#
|
|
55
|
+
# @return [ServerVersion]
|
|
56
|
+
# @raise [Prusalink::Exceptions::Error] if the request fails
|
|
57
|
+
sig { returns(ServerVersion) }
|
|
58
|
+
def self.get
|
|
59
|
+
fetch_resource
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Whether the printer accepts uploads with PUT /api/v1/files (see {Files.upload})
|
|
63
|
+
#
|
|
64
|
+
# @return [Boolean]
|
|
65
|
+
sig { returns(T::Boolean) }
|
|
66
|
+
def upload_by_put?
|
|
67
|
+
capabilities&.fetch(:upload_by_put, false) == true
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Prusalink
|
|
5
|
+
class Status
|
|
6
|
+
# The default working camera, if available.
|
|
7
|
+
#
|
|
8
|
+
# @example
|
|
9
|
+
# Prusalink::Status.get.camera&.id # => "Ba1kmCbifTa8X"
|
|
10
|
+
class Camera
|
|
11
|
+
extend T::Sig
|
|
12
|
+
include AutoInitializable
|
|
13
|
+
include Deserializable
|
|
14
|
+
|
|
15
|
+
# @!attribute [r] id
|
|
16
|
+
# @return [String] The camera's id
|
|
17
|
+
auto_attr :id, type: String
|
|
18
|
+
|
|
19
|
+
# @!attribute [r] extra
|
|
20
|
+
# @return [Hash] Any additional fields returned by the API
|
|
21
|
+
auto_attr :extra, type: Hash
|
|
22
|
+
|
|
23
|
+
auto_initialize!
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Prusalink
|
|
5
|
+
class Status
|
|
6
|
+
# Telemetry about the current job. All values are optional.
|
|
7
|
+
# See {Prusalink::Job} for the full job details.
|
|
8
|
+
#
|
|
9
|
+
# @example
|
|
10
|
+
# job = Prusalink::Status.get.job
|
|
11
|
+
# job.progress # => 42.0
|
|
12
|
+
# job.time_remaining # => 520
|
|
13
|
+
class Job
|
|
14
|
+
extend T::Sig
|
|
15
|
+
include AutoInitializable
|
|
16
|
+
include Deserializable
|
|
17
|
+
|
|
18
|
+
# @!attribute [r] id
|
|
19
|
+
# @return [Integer] The job's id
|
|
20
|
+
auto_attr :id, type: Integer
|
|
21
|
+
|
|
22
|
+
# @!attribute [r] progress
|
|
23
|
+
# @return [Float] Job progress, in percent
|
|
24
|
+
auto_attr :progress, type: Float
|
|
25
|
+
|
|
26
|
+
# @!attribute [r] time_remaining
|
|
27
|
+
# @return [Integer] Estimated time remaining, in seconds
|
|
28
|
+
auto_attr :time_remaining, type: Integer
|
|
29
|
+
|
|
30
|
+
# @!attribute [r] time_printing
|
|
31
|
+
# @return [Integer] Time spent printing, in seconds
|
|
32
|
+
auto_attr :time_printing, type: Integer
|
|
33
|
+
|
|
34
|
+
# @!attribute [r] extra
|
|
35
|
+
# @return [Hash] Any additional fields returned by the API
|
|
36
|
+
auto_attr :extra, type: Hash
|
|
37
|
+
|
|
38
|
+
auto_initialize!
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Prusalink
|
|
5
|
+
class Status
|
|
6
|
+
# Telemetry about the printer. All values except {#state} are optional.
|
|
7
|
+
#
|
|
8
|
+
# @example
|
|
9
|
+
# printer = Prusalink::Status.get.printer
|
|
10
|
+
# printer.state # => "PRINTING"
|
|
11
|
+
# printer.printing? # => true
|
|
12
|
+
# printer.temp_bed # => 59.5
|
|
13
|
+
class Printer
|
|
14
|
+
extend T::Sig
|
|
15
|
+
include AutoInitializable
|
|
16
|
+
include Deserializable
|
|
17
|
+
|
|
18
|
+
# @!attribute [r] state
|
|
19
|
+
# @return [String] The printer's state: "IDLE", "BUSY", "PRINTING", "PAUSED", "FINISHED", "STOPPED",
|
|
20
|
+
# "ERROR", "ATTENTION" or "READY"
|
|
21
|
+
auto_attr :state, type: String
|
|
22
|
+
|
|
23
|
+
# @!attribute [r] temp_nozzle
|
|
24
|
+
# @return [Float] Current nozzle temperature, in °C
|
|
25
|
+
auto_attr :temp_nozzle, type: Float
|
|
26
|
+
|
|
27
|
+
# @!attribute [r] target_nozzle
|
|
28
|
+
# @return [Float] Target nozzle temperature, in °C
|
|
29
|
+
auto_attr :target_nozzle, type: Float
|
|
30
|
+
|
|
31
|
+
# @!attribute [r] temp_bed
|
|
32
|
+
# @return [Float] Current bed temperature, in °C
|
|
33
|
+
auto_attr :temp_bed, type: Float
|
|
34
|
+
|
|
35
|
+
# @!attribute [r] target_bed
|
|
36
|
+
# @return [Float] Target bed temperature, in °C
|
|
37
|
+
auto_attr :target_bed, type: Float
|
|
38
|
+
|
|
39
|
+
# @!attribute [r] axis_x
|
|
40
|
+
# @return [Float, nil] X axis position, in mm. Only available when the printer is not moving
|
|
41
|
+
auto_attr :axis_x, type: Float
|
|
42
|
+
|
|
43
|
+
# @!attribute [r] axis_y
|
|
44
|
+
# @return [Float, nil] Y axis position, in mm. Only available when the printer is not moving
|
|
45
|
+
auto_attr :axis_y, type: Float
|
|
46
|
+
|
|
47
|
+
# @!attribute [r] axis_z
|
|
48
|
+
# @return [Float] Z axis position, in mm
|
|
49
|
+
auto_attr :axis_z, type: Float
|
|
50
|
+
|
|
51
|
+
# @!attribute [r] flow
|
|
52
|
+
# @return [Integer] Flow rate factor, in percent
|
|
53
|
+
auto_attr :flow, type: Integer
|
|
54
|
+
|
|
55
|
+
# @!attribute [r] speed
|
|
56
|
+
# @return [Integer] Print speed factor, in percent
|
|
57
|
+
auto_attr :speed, type: Integer
|
|
58
|
+
|
|
59
|
+
# @!attribute [r] fan_hotend
|
|
60
|
+
# @return [Integer] Hotend fan speed, in RPM
|
|
61
|
+
auto_attr :fan_hotend, type: Integer
|
|
62
|
+
|
|
63
|
+
# @!attribute [r] fan_print
|
|
64
|
+
# @return [Integer] Print fan speed, in RPM
|
|
65
|
+
auto_attr :fan_print, type: Integer
|
|
66
|
+
|
|
67
|
+
# @!attribute [r] status_printer
|
|
68
|
+
# @return [Hash] Printer health, e.g. { ok: true, message: "OK" }
|
|
69
|
+
auto_attr :status_printer, type: Hash
|
|
70
|
+
|
|
71
|
+
# @!attribute [r] status_connect
|
|
72
|
+
# @return [Hash] Prusa Connect health, e.g. { ok: true, message: "OK" }
|
|
73
|
+
auto_attr :status_connect, type: Hash
|
|
74
|
+
|
|
75
|
+
# @!attribute [r] extra
|
|
76
|
+
# @return [Hash] Any additional fields returned by the API
|
|
77
|
+
auto_attr :extra, type: Hash
|
|
78
|
+
|
|
79
|
+
auto_initialize!
|
|
80
|
+
|
|
81
|
+
# @return [Boolean] true when the state is "IDLE"
|
|
82
|
+
sig { returns(T::Boolean) }
|
|
83
|
+
def idle?
|
|
84
|
+
state == "IDLE"
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# @return [Boolean] true when the state is "BUSY"
|
|
88
|
+
sig { returns(T::Boolean) }
|
|
89
|
+
def busy?
|
|
90
|
+
state == "BUSY"
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# @return [Boolean] true when the state is "PRINTING"
|
|
94
|
+
sig { returns(T::Boolean) }
|
|
95
|
+
def printing?
|
|
96
|
+
state == "PRINTING"
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# @return [Boolean] true when the state is "PAUSED"
|
|
100
|
+
sig { returns(T::Boolean) }
|
|
101
|
+
def paused?
|
|
102
|
+
state == "PAUSED"
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# @return [Boolean] true when the state is "FINISHED"
|
|
106
|
+
sig { returns(T::Boolean) }
|
|
107
|
+
def finished?
|
|
108
|
+
state == "FINISHED"
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# @return [Boolean] true when the state is "STOPPED"
|
|
112
|
+
sig { returns(T::Boolean) }
|
|
113
|
+
def stopped?
|
|
114
|
+
state == "STOPPED"
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# @return [Boolean] true when the state is "ERROR"
|
|
118
|
+
sig { returns(T::Boolean) }
|
|
119
|
+
def error?
|
|
120
|
+
state == "ERROR"
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# @return [Boolean] true when the state is "ATTENTION" (the printer waits for user input)
|
|
124
|
+
sig { returns(T::Boolean) }
|
|
125
|
+
def attention?
|
|
126
|
+
state == "ATTENTION"
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# @return [Boolean] true when the state is "READY"
|
|
130
|
+
sig { returns(T::Boolean) }
|
|
131
|
+
def ready?
|
|
132
|
+
state == "READY"
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Prusalink
|
|
5
|
+
class Status
|
|
6
|
+
# Telemetry about the current storage.
|
|
7
|
+
#
|
|
8
|
+
# @example
|
|
9
|
+
# storage = Prusalink::Status.get.storage
|
|
10
|
+
# storage.name # => "LOCAL"
|
|
11
|
+
# storage.free_space # => 4202335
|
|
12
|
+
class Storage
|
|
13
|
+
extend T::Sig
|
|
14
|
+
include AutoInitializable
|
|
15
|
+
include Deserializable
|
|
16
|
+
|
|
17
|
+
# @!attribute [r] name
|
|
18
|
+
# @return [String] The storage's name, e.g. "LOCAL"
|
|
19
|
+
auto_attr :name, type: String
|
|
20
|
+
|
|
21
|
+
# @!attribute [r] path
|
|
22
|
+
# @return [String] The storage's path, e.g. "/local"
|
|
23
|
+
auto_attr :path, type: String
|
|
24
|
+
|
|
25
|
+
# @!attribute [r] read_only
|
|
26
|
+
# @return [Boolean] Whether the storage is read-only
|
|
27
|
+
auto_attr :read_only, type: T::Boolean
|
|
28
|
+
|
|
29
|
+
# @!attribute [r] free_space
|
|
30
|
+
# @return [Integer] Free space, in bytes
|
|
31
|
+
auto_attr :free_space, type: Integer
|
|
32
|
+
|
|
33
|
+
# @!attribute [r] extra
|
|
34
|
+
# @return [Hash] Any additional fields returned by the API
|
|
35
|
+
auto_attr :extra, type: Hash
|
|
36
|
+
|
|
37
|
+
auto_initialize!
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Prusalink
|
|
5
|
+
class Status
|
|
6
|
+
# Telemetry about the current file transfer. All values except {#id} and {#time_transferring} are optional.
|
|
7
|
+
#
|
|
8
|
+
# @example
|
|
9
|
+
# transfer = Prusalink::Status.get.transfer
|
|
10
|
+
# transfer.progress # => 65.82
|
|
11
|
+
# transfer.data_transferred # => 123084800
|
|
12
|
+
class Transfer
|
|
13
|
+
extend T::Sig
|
|
14
|
+
include AutoInitializable
|
|
15
|
+
include Deserializable
|
|
16
|
+
|
|
17
|
+
# @!attribute [r] id
|
|
18
|
+
# @return [Integer] The transfer's id
|
|
19
|
+
auto_attr :id, type: Integer
|
|
20
|
+
|
|
21
|
+
# @!attribute [r] time_transferring
|
|
22
|
+
# @return [Integer] Time spent transferring, in seconds
|
|
23
|
+
auto_attr :time_transferring, type: Integer
|
|
24
|
+
|
|
25
|
+
# @!attribute [r] progress
|
|
26
|
+
# @return [Float] Transfer progress, in percent
|
|
27
|
+
auto_attr :progress, type: Float
|
|
28
|
+
|
|
29
|
+
# @!attribute [r] data_transferred
|
|
30
|
+
# @return [Integer] Amount of data transferred, in bytes
|
|
31
|
+
auto_attr :data_transferred, type: Integer
|
|
32
|
+
|
|
33
|
+
# @!attribute [r] extra
|
|
34
|
+
# @return [Hash] Any additional fields returned by the API
|
|
35
|
+
auto_attr :extra, type: Hash
|
|
36
|
+
|
|
37
|
+
auto_initialize!
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Prusalink
|
|
5
|
+
# Telemetry about the printer, the current job, the current transfer, the storage and the camera.
|
|
6
|
+
# Everything except {#printer} is optional and is nil when the printer doesn't report it.
|
|
7
|
+
#
|
|
8
|
+
# @example
|
|
9
|
+
# status = Prusalink::Status.get
|
|
10
|
+
# status.printer.state # => "PRINTING"
|
|
11
|
+
# status.printer.printing? # => true
|
|
12
|
+
# status.job&.progress # => 42.0
|
|
13
|
+
# status.transfer # => nil when nothing is being transferred
|
|
14
|
+
class Status < BaseResource
|
|
15
|
+
extend T::Sig
|
|
16
|
+
include AutoInitializable
|
|
17
|
+
include Deserializable
|
|
18
|
+
|
|
19
|
+
resource_path("/api/v1/status")
|
|
20
|
+
|
|
21
|
+
# @!attribute [r] printer
|
|
22
|
+
# @return [Status::Printer] Telemetry about the printer (always present)
|
|
23
|
+
auto_attr :printer, type: Status::Printer
|
|
24
|
+
|
|
25
|
+
# @!attribute [r] job
|
|
26
|
+
# @return [Status::Job, nil] Telemetry about the current job
|
|
27
|
+
auto_attr :job, type: Status::Job
|
|
28
|
+
|
|
29
|
+
# @!attribute [r] transfer
|
|
30
|
+
# @return [Status::Transfer, nil] Telemetry about the current file transfer
|
|
31
|
+
auto_attr :transfer, type: Status::Transfer
|
|
32
|
+
|
|
33
|
+
# @!attribute [r] storage
|
|
34
|
+
# @return [Status::Storage, nil] Telemetry about the current storage
|
|
35
|
+
auto_attr :storage, type: Status::Storage
|
|
36
|
+
|
|
37
|
+
# @!attribute [r] camera
|
|
38
|
+
# @return [Status::Camera, nil] The default working camera, if available
|
|
39
|
+
auto_attr :camera, type: Status::Camera
|
|
40
|
+
|
|
41
|
+
# @!attribute [r] extra
|
|
42
|
+
# @return [Hash] Any additional fields returned by the API
|
|
43
|
+
auto_attr :extra, type: Hash
|
|
44
|
+
|
|
45
|
+
auto_initialize!
|
|
46
|
+
|
|
47
|
+
deserialize_config do
|
|
48
|
+
nested :printer, Status::Printer
|
|
49
|
+
nested :job, Status::Job
|
|
50
|
+
nested :transfer, Status::Transfer
|
|
51
|
+
nested :storage, Status::Storage
|
|
52
|
+
nested :camera, Status::Camera
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Retrieve the printer, job, transfer, storage and camera telemetry.
|
|
56
|
+
#
|
|
57
|
+
# @return [Status, nil] nil when the printer answers 204 No Content
|
|
58
|
+
# @raise [Prusalink::Exceptions::Error] if the request fails
|
|
59
|
+
sig { returns(T.nilable(Status)) }
|
|
60
|
+
def self.get
|
|
61
|
+
fetch_resource
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Prusalink
|
|
5
|
+
# A file storage of the printer, such as the local storage, an SD card or a USB drive.
|
|
6
|
+
#
|
|
7
|
+
# @example
|
|
8
|
+
# storages = Prusalink::Storage.list
|
|
9
|
+
# usb = storages.find { |storage| storage.storage_type == "USB" }
|
|
10
|
+
# usb.available? # => true
|
|
11
|
+
# usb.free_space # => 1921681142
|
|
12
|
+
class Storage < BaseResource
|
|
13
|
+
extend T::Sig
|
|
14
|
+
include AutoInitializable
|
|
15
|
+
include Deserializable
|
|
16
|
+
|
|
17
|
+
resource_path("/api/v1/storage")
|
|
18
|
+
|
|
19
|
+
# @!attribute [r] name
|
|
20
|
+
# @return [String, nil] Name of the storage, in the printer's language, e.g. "PrusaLink gcodes"
|
|
21
|
+
auto_attr :name, type: String
|
|
22
|
+
|
|
23
|
+
# @!attribute [r] storage_type
|
|
24
|
+
# @return [String] The storage's source: "LOCAL", "SDCARD" or "USB". Renamed from the API's `type` field.
|
|
25
|
+
auto_attr :storage_type, type: String
|
|
26
|
+
|
|
27
|
+
# @!attribute [r] path
|
|
28
|
+
# @return [String] Path of the storage (not the display path), e.g. "/local"
|
|
29
|
+
auto_attr :path, type: String
|
|
30
|
+
|
|
31
|
+
# @!attribute [r] print_files
|
|
32
|
+
# @return [Integer, nil] Size of all print files, in bytes
|
|
33
|
+
auto_attr :print_files, type: Integer
|
|
34
|
+
|
|
35
|
+
# @!attribute [r] system_files
|
|
36
|
+
# @return [Integer, nil] Size of all system files, in bytes
|
|
37
|
+
auto_attr :system_files, type: Integer
|
|
38
|
+
|
|
39
|
+
# @!attribute [r] free_space
|
|
40
|
+
# @return [Integer, nil] Free space, in bytes
|
|
41
|
+
auto_attr :free_space, type: Integer
|
|
42
|
+
|
|
43
|
+
# @!attribute [r] total_space
|
|
44
|
+
# @return [Integer, nil] Total space, in bytes
|
|
45
|
+
auto_attr :total_space, type: Integer
|
|
46
|
+
|
|
47
|
+
# @!attribute [r] available
|
|
48
|
+
# @return [Boolean] Whether the storage is available. See {#available?}
|
|
49
|
+
auto_attr :available, type: T::Boolean
|
|
50
|
+
|
|
51
|
+
# @!attribute [r] read_only
|
|
52
|
+
# @return [Boolean, nil] Whether the storage is read only. See {#read_only?}
|
|
53
|
+
auto_attr :read_only, type: T::Boolean
|
|
54
|
+
|
|
55
|
+
# @!attribute [r] extra
|
|
56
|
+
# @return [Hash] Any additional fields returned by the API
|
|
57
|
+
auto_attr :extra, type: Hash
|
|
58
|
+
|
|
59
|
+
auto_initialize!
|
|
60
|
+
|
|
61
|
+
deserialize_config do
|
|
62
|
+
rename type: :storage_type
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Retrieve every file storage of the printer.
|
|
66
|
+
#
|
|
67
|
+
# @return [Array<Storage>]
|
|
68
|
+
# @raise [Prusalink::Exceptions::Error] if the request fails
|
|
69
|
+
sig { returns(T::Array[Storage]) }
|
|
70
|
+
def self.list
|
|
71
|
+
response = fetch_resource(deserialize: false)
|
|
72
|
+
Array(response&.fetch(:storage_list, nil)).map { |storage| deserialize(storage) }
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# @return [Boolean] whether the storage is available
|
|
76
|
+
sig { returns(T::Boolean) }
|
|
77
|
+
def available?
|
|
78
|
+
available == true
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# @return [Boolean] whether the storage is read only
|
|
82
|
+
sig { returns(T::Boolean) }
|
|
83
|
+
def read_only?
|
|
84
|
+
read_only == true
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|