anycubic-cloud-api 0.1.0__py3-none-any.whl
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.
- anycubic_cloud_api/__init__.py +62 -0
- anycubic_cloud_api/anycubic_api.py +7 -0
- anycubic_cloud_api/api/base.py +400 -0
- anycubic_cloud_api/api/functions.py +2055 -0
- anycubic_cloud_api/api/mqtt.py +449 -0
- anycubic_cloud_api/const/api_endpoints.py +106 -0
- anycubic_cloud_api/const/const.py +47 -0
- anycubic_cloud_api/const/enums.py +97 -0
- anycubic_cloud_api/const/mqtt.py +13 -0
- anycubic_cloud_api/data_models/consumable.py +116 -0
- anycubic_cloud_api/data_models/files.py +429 -0
- anycubic_cloud_api/data_models/gcode_file.py +107 -0
- anycubic_cloud_api/data_models/orders.py +369 -0
- anycubic_cloud_api/data_models/print_response.py +71 -0
- anycubic_cloud_api/data_models/print_speed_mode.py +61 -0
- anycubic_cloud_api/data_models/printer.py +2753 -0
- anycubic_cloud_api/data_models/printer_properties.py +1107 -0
- anycubic_cloud_api/data_models/printing_settings.py +130 -0
- anycubic_cloud_api/data_models/project.py +1234 -0
- anycubic_cloud_api/exceptions/error_strings.py +340 -0
- anycubic_cloud_api/exceptions/exceptions.py +91 -0
- anycubic_cloud_api/helpers/helpers.py +240 -0
- anycubic_cloud_api/models/auth.py +396 -0
- anycubic_cloud_api/models/cloud_upload.py +249 -0
- anycubic_cloud_api/models/http.py +29 -0
- anycubic_cloud_api/resources/anycubic_mqqt_tls_ca.crt +24 -0
- anycubic_cloud_api/resources/anycubic_mqqt_tls_client.crt +24 -0
- anycubic_cloud_api/resources/anycubic_mqqt_tls_client.key +28 -0
- anycubic_cloud_api-0.1.0.dist-info/METADATA +79 -0
- anycubic_cloud_api-0.1.0.dist-info/RECORD +33 -0
- anycubic_cloud_api-0.1.0.dist-info/WHEEL +5 -0
- anycubic_cloud_api-0.1.0.dist-info/licenses/LICENSE +674 -0
- anycubic_cloud_api-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,1107 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from ..exceptions.error_strings import ErrorsDataParsing
|
|
6
|
+
from ..exceptions.exceptions import AnycubicDataParsingError
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class AnycubicMaterialMapping:
|
|
10
|
+
__slots__ = (
|
|
11
|
+
"_spool_index",
|
|
12
|
+
"_filament_used",
|
|
13
|
+
"_material_type",
|
|
14
|
+
"_color_red",
|
|
15
|
+
"_color_green",
|
|
16
|
+
"_color_blue",
|
|
17
|
+
"_paint_index",
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
def __init__(
|
|
21
|
+
self,
|
|
22
|
+
spool_index: int,
|
|
23
|
+
filament_used: float,
|
|
24
|
+
material_type: str,
|
|
25
|
+
color_red: int,
|
|
26
|
+
color_green: int,
|
|
27
|
+
color_blue: int,
|
|
28
|
+
paint_index: int = 0,
|
|
29
|
+
) -> None:
|
|
30
|
+
self._spool_index = int(spool_index)
|
|
31
|
+
self._filament_used = float(filament_used)
|
|
32
|
+
self._material_type = str(material_type)
|
|
33
|
+
self._color_red = int(color_red)
|
|
34
|
+
self._color_green = int(color_green)
|
|
35
|
+
self._color_blue = int(color_blue)
|
|
36
|
+
self._paint_index = int(paint_index)
|
|
37
|
+
|
|
38
|
+
@property
|
|
39
|
+
def spool_index(self) -> int:
|
|
40
|
+
return self._spool_index
|
|
41
|
+
|
|
42
|
+
@property
|
|
43
|
+
def filament_used(self) -> float:
|
|
44
|
+
return self._filament_used
|
|
45
|
+
|
|
46
|
+
@property
|
|
47
|
+
def material_type(self) -> str:
|
|
48
|
+
return self._material_type
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
def paint_index(self) -> int:
|
|
52
|
+
return self._paint_index
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def color_data(self) -> list[int]:
|
|
56
|
+
return list([
|
|
57
|
+
self._color_red,
|
|
58
|
+
self._color_green,
|
|
59
|
+
self._color_blue,
|
|
60
|
+
])
|
|
61
|
+
|
|
62
|
+
def as_box_mapping_data(self) -> dict[str, Any]:
|
|
63
|
+
return {
|
|
64
|
+
'ams_color': self.color_data,
|
|
65
|
+
'ams_index': self._spool_index,
|
|
66
|
+
'filament_used': self._filament_used,
|
|
67
|
+
'material_type': self._material_type,
|
|
68
|
+
'paint_color': self.color_data,
|
|
69
|
+
'paint_index': self._paint_index,
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
def __repr__(self) -> str:
|
|
73
|
+
return (
|
|
74
|
+
f"AnycubicMaterialMapping("
|
|
75
|
+
f"spool_index={self._spool_index}, "
|
|
76
|
+
f"filament_used={self._filament_used}, "
|
|
77
|
+
f"material_type={self._material_type}, "
|
|
78
|
+
f"color_red={self._color_red}, "
|
|
79
|
+
f"color_green={self._color_green}, "
|
|
80
|
+
f"color_blue={self._color_blue}, "
|
|
81
|
+
f"paint_index={self._paint_index})"
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class AnycubicMaterialColor:
|
|
86
|
+
__slots__ = (
|
|
87
|
+
"_red",
|
|
88
|
+
"_green",
|
|
89
|
+
"_blue",
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
def __init__(
|
|
93
|
+
self,
|
|
94
|
+
red: int,
|
|
95
|
+
green: int,
|
|
96
|
+
blue: int,
|
|
97
|
+
) -> None:
|
|
98
|
+
self._red: int = red
|
|
99
|
+
self._green: int = green
|
|
100
|
+
self._blue: int = blue
|
|
101
|
+
|
|
102
|
+
@property
|
|
103
|
+
def red(self) -> int:
|
|
104
|
+
return self._red
|
|
105
|
+
|
|
106
|
+
@property
|
|
107
|
+
def green(self) -> int:
|
|
108
|
+
return self._green
|
|
109
|
+
|
|
110
|
+
@property
|
|
111
|
+
def blue(self) -> int:
|
|
112
|
+
return self._blue
|
|
113
|
+
|
|
114
|
+
@property
|
|
115
|
+
def data(self) -> list[int]:
|
|
116
|
+
return list([
|
|
117
|
+
self._red,
|
|
118
|
+
self._green,
|
|
119
|
+
self._blue,
|
|
120
|
+
])
|
|
121
|
+
|
|
122
|
+
def __repr__(self) -> str:
|
|
123
|
+
return (
|
|
124
|
+
f"AnycubicMaterialColor("
|
|
125
|
+
f"red={self._red}, "
|
|
126
|
+
f"green={self._green}, "
|
|
127
|
+
f"blue={self._blue})"
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
# class AnycubicMachineBaseInfo:
|
|
132
|
+
# def __init__(
|
|
133
|
+
# self,
|
|
134
|
+
# print_count: int,
|
|
135
|
+
# print_totaltime: str,
|
|
136
|
+
# material_type: str,
|
|
137
|
+
# material_used: str,
|
|
138
|
+
# description: str,
|
|
139
|
+
# create_time: int,
|
|
140
|
+
# firmware_version: str,
|
|
141
|
+
# machine_mac: str,
|
|
142
|
+
# ) -> None:
|
|
143
|
+
# self._print_count: int = int(print_count)
|
|
144
|
+
# self._print_totaltime: str = str(print_totaltime)
|
|
145
|
+
# self._material_type: str = str(material_type)
|
|
146
|
+
# self._material_used: str = str(material_used)
|
|
147
|
+
# self._description: str = str(description)
|
|
148
|
+
# self._create_time: int = int(create_time)
|
|
149
|
+
# self._firmware_version = str(firmware_version)
|
|
150
|
+
# self._machine_mac: str = str(machine_mac)
|
|
151
|
+
|
|
152
|
+
# @classmethod
|
|
153
|
+
# def from_json(cls, data: dict[str, Any] | None) -> AnycubicMachineBaseInfo | None:
|
|
154
|
+
# if data is None:
|
|
155
|
+
# return None
|
|
156
|
+
|
|
157
|
+
# return cls(
|
|
158
|
+
# print_count=data['print_count'],
|
|
159
|
+
# print_totaltime=data['print_totaltime'],
|
|
160
|
+
# material_type=data['material_type'],
|
|
161
|
+
# material_used=data['material_used'],
|
|
162
|
+
# description=data['description'],
|
|
163
|
+
# create_time=data['create_time'],
|
|
164
|
+
# firmware_version=data['firmware_version'],
|
|
165
|
+
# machine_mac=data['machine_mac'],
|
|
166
|
+
# )
|
|
167
|
+
|
|
168
|
+
# def __repr__(self) -> str:
|
|
169
|
+
# return (
|
|
170
|
+
# f"AnycubicMachineBaseInfo(print_count={self._print_count}, print_totaltime={self._print_totaltime}, "
|
|
171
|
+
# f"material_type={self._material_type}, material_used={self._material_used},"
|
|
172
|
+
# f"description={self._description}, create_time={self._create_time}, firmware_version={self._firmware_version}, "
|
|
173
|
+
# f"machine_mac={self._machine_mac})"
|
|
174
|
+
# )
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
class AnycubicMachineToolInfo:
|
|
178
|
+
__slots__ = (
|
|
179
|
+
"_id",
|
|
180
|
+
"_typd_id",
|
|
181
|
+
"_model_id",
|
|
182
|
+
"_type_function_id",
|
|
183
|
+
"_parent_id",
|
|
184
|
+
"_function_name",
|
|
185
|
+
"_function_des",
|
|
186
|
+
"_control",
|
|
187
|
+
"_param",
|
|
188
|
+
"_icon_url",
|
|
189
|
+
"_function_type",
|
|
190
|
+
"_status",
|
|
191
|
+
"_show_place",
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
def __init__(
|
|
195
|
+
self,
|
|
196
|
+
id: int,
|
|
197
|
+
typd_id: int,
|
|
198
|
+
model_id: int,
|
|
199
|
+
type_function_id: int,
|
|
200
|
+
parent_id: int,
|
|
201
|
+
function_name: str,
|
|
202
|
+
function_des: str,
|
|
203
|
+
control: int,
|
|
204
|
+
param: Any,
|
|
205
|
+
icon_url: str,
|
|
206
|
+
function_type: int,
|
|
207
|
+
status: int,
|
|
208
|
+
show_place: int,
|
|
209
|
+
) -> None:
|
|
210
|
+
self._id = int(id)
|
|
211
|
+
self._typd_id = int(typd_id)
|
|
212
|
+
self._model_id = int(model_id)
|
|
213
|
+
self._type_function_id = int(type_function_id)
|
|
214
|
+
self._parent_id = int(parent_id)
|
|
215
|
+
self._function_name = str(function_name)
|
|
216
|
+
self._function_des = str(function_des)
|
|
217
|
+
self._control = int(control)
|
|
218
|
+
self._param = param
|
|
219
|
+
self._icon_url = str(icon_url)
|
|
220
|
+
self._function_type = int(function_type)
|
|
221
|
+
self._status = int(status)
|
|
222
|
+
self._show_place = int(show_place)
|
|
223
|
+
|
|
224
|
+
@classmethod
|
|
225
|
+
def from_json(cls, data: dict[str, Any] | None) -> AnycubicMachineToolInfo | None:
|
|
226
|
+
if data is None:
|
|
227
|
+
return None
|
|
228
|
+
|
|
229
|
+
return cls(
|
|
230
|
+
id=data['id'],
|
|
231
|
+
typd_id=data['typd_id'],
|
|
232
|
+
model_id=data['model_id'],
|
|
233
|
+
type_function_id=data['type_function_id'],
|
|
234
|
+
parent_id=data['parent_id'],
|
|
235
|
+
function_name=data['function_name'],
|
|
236
|
+
function_des=data['function_des'],
|
|
237
|
+
control=data['control'],
|
|
238
|
+
param=data['param'],
|
|
239
|
+
icon_url=data['icon_url'],
|
|
240
|
+
function_type=data['function_type'],
|
|
241
|
+
status=data['status'],
|
|
242
|
+
show_place=data['show_place'],
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
def __repr__(self) -> str:
|
|
246
|
+
return (
|
|
247
|
+
f"AnycubicMachineToolInfo(id={self._id}, typd_id={self._typd_id}, model_id={self._model_id}, "
|
|
248
|
+
f"type_function_id={self._type_function_id}, parent_id={self._parent_id},\n "
|
|
249
|
+
f"function_name={self._function_name}, function_des={self._function_des}, control={self._control}, "
|
|
250
|
+
f"param={self._param}, icon_url={self._icon_url},\n "
|
|
251
|
+
f"function_type={self._function_type}, status={self._status}, show_place={self._show_place})"
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
class AnycubicMachineExternalShelves:
|
|
256
|
+
__slots__ = (
|
|
257
|
+
"_id",
|
|
258
|
+
"_type",
|
|
259
|
+
"_color",
|
|
260
|
+
"_loaded",
|
|
261
|
+
"_status_type",
|
|
262
|
+
"_current_status",
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
def __init__(
|
|
266
|
+
self,
|
|
267
|
+
id: int,
|
|
268
|
+
type: str,
|
|
269
|
+
color: list[int],
|
|
270
|
+
loaded: int,
|
|
271
|
+
status_type: int,
|
|
272
|
+
current_status: int,
|
|
273
|
+
) -> None:
|
|
274
|
+
self._id = int(id)
|
|
275
|
+
self._type = str(type)
|
|
276
|
+
self._color = list([
|
|
277
|
+
int(x) for x in color
|
|
278
|
+
])
|
|
279
|
+
self._loaded = int(loaded)
|
|
280
|
+
self._status_type = int(status_type)
|
|
281
|
+
self._current_status = int(current_status)
|
|
282
|
+
|
|
283
|
+
@classmethod
|
|
284
|
+
def from_json(cls, data: dict[str, Any] | None) -> AnycubicMachineExternalShelves | None:
|
|
285
|
+
if data is None:
|
|
286
|
+
return None
|
|
287
|
+
|
|
288
|
+
return cls(
|
|
289
|
+
id=data['id'],
|
|
290
|
+
type=data['type'],
|
|
291
|
+
color=data['color'],
|
|
292
|
+
loaded=data.get('loaded', False),
|
|
293
|
+
status_type=data.get('status_type', False),
|
|
294
|
+
current_status=data.get('current_status', False),
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
def update_with_mqtt_data(self, data: dict[str, Any] | None) -> None:
|
|
298
|
+
if data is None:
|
|
299
|
+
return None
|
|
300
|
+
|
|
301
|
+
self._type = data['type']
|
|
302
|
+
self._color = data['color']
|
|
303
|
+
self._loaded = data['loaded']
|
|
304
|
+
self._status_type = data['status_type']
|
|
305
|
+
self._current_status = data['current_status']
|
|
306
|
+
|
|
307
|
+
def __repr__(self) -> str:
|
|
308
|
+
return (
|
|
309
|
+
f"AnycubicMachineExternalShelves(id={self._id}, type={self._type}, color={self._color}, loaded={self._loaded}, "
|
|
310
|
+
f"status_type={self._status_type}, current_status={self._current_status})"
|
|
311
|
+
)
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
class AnycubicFeedStatus:
|
|
315
|
+
__slots__ = (
|
|
316
|
+
"_code",
|
|
317
|
+
"_type",
|
|
318
|
+
"_current_status",
|
|
319
|
+
"_slot_index",
|
|
320
|
+
)
|
|
321
|
+
|
|
322
|
+
def __init__(
|
|
323
|
+
self,
|
|
324
|
+
code: int,
|
|
325
|
+
type: int,
|
|
326
|
+
current_status: int,
|
|
327
|
+
slot_index: int,
|
|
328
|
+
) -> None:
|
|
329
|
+
self._code = int(code)
|
|
330
|
+
self._type = int(type)
|
|
331
|
+
self._current_status = int(current_status)
|
|
332
|
+
self._slot_index = int(slot_index)
|
|
333
|
+
|
|
334
|
+
@classmethod
|
|
335
|
+
def from_json(cls, data: dict[str, Any] | None) -> AnycubicFeedStatus | None:
|
|
336
|
+
if data is None:
|
|
337
|
+
return None
|
|
338
|
+
|
|
339
|
+
return cls(
|
|
340
|
+
code=data.get('code', -1),
|
|
341
|
+
type=data['type'],
|
|
342
|
+
current_status=data['current_status'],
|
|
343
|
+
slot_index=data['slot_index'],
|
|
344
|
+
)
|
|
345
|
+
|
|
346
|
+
@property
|
|
347
|
+
def info_object(self) -> dict[str, Any]:
|
|
348
|
+
return {
|
|
349
|
+
"code": self._code,
|
|
350
|
+
"type": self._type,
|
|
351
|
+
"current_status": self._current_status,
|
|
352
|
+
# -1 when nothing is feeding; otherwise the 1-based slot.
|
|
353
|
+
"slot": self._slot_index + 1 if self._slot_index >= 0 else None,
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
def __repr__(self) -> str:
|
|
357
|
+
return (
|
|
358
|
+
f"AnycubicFeedStatus(code={self._code}, type={self._type}, current_status={self._current_status}, "
|
|
359
|
+
f"slot_index={self._slot_index})"
|
|
360
|
+
)
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
class AnycubicDryingStatus:
|
|
364
|
+
__slots__ = (
|
|
365
|
+
"_status",
|
|
366
|
+
"_target_temp",
|
|
367
|
+
"_duration",
|
|
368
|
+
"_remain_time",
|
|
369
|
+
)
|
|
370
|
+
|
|
371
|
+
def __init__(
|
|
372
|
+
self,
|
|
373
|
+
status: int,
|
|
374
|
+
target_temp: int,
|
|
375
|
+
duration: int,
|
|
376
|
+
remain_time: int,
|
|
377
|
+
) -> None:
|
|
378
|
+
self._status = int(status)
|
|
379
|
+
self._target_temp = int(target_temp)
|
|
380
|
+
self._duration = int(duration)
|
|
381
|
+
self._remain_time = int(remain_time)
|
|
382
|
+
|
|
383
|
+
@classmethod
|
|
384
|
+
def from_json(cls, data: dict[str, Any] | None) -> AnycubicDryingStatus | None:
|
|
385
|
+
if data is None:
|
|
386
|
+
return None
|
|
387
|
+
|
|
388
|
+
return cls(
|
|
389
|
+
status=data['status'],
|
|
390
|
+
target_temp=data.get('target_temp', 0),
|
|
391
|
+
duration=data.get('duration', 0),
|
|
392
|
+
remain_time=data.get('remain_time', 0),
|
|
393
|
+
)
|
|
394
|
+
|
|
395
|
+
@property
|
|
396
|
+
def is_drying(self) -> bool:
|
|
397
|
+
return self._status == 1
|
|
398
|
+
|
|
399
|
+
@property
|
|
400
|
+
def raw_status_code(self) -> int:
|
|
401
|
+
return self._status
|
|
402
|
+
|
|
403
|
+
@property
|
|
404
|
+
def target_temperature(self) -> int:
|
|
405
|
+
return self._target_temp if self.is_drying else 0
|
|
406
|
+
|
|
407
|
+
@property
|
|
408
|
+
def total_duration(self) -> int:
|
|
409
|
+
return self._duration if self.is_drying else 0
|
|
410
|
+
|
|
411
|
+
@property
|
|
412
|
+
def remaining_time(self) -> int:
|
|
413
|
+
return self._remain_time if self.is_drying else 0
|
|
414
|
+
|
|
415
|
+
def __repr__(self) -> str:
|
|
416
|
+
return (
|
|
417
|
+
f"AnycubicDryingStatus(is_drying={self.is_drying}, status={self._status}, target_temp={self._target_temp}, "
|
|
418
|
+
f"duration={self._duration}, remain_time={self._remain_time})"
|
|
419
|
+
)
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
class AnycubicSpoolInfo:
|
|
423
|
+
__slots__ = (
|
|
424
|
+
"_index",
|
|
425
|
+
"_sku",
|
|
426
|
+
"_material_type",
|
|
427
|
+
"_color",
|
|
428
|
+
"_color_group",
|
|
429
|
+
"_edit_status",
|
|
430
|
+
"_status",
|
|
431
|
+
"_icon_type",
|
|
432
|
+
"_consumables_percent",
|
|
433
|
+
)
|
|
434
|
+
|
|
435
|
+
def __init__(
|
|
436
|
+
self,
|
|
437
|
+
index: int,
|
|
438
|
+
sku: str,
|
|
439
|
+
material_type: str,
|
|
440
|
+
color: list[int],
|
|
441
|
+
edit_status: int,
|
|
442
|
+
status: int,
|
|
443
|
+
color_group: list[list[int]] | None = None,
|
|
444
|
+
icon_type: int | None = None,
|
|
445
|
+
consumables_percent: float | None = None,
|
|
446
|
+
) -> None:
|
|
447
|
+
self._index = int(index)
|
|
448
|
+
self._sku = str(sku)
|
|
449
|
+
self._material_type = str(material_type)
|
|
450
|
+
self._color = list([
|
|
451
|
+
int(x) for x in color
|
|
452
|
+
])
|
|
453
|
+
# Every colour on the spool, as RGBA. Single-colour filament reports one
|
|
454
|
+
# entry matching `color`; multi-colour / gradient spools report several.
|
|
455
|
+
self._color_group: list[list[int]] = list([
|
|
456
|
+
list([int(c) for c in entry]) for entry in (color_group or [])
|
|
457
|
+
])
|
|
458
|
+
self._edit_status = int(edit_status)
|
|
459
|
+
self._status = int(status)
|
|
460
|
+
self._icon_type = int(icon_type) if icon_type is not None else None
|
|
461
|
+
self._consumables_percent = (
|
|
462
|
+
float(consumables_percent) if consumables_percent is not None else None
|
|
463
|
+
)
|
|
464
|
+
|
|
465
|
+
@classmethod
|
|
466
|
+
def from_json(cls, data: dict[str, Any] | None) -> AnycubicSpoolInfo | None:
|
|
467
|
+
if data is None:
|
|
468
|
+
return None
|
|
469
|
+
|
|
470
|
+
return cls(
|
|
471
|
+
index=data['index'],
|
|
472
|
+
sku=data['sku'],
|
|
473
|
+
material_type=data['type'],
|
|
474
|
+
color=data['color'],
|
|
475
|
+
edit_status=data['edit_status'],
|
|
476
|
+
status=data['status'],
|
|
477
|
+
color_group=data.get('color_group'),
|
|
478
|
+
icon_type=data.get('icon_type'),
|
|
479
|
+
consumables_percent=data.get('consumables_percent'),
|
|
480
|
+
)
|
|
481
|
+
|
|
482
|
+
@property
|
|
483
|
+
def slot_index(self) -> int:
|
|
484
|
+
return self._index
|
|
485
|
+
|
|
486
|
+
@property
|
|
487
|
+
def sku(self) -> str:
|
|
488
|
+
return self._sku
|
|
489
|
+
|
|
490
|
+
@property
|
|
491
|
+
def material_type(self) -> str:
|
|
492
|
+
return self._material_type
|
|
493
|
+
|
|
494
|
+
@property
|
|
495
|
+
def color(self) -> list[int]:
|
|
496
|
+
return self._color
|
|
497
|
+
|
|
498
|
+
@property
|
|
499
|
+
def color_hex(self) -> str:
|
|
500
|
+
"""Slot colour as #RRGGBB, for dashboard cards and templates."""
|
|
501
|
+
return "#{:02X}{:02X}{:02X}".format(*self._color[:3])
|
|
502
|
+
|
|
503
|
+
@property
|
|
504
|
+
def color_group(self) -> list[list[int]]:
|
|
505
|
+
"""Every colour on the spool as RGBA. Several entries for multi-colour."""
|
|
506
|
+
return self._color_group
|
|
507
|
+
|
|
508
|
+
@property
|
|
509
|
+
def colors_hex(self) -> list[str]:
|
|
510
|
+
"""Every colour on the spool as #RRGGBB, in order."""
|
|
511
|
+
if not self._color_group:
|
|
512
|
+
return [self.color_hex]
|
|
513
|
+
|
|
514
|
+
return [
|
|
515
|
+
"#{:02X}{:02X}{:02X}".format(*entry[:3])
|
|
516
|
+
for entry in self._color_group
|
|
517
|
+
if len(entry) >= 3
|
|
518
|
+
]
|
|
519
|
+
|
|
520
|
+
@property
|
|
521
|
+
def is_multi_color(self) -> bool:
|
|
522
|
+
return len(self._color_group) > 1
|
|
523
|
+
|
|
524
|
+
@property
|
|
525
|
+
def edit_status(self) -> int:
|
|
526
|
+
return self._edit_status
|
|
527
|
+
|
|
528
|
+
@property
|
|
529
|
+
def icon_type(self) -> int | None:
|
|
530
|
+
return self._icon_type
|
|
531
|
+
|
|
532
|
+
@property
|
|
533
|
+
def consumables_percent(self) -> float | None:
|
|
534
|
+
return self._consumables_percent
|
|
535
|
+
|
|
536
|
+
@property
|
|
537
|
+
def color_red(self) -> int:
|
|
538
|
+
return self._color[0]
|
|
539
|
+
|
|
540
|
+
@property
|
|
541
|
+
def color_green(self) -> int:
|
|
542
|
+
return self._color[1]
|
|
543
|
+
|
|
544
|
+
@property
|
|
545
|
+
def color_blue(self) -> int:
|
|
546
|
+
return self._color[2]
|
|
547
|
+
|
|
548
|
+
@property
|
|
549
|
+
def status(self) -> int:
|
|
550
|
+
return self._status
|
|
551
|
+
|
|
552
|
+
@property
|
|
553
|
+
def spool_loaded(self) -> bool:
|
|
554
|
+
return self._status == 5
|
|
555
|
+
|
|
556
|
+
def set_spool_loaded(self, is_loaded: bool) -> None:
|
|
557
|
+
if is_loaded:
|
|
558
|
+
self._status = 5
|
|
559
|
+
else:
|
|
560
|
+
self._status = 4
|
|
561
|
+
|
|
562
|
+
def __repr__(self) -> str:
|
|
563
|
+
return (
|
|
564
|
+
f"AnycubicSpoolInfo(index={self._index}, sku={self._sku}, material_type={self.material_type}, color={self._color}, "
|
|
565
|
+
f"edit_status={self._edit_status}, status={self._status})"
|
|
566
|
+
)
|
|
567
|
+
|
|
568
|
+
|
|
569
|
+
class AnycubicMultiColorBox:
|
|
570
|
+
__slots__ = (
|
|
571
|
+
"_id",
|
|
572
|
+
"_status",
|
|
573
|
+
"_model_id",
|
|
574
|
+
"_auto_feed",
|
|
575
|
+
"_loaded_slot",
|
|
576
|
+
"_feed_status",
|
|
577
|
+
"_temp",
|
|
578
|
+
"_humidity",
|
|
579
|
+
"_drying_status",
|
|
580
|
+
"_curr_nozzle_temp",
|
|
581
|
+
"_target_nozzle_temp",
|
|
582
|
+
"_slots",
|
|
583
|
+
)
|
|
584
|
+
|
|
585
|
+
def __init__(
|
|
586
|
+
self,
|
|
587
|
+
id: int,
|
|
588
|
+
status: int,
|
|
589
|
+
model_id: int,
|
|
590
|
+
auto_feed: int,
|
|
591
|
+
loaded_slot: int,
|
|
592
|
+
feed_status: dict[str, Any] | None,
|
|
593
|
+
temp: int,
|
|
594
|
+
drying_status: dict[str, Any] | None,
|
|
595
|
+
curr_nozzle_temp: int | None,
|
|
596
|
+
target_nozzle_temp: int | None,
|
|
597
|
+
slots: list[dict[str, Any]],
|
|
598
|
+
humidity: float | None = None,
|
|
599
|
+
) -> None:
|
|
600
|
+
self._id: int = int(id)
|
|
601
|
+
self._status: int = int(status)
|
|
602
|
+
self._model_id: int = int(model_id)
|
|
603
|
+
self._auto_feed: int = int(auto_feed)
|
|
604
|
+
self._loaded_slot: int = int(loaded_slot)
|
|
605
|
+
self.set_feed_status(feed_status)
|
|
606
|
+
self.set_current_temperature(temp)
|
|
607
|
+
self._humidity: float | None = (
|
|
608
|
+
float(humidity) if humidity is not None else None
|
|
609
|
+
)
|
|
610
|
+
self.set_drying_status(drying_status)
|
|
611
|
+
self._curr_nozzle_temp: int | None = int(curr_nozzle_temp) if curr_nozzle_temp is not None else None
|
|
612
|
+
self._target_nozzle_temp: int | None = int(target_nozzle_temp) if target_nozzle_temp is not None else None
|
|
613
|
+
self._slots: list[AnycubicSpoolInfo] = list()
|
|
614
|
+
for x in slots:
|
|
615
|
+
if spool := AnycubicSpoolInfo.from_json(x):
|
|
616
|
+
self._slots.append(spool)
|
|
617
|
+
else:
|
|
618
|
+
raise AnycubicDataParsingError(ErrorsDataParsing.ace.format(slots))
|
|
619
|
+
|
|
620
|
+
def set_auto_feed(self, auto_feed: int) -> None:
|
|
621
|
+
self._auto_feed = int(auto_feed)
|
|
622
|
+
|
|
623
|
+
def set_drying_status(self, drying_status: dict[str, Any] | None) -> None:
|
|
624
|
+
self._drying_status = AnycubicDryingStatus.from_json(drying_status)
|
|
625
|
+
|
|
626
|
+
def set_feed_status(self, feed_status: dict[str, Any] | None) -> None:
|
|
627
|
+
self._feed_status = AnycubicFeedStatus.from_json(feed_status)
|
|
628
|
+
|
|
629
|
+
def set_slot_loaded(self, slot_num: int) -> None:
|
|
630
|
+
self._loaded_slot = slot_num
|
|
631
|
+
|
|
632
|
+
def set_current_temperature(self, temp: int) -> None:
|
|
633
|
+
self._temp = int(temp)
|
|
634
|
+
|
|
635
|
+
def update_slots_with_mqtt_data(self, slot_list: list[dict[str, Any]] | None) -> None:
|
|
636
|
+
if slot_list is None:
|
|
637
|
+
return
|
|
638
|
+
|
|
639
|
+
for slot in slot_list:
|
|
640
|
+
slot_index = slot['index']
|
|
641
|
+
if spool := AnycubicSpoolInfo.from_json(slot):
|
|
642
|
+
self._slots[slot_index] = spool
|
|
643
|
+
else:
|
|
644
|
+
raise AnycubicDataParsingError(ErrorsDataParsing.ace.format(slot_list))
|
|
645
|
+
|
|
646
|
+
def build_mapping_for_material_list(
|
|
647
|
+
self,
|
|
648
|
+
slot_index_list: list[int],
|
|
649
|
+
material_list: list[dict[str, Any]],
|
|
650
|
+
) -> list[AnycubicMaterialMapping]:
|
|
651
|
+
box_slots = self.slots
|
|
652
|
+
ams_box_mapping = list()
|
|
653
|
+
|
|
654
|
+
for x, mat_conf in enumerate(material_list):
|
|
655
|
+
slot_index = slot_index_list[x]
|
|
656
|
+
spool_index = slot_index
|
|
657
|
+
slot_index = slot_index - (4 * self.box_id)
|
|
658
|
+
|
|
659
|
+
if slot_index < 0 or slot_index > 3:
|
|
660
|
+
continue
|
|
661
|
+
|
|
662
|
+
ams_slot = box_slots[slot_index]
|
|
663
|
+
material = AnycubicMaterialMapping(
|
|
664
|
+
spool_index=spool_index,
|
|
665
|
+
filament_used=mat_conf['filament_used'],
|
|
666
|
+
material_type=mat_conf['material_type'],
|
|
667
|
+
color_red=ams_slot.color_red,
|
|
668
|
+
color_green=ams_slot.color_green,
|
|
669
|
+
color_blue=ams_slot.color_blue,
|
|
670
|
+
paint_index=mat_conf['paint_index'],
|
|
671
|
+
)
|
|
672
|
+
ams_box_mapping.append(material)
|
|
673
|
+
|
|
674
|
+
return ams_box_mapping
|
|
675
|
+
|
|
676
|
+
@classmethod
|
|
677
|
+
def from_json(cls, data: dict[str, Any] | None) -> AnycubicMultiColorBox | None:
|
|
678
|
+
if data is None:
|
|
679
|
+
return None
|
|
680
|
+
|
|
681
|
+
return cls(
|
|
682
|
+
id=data['id'],
|
|
683
|
+
status=data['status'],
|
|
684
|
+
model_id=data['model_id'],
|
|
685
|
+
auto_feed=data['auto_feed'],
|
|
686
|
+
loaded_slot=data['loaded_slot'],
|
|
687
|
+
feed_status=data['feed_status'],
|
|
688
|
+
temp=data['temp'],
|
|
689
|
+
humidity=data.get('humidity'),
|
|
690
|
+
drying_status=data['drying_status'],
|
|
691
|
+
curr_nozzle_temp=data.get('curr_nozzle_temp'),
|
|
692
|
+
target_nozzle_temp=data.get('target_nozzle_temp'),
|
|
693
|
+
slots=data['slots'],
|
|
694
|
+
)
|
|
695
|
+
|
|
696
|
+
@property
|
|
697
|
+
def current_temperature(self) -> int:
|
|
698
|
+
return self._temp
|
|
699
|
+
|
|
700
|
+
@property
|
|
701
|
+
def model_id(self) -> int:
|
|
702
|
+
return self._model_id
|
|
703
|
+
|
|
704
|
+
@property
|
|
705
|
+
def box_info_object(self) -> dict[str, Any]:
|
|
706
|
+
return {
|
|
707
|
+
"box_id": self._id,
|
|
708
|
+
"model_id": self._model_id,
|
|
709
|
+
"status": self._status,
|
|
710
|
+
"temperature": self._temp,
|
|
711
|
+
"humidity": self._humidity,
|
|
712
|
+
"auto_feed": bool(self._auto_feed),
|
|
713
|
+
"loaded_slot": self._loaded_slot + 1 if self._loaded_slot >= 0 else None,
|
|
714
|
+
"feed_status": (
|
|
715
|
+
self._feed_status.info_object if self._feed_status else None
|
|
716
|
+
),
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
@property
|
|
720
|
+
def humidity(self) -> float | None:
|
|
721
|
+
"""ACE internal humidity. Reads 0 on hardware without the sensor."""
|
|
722
|
+
return self._humidity
|
|
723
|
+
|
|
724
|
+
@property
|
|
725
|
+
def loaded_slot(self) -> int:
|
|
726
|
+
"""Index of the slot currently feeding, or -1 when none is loaded."""
|
|
727
|
+
return self._loaded_slot
|
|
728
|
+
|
|
729
|
+
@property
|
|
730
|
+
def box_id(self) -> int:
|
|
731
|
+
return self._id
|
|
732
|
+
|
|
733
|
+
@property
|
|
734
|
+
def auto_feed(self) -> int:
|
|
735
|
+
return self._auto_feed
|
|
736
|
+
|
|
737
|
+
@property
|
|
738
|
+
def slots(self) -> list[AnycubicSpoolInfo]:
|
|
739
|
+
return self._slots
|
|
740
|
+
|
|
741
|
+
@property
|
|
742
|
+
def total_slots(self) -> int:
|
|
743
|
+
return len(self._slots)
|
|
744
|
+
|
|
745
|
+
@property
|
|
746
|
+
def drying_status(self) -> AnycubicDryingStatus | None:
|
|
747
|
+
return self._drying_status
|
|
748
|
+
|
|
749
|
+
@property
|
|
750
|
+
def spool_info_object(self) -> list[dict[str, Any]] | None:
|
|
751
|
+
if not self._slots or len(self._slots) < 1:
|
|
752
|
+
return None
|
|
753
|
+
|
|
754
|
+
spool_list = list([
|
|
755
|
+
{
|
|
756
|
+
"slot": slot.slot_index + 1,
|
|
757
|
+
"material_type": slot.material_type,
|
|
758
|
+
"color": slot.color,
|
|
759
|
+
"color_hex": slot.color_hex,
|
|
760
|
+
"colors_hex": slot.colors_hex,
|
|
761
|
+
"color_group": slot.color_group,
|
|
762
|
+
"is_multi_color": slot.is_multi_color,
|
|
763
|
+
"sku": slot.sku,
|
|
764
|
+
"status": slot.status,
|
|
765
|
+
"spool_loaded": slot.spool_loaded,
|
|
766
|
+
"edit_status": slot.edit_status,
|
|
767
|
+
"icon_type": slot.icon_type,
|
|
768
|
+
"consumables_percent": slot.consumables_percent,
|
|
769
|
+
} for slot in self._slots
|
|
770
|
+
])
|
|
771
|
+
return spool_list
|
|
772
|
+
|
|
773
|
+
def __repr__(self) -> str:
|
|
774
|
+
return (
|
|
775
|
+
f"AnycubicMultiColorBox(id={self._id}, status={self._status}, model_id={self._model_id}, auto_feed={self._auto_feed}, "
|
|
776
|
+
f"loaded_slot={self._loaded_slot},\n "
|
|
777
|
+
f"temp={self._temp}, curr_nozzle_temp={self._curr_nozzle_temp}, target_nozzle_temp={self._target_nozzle_temp},\n "
|
|
778
|
+
f"feed_status={self._feed_status},\n "
|
|
779
|
+
f"drying_status={self._drying_status},\n "
|
|
780
|
+
f"slots={self._slots})"
|
|
781
|
+
)
|
|
782
|
+
|
|
783
|
+
|
|
784
|
+
class AnycubicMachineData:
|
|
785
|
+
__slots__ = (
|
|
786
|
+
"_name",
|
|
787
|
+
"_pixel",
|
|
788
|
+
"_res_x",
|
|
789
|
+
"_res_y",
|
|
790
|
+
"_format",
|
|
791
|
+
"_size_x",
|
|
792
|
+
"_size_y",
|
|
793
|
+
"_size_z",
|
|
794
|
+
"_suffix",
|
|
795
|
+
"_anti_max",
|
|
796
|
+
)
|
|
797
|
+
|
|
798
|
+
def __init__(
|
|
799
|
+
self,
|
|
800
|
+
name: str,
|
|
801
|
+
pixel: float,
|
|
802
|
+
res_x: int,
|
|
803
|
+
res_y: int,
|
|
804
|
+
format: str,
|
|
805
|
+
size_x: float,
|
|
806
|
+
size_y: float,
|
|
807
|
+
size_z: float,
|
|
808
|
+
suffix: str,
|
|
809
|
+
anti_max: int,
|
|
810
|
+
) -> None:
|
|
811
|
+
self._name = str(name)
|
|
812
|
+
self._pixel = float(pixel)
|
|
813
|
+
self._res_x = int(res_x)
|
|
814
|
+
self._res_y = int(res_y)
|
|
815
|
+
self._format = str(format)
|
|
816
|
+
self._size_x = float(size_x)
|
|
817
|
+
self._size_y = float(size_y)
|
|
818
|
+
self._size_z = float(size_z)
|
|
819
|
+
self._suffix = str(suffix)
|
|
820
|
+
self._anti_max = int(anti_max)
|
|
821
|
+
|
|
822
|
+
@classmethod
|
|
823
|
+
def from_json(cls, data: dict[str, Any] | None) -> AnycubicMachineData | None:
|
|
824
|
+
if data is None:
|
|
825
|
+
return None
|
|
826
|
+
|
|
827
|
+
return cls(
|
|
828
|
+
name=data['name'],
|
|
829
|
+
pixel=data['pixel'],
|
|
830
|
+
res_x=data['res_x'],
|
|
831
|
+
res_y=data['res_y'],
|
|
832
|
+
format=data['format'],
|
|
833
|
+
size_x=data['size_x'],
|
|
834
|
+
size_y=data['size_y'],
|
|
835
|
+
size_z=data['size_z'],
|
|
836
|
+
suffix=data['suffix'],
|
|
837
|
+
anti_max=data['anti_max'],
|
|
838
|
+
)
|
|
839
|
+
|
|
840
|
+
def __repr__(self) -> str:
|
|
841
|
+
return (
|
|
842
|
+
f"AnycubicMachineData(name={self._name}, pixel={self._pixel}, format={self._format}, suffix={self._suffix},\n "
|
|
843
|
+
f"res_x={self._res_x}, res_y={self._res_y}, size_x={self._size_x}, size_y={self._size_y}, size_z={self._size_z}, "
|
|
844
|
+
f"anti_max={self._anti_max})"
|
|
845
|
+
)
|
|
846
|
+
|
|
847
|
+
|
|
848
|
+
class AnycubicMachineParameter:
|
|
849
|
+
__slots__ = (
|
|
850
|
+
"_curr_hotbed_temp",
|
|
851
|
+
"_curr_nozzle_temp",
|
|
852
|
+
)
|
|
853
|
+
|
|
854
|
+
def __init__(
|
|
855
|
+
self,
|
|
856
|
+
curr_hotbed_temp: int,
|
|
857
|
+
curr_nozzle_temp: int,
|
|
858
|
+
) -> None:
|
|
859
|
+
self._curr_hotbed_temp = int(curr_hotbed_temp)
|
|
860
|
+
self._curr_nozzle_temp = int(curr_nozzle_temp)
|
|
861
|
+
|
|
862
|
+
@property
|
|
863
|
+
def curr_hotbed_temp(self) -> int:
|
|
864
|
+
return self._curr_hotbed_temp
|
|
865
|
+
|
|
866
|
+
@property
|
|
867
|
+
def curr_nozzle_temp(self) -> int:
|
|
868
|
+
return self._curr_nozzle_temp
|
|
869
|
+
|
|
870
|
+
@classmethod
|
|
871
|
+
def from_json(cls, data: dict[str, Any] | None) -> AnycubicMachineParameter | None:
|
|
872
|
+
if data is None:
|
|
873
|
+
return None
|
|
874
|
+
|
|
875
|
+
return cls(
|
|
876
|
+
curr_hotbed_temp=data['curr_hotbed_temp'],
|
|
877
|
+
curr_nozzle_temp=data['curr_nozzle_temp'],
|
|
878
|
+
)
|
|
879
|
+
|
|
880
|
+
def update_current_temps(self, new_hotbed_temp: int, new_nozzle_temp: int) -> None:
|
|
881
|
+
self._curr_hotbed_temp = int(new_hotbed_temp)
|
|
882
|
+
self._curr_nozzle_temp = int(new_nozzle_temp)
|
|
883
|
+
|
|
884
|
+
def __repr__(self) -> str:
|
|
885
|
+
return f"AnycubicMachineParameter(curr_hotbed_temp={self._curr_hotbed_temp}, curr_nozzle_temp={self._curr_nozzle_temp})"
|
|
886
|
+
|
|
887
|
+
|
|
888
|
+
class AnycubicMachineFirmwareInfo:
|
|
889
|
+
__slots__ = (
|
|
890
|
+
"_need_update",
|
|
891
|
+
"_firmware_version",
|
|
892
|
+
"_update_progress",
|
|
893
|
+
"_update_date",
|
|
894
|
+
"_update_status",
|
|
895
|
+
"_update_desc",
|
|
896
|
+
"_force_update",
|
|
897
|
+
"_target_version",
|
|
898
|
+
"_time_cost",
|
|
899
|
+
"_box_id",
|
|
900
|
+
"_download_progress",
|
|
901
|
+
"_is_downloading",
|
|
902
|
+
"_is_updating",
|
|
903
|
+
)
|
|
904
|
+
|
|
905
|
+
def __init__(
|
|
906
|
+
self,
|
|
907
|
+
need_update: int,
|
|
908
|
+
firmware_version: str,
|
|
909
|
+
update_progress: int | None = None,
|
|
910
|
+
update_date: int | None = None,
|
|
911
|
+
update_status: str | None = None,
|
|
912
|
+
update_desc: str | None = None,
|
|
913
|
+
force_update: str | None = None,
|
|
914
|
+
target_version: str | None = None,
|
|
915
|
+
time_cost: int | None = None,
|
|
916
|
+
box_id: int | None = None,
|
|
917
|
+
) -> None:
|
|
918
|
+
self.set_need_update(need_update)
|
|
919
|
+
self.set_firmware_version(firmware_version)
|
|
920
|
+
self.set_update_progress(update_progress)
|
|
921
|
+
self.set_update_date(update_date)
|
|
922
|
+
self.set_update_status(update_status)
|
|
923
|
+
self.set_update_desc(update_desc)
|
|
924
|
+
self.set_force_update(force_update)
|
|
925
|
+
self.set_target_version(target_version)
|
|
926
|
+
self.set_time_cost(time_cost)
|
|
927
|
+
self.set_box_id(box_id)
|
|
928
|
+
|
|
929
|
+
self._download_progress: int = 0
|
|
930
|
+
self._is_downloading: bool = False
|
|
931
|
+
self._is_updating: bool = False
|
|
932
|
+
|
|
933
|
+
@property
|
|
934
|
+
def firmware_version(self) -> str:
|
|
935
|
+
return self._firmware_version
|
|
936
|
+
|
|
937
|
+
@property
|
|
938
|
+
def update_available(self) -> bool:
|
|
939
|
+
return self._need_update == 1
|
|
940
|
+
|
|
941
|
+
@property
|
|
942
|
+
def update_progress(self) -> int:
|
|
943
|
+
return self._update_progress
|
|
944
|
+
|
|
945
|
+
@property
|
|
946
|
+
def download_progress(self) -> int:
|
|
947
|
+
return self._download_progress
|
|
948
|
+
|
|
949
|
+
@property
|
|
950
|
+
def total_progress(self) -> int | float | bool:
|
|
951
|
+
if self._is_updating or self._is_downloading:
|
|
952
|
+
if self._update_progress == 0 and self._download_progress > 0:
|
|
953
|
+
return min(self._download_progress / 2, 100)
|
|
954
|
+
elif self._update_progress > 0:
|
|
955
|
+
return min(self._update_progress / 2 + 50, 100)
|
|
956
|
+
return 1
|
|
957
|
+
return False
|
|
958
|
+
|
|
959
|
+
@property
|
|
960
|
+
def available_version(self) -> str | None:
|
|
961
|
+
return self._target_version
|
|
962
|
+
|
|
963
|
+
@property
|
|
964
|
+
def is_updating(self) -> bool:
|
|
965
|
+
return self._is_updating
|
|
966
|
+
|
|
967
|
+
@property
|
|
968
|
+
def is_downloading(self) -> bool:
|
|
969
|
+
return self._is_downloading
|
|
970
|
+
|
|
971
|
+
@classmethod
|
|
972
|
+
def from_json(cls, data: dict[str, Any] | None) -> AnycubicMachineFirmwareInfo | None:
|
|
973
|
+
if data is None:
|
|
974
|
+
return None
|
|
975
|
+
|
|
976
|
+
return cls(
|
|
977
|
+
need_update=data['need_update'],
|
|
978
|
+
firmware_version=data['firmware_version'],
|
|
979
|
+
update_progress=data.get('update_progress'),
|
|
980
|
+
update_date=data.get('update_date'),
|
|
981
|
+
update_status=data.get('update_status'),
|
|
982
|
+
update_desc=data.get('update_desc'),
|
|
983
|
+
force_update=data.get('force_update'),
|
|
984
|
+
target_version=data.get('target_version'),
|
|
985
|
+
time_cost=data.get('time_cost'),
|
|
986
|
+
box_id=data.get('box_id'),
|
|
987
|
+
)
|
|
988
|
+
|
|
989
|
+
def update_from_json(self, data: dict[str, Any] | None) -> None:
|
|
990
|
+
if data is None:
|
|
991
|
+
return
|
|
992
|
+
|
|
993
|
+
self.set_need_update(data['need_update'])
|
|
994
|
+
self.set_firmware_version(data['firmware_version'])
|
|
995
|
+
|
|
996
|
+
if data.get('update_progress') is not None:
|
|
997
|
+
self.set_update_progress(data['update_progress'])
|
|
998
|
+
|
|
999
|
+
self.set_update_date(data.get('update_date'))
|
|
1000
|
+
self.set_update_status(data.get('update_status'))
|
|
1001
|
+
self.set_update_desc(data.get('update_desc'))
|
|
1002
|
+
self.set_force_update(data.get('force_update'))
|
|
1003
|
+
self.set_target_version(data.get('target_version'))
|
|
1004
|
+
self.set_time_cost(data.get('time_cost'))
|
|
1005
|
+
self.set_box_id(data.get('box_id'))
|
|
1006
|
+
|
|
1007
|
+
def update_version(self, new_version: str) -> None:
|
|
1008
|
+
if self._firmware_version != str(new_version):
|
|
1009
|
+
self.set_firmware_version(new_version)
|
|
1010
|
+
|
|
1011
|
+
if self._is_updating:
|
|
1012
|
+
self.set_is_updating(False)
|
|
1013
|
+
|
|
1014
|
+
if self._is_downloading:
|
|
1015
|
+
self.set_is_downloading(False)
|
|
1016
|
+
|
|
1017
|
+
self.set_download_progress(0)
|
|
1018
|
+
self.set_update_progress(0)
|
|
1019
|
+
self.set_need_update(0)
|
|
1020
|
+
|
|
1021
|
+
def set_need_update(self, need_update: int) -> None:
|
|
1022
|
+
self._need_update = int(need_update)
|
|
1023
|
+
|
|
1024
|
+
def set_firmware_version(self, firmware_version: str) -> None:
|
|
1025
|
+
self._firmware_version = str(firmware_version)
|
|
1026
|
+
|
|
1027
|
+
def set_update_date(self, update_date: int | None) -> None:
|
|
1028
|
+
self._update_date = int(update_date) if update_date is not None else None
|
|
1029
|
+
|
|
1030
|
+
def set_update_status(self, update_status: str | None) -> None:
|
|
1031
|
+
self._update_status = str(update_status) if update_status is not None else None
|
|
1032
|
+
|
|
1033
|
+
def set_update_desc(self, update_desc: str | None) -> None:
|
|
1034
|
+
self._update_desc = str(update_desc) if update_desc is not None else None
|
|
1035
|
+
|
|
1036
|
+
def set_force_update(self, force_update: str | None) -> None:
|
|
1037
|
+
self._force_update = str(force_update) if force_update is not None else None
|
|
1038
|
+
|
|
1039
|
+
def set_target_version(self, target_version: str | None) -> None:
|
|
1040
|
+
self._target_version = str(target_version) if target_version is not None else None
|
|
1041
|
+
|
|
1042
|
+
def set_time_cost(self, time_cost: int | None) -> None:
|
|
1043
|
+
self._time_cost = int(time_cost) if time_cost is not None else None
|
|
1044
|
+
|
|
1045
|
+
def set_box_id(self, box_id: int | None) -> None:
|
|
1046
|
+
self._box_id = int(box_id) if box_id is not None else None
|
|
1047
|
+
|
|
1048
|
+
def set_is_updating(self, is_updating: bool) -> None:
|
|
1049
|
+
self._is_updating = bool(is_updating)
|
|
1050
|
+
|
|
1051
|
+
def set_is_downloading(self, is_downloading: bool) -> None:
|
|
1052
|
+
self._is_downloading = bool(is_downloading)
|
|
1053
|
+
|
|
1054
|
+
def set_update_progress(self, update_progress: int | None) -> None:
|
|
1055
|
+
self._update_progress = int(update_progress) if update_progress is not None else 0
|
|
1056
|
+
|
|
1057
|
+
def set_download_progress(self, download_progress: int) -> None:
|
|
1058
|
+
self._download_progress = int(download_progress)
|
|
1059
|
+
|
|
1060
|
+
def __repr__(self) -> str:
|
|
1061
|
+
return f"AnycubicMachineFirmwareInfo(need_update={self._need_update}, firmware_version={self._firmware_version})"
|
|
1062
|
+
|
|
1063
|
+
|
|
1064
|
+
class AnycubicMachineColorInfo:
|
|
1065
|
+
__slots__ = (
|
|
1066
|
+
"_raw_color_list",
|
|
1067
|
+
"_color_list",
|
|
1068
|
+
)
|
|
1069
|
+
|
|
1070
|
+
def __init__(
|
|
1071
|
+
self,
|
|
1072
|
+
color_list: list[list[int]],
|
|
1073
|
+
) -> None:
|
|
1074
|
+
self._raw_color_list: list[list[int]] = color_list
|
|
1075
|
+
self._color_list: list[list[int]] = list()
|
|
1076
|
+
self._set_color_list()
|
|
1077
|
+
|
|
1078
|
+
def _set_color_list(
|
|
1079
|
+
self,
|
|
1080
|
+
) -> None:
|
|
1081
|
+
extended_colors_found = False
|
|
1082
|
+
if len(self._raw_color_list) > 4:
|
|
1083
|
+
for x in self._raw_color_list[4:]:
|
|
1084
|
+
if any([c != -2 for c in x]):
|
|
1085
|
+
extended_colors_found = True
|
|
1086
|
+
|
|
1087
|
+
self._color_list = (
|
|
1088
|
+
self._raw_color_list[:4]
|
|
1089
|
+
if not extended_colors_found else
|
|
1090
|
+
self._raw_color_list[:]
|
|
1091
|
+
)
|
|
1092
|
+
|
|
1093
|
+
@classmethod
|
|
1094
|
+
def from_json(cls, data: list[list[int]] | None) -> AnycubicMachineColorInfo | None:
|
|
1095
|
+
if data is None or not isinstance(data, list):
|
|
1096
|
+
return None
|
|
1097
|
+
|
|
1098
|
+
return cls(
|
|
1099
|
+
color_list=data,
|
|
1100
|
+
)
|
|
1101
|
+
|
|
1102
|
+
@property
|
|
1103
|
+
def color_list(self) -> list[list[int]]:
|
|
1104
|
+
return self._color_list
|
|
1105
|
+
|
|
1106
|
+
def __repr__(self) -> str:
|
|
1107
|
+
return f"AnycubicMachineColorInfo(color_list={self.color_list})"
|