anycubic-cloud-api 0.4.2__tar.gz → 0.4.4__tar.gz

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.
Files changed (49) hide show
  1. anycubic_cloud_api-0.4.4/COPYRIGHT +54 -0
  2. anycubic_cloud_api-0.4.4/MANIFEST.in +3 -0
  3. {anycubic_cloud_api-0.4.2/src/anycubic_cloud_api.egg-info → anycubic_cloud_api-0.4.4}/PKG-INFO +27 -3
  4. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/README.md +25 -1
  5. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/pyproject.toml +5 -1
  6. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/src/anycubic_cloud_api/const/enums.py +2 -0
  7. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/src/anycubic_cloud_api/data_models/project.py +5 -3
  8. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4/src/anycubic_cloud_api.egg-info}/PKG-INFO +27 -3
  9. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/src/anycubic_cloud_api.egg-info/SOURCES.txt +2 -0
  10. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/tests/test_lan_reports.py +64 -0
  11. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/LICENSE +0 -0
  12. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/setup.cfg +0 -0
  13. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/src/anycubic_cloud_api/__init__.py +0 -0
  14. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/src/anycubic_cloud_api/anycubic_api.py +0 -0
  15. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/src/anycubic_cloud_api/api/base.py +0 -0
  16. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/src/anycubic_cloud_api/api/functions.py +0 -0
  17. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/src/anycubic_cloud_api/api/mqtt.py +0 -0
  18. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/src/anycubic_cloud_api/const/api_endpoints.py +0 -0
  19. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/src/anycubic_cloud_api/const/const.py +0 -0
  20. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/src/anycubic_cloud_api/const/lan.py +0 -0
  21. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/src/anycubic_cloud_api/const/mqtt.py +0 -0
  22. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/src/anycubic_cloud_api/data_models/consumable.py +0 -0
  23. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/src/anycubic_cloud_api/data_models/files.py +0 -0
  24. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/src/anycubic_cloud_api/data_models/gcode_file.py +0 -0
  25. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/src/anycubic_cloud_api/data_models/orders.py +0 -0
  26. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/src/anycubic_cloud_api/data_models/print_response.py +0 -0
  27. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/src/anycubic_cloud_api/data_models/print_speed_mode.py +0 -0
  28. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/src/anycubic_cloud_api/data_models/printer.py +0 -0
  29. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/src/anycubic_cloud_api/data_models/printer_properties.py +0 -0
  30. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/src/anycubic_cloud_api/data_models/printing_settings.py +0 -0
  31. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/src/anycubic_cloud_api/exceptions/error_strings.py +0 -0
  32. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/src/anycubic_cloud_api/exceptions/exceptions.py +0 -0
  33. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/src/anycubic_cloud_api/helpers/helpers.py +0 -0
  34. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/src/anycubic_cloud_api/lan/__init__.py +0 -0
  35. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/src/anycubic_cloud_api/lan/client.py +0 -0
  36. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/src/anycubic_cloud_api/lan/handshake.py +0 -0
  37. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/src/anycubic_cloud_api/models/auth.py +0 -0
  38. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/src/anycubic_cloud_api/models/cloud_upload.py +0 -0
  39. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/src/anycubic_cloud_api/models/http.py +0 -0
  40. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/src/anycubic_cloud_api/resources/anycubic_mqqt_tls_ca.crt +0 -0
  41. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/src/anycubic_cloud_api/resources/anycubic_mqqt_tls_client.crt +0 -0
  42. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/src/anycubic_cloud_api/resources/anycubic_mqqt_tls_client.key +0 -0
  43. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/src/anycubic_cloud_api.egg-info/dependency_links.txt +0 -0
  44. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/src/anycubic_cloud_api.egg-info/requires.txt +0 -0
  45. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/src/anycubic_cloud_api.egg-info/top_level.txt +0 -0
  46. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/tests/test_axis_position.py +0 -0
  47. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/tests/test_lan_client.py +0 -0
  48. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/tests/test_lan_handshake.py +0 -0
  49. {anycubic_cloud_api-0.4.2 → anycubic_cloud_api-0.4.4}/tests/test_partial_reports.py +0 -0
@@ -0,0 +1,54 @@
1
+ anycubic-cloud-api
2
+ ==================
3
+
4
+ Copyright (C) 2024-2026 WaresWichall
5
+ Copyright (C) 2026 Nino Bondonno
6
+
7
+ This library originated as part of the Home Assistant integration
8
+ "hass-anycubic_cloud" by WaresWichall:
9
+
10
+ https://github.com/WaresWichall/hass-anycubic_cloud
11
+
12
+ It was extracted into a standalone package, modified and extended by
13
+ Nino Bondonno from 2026 onwards. Modifications include the LAN Mode
14
+ client, filament-usage estimation, tolerant parsing of partial printer
15
+ reports, and the test suite.
16
+
17
+ This program is free software: you can redistribute it and/or modify it
18
+ under the terms of the GNU General Public License as published by the
19
+ Free Software Foundation, either version 3 of the License, or (at your
20
+ option) any later version.
21
+
22
+ This program is distributed in the hope that it will be useful, but
23
+ WITHOUT ANY WARRANTY; without even the implied warranty of
24
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25
+ General Public License for more details.
26
+
27
+ You should have received a copy of the GNU General Public License along
28
+ with this program. If not, see <https://www.gnu.org/licenses/>.
29
+
30
+
31
+ THIRD-PARTY MATERIAL — NOT COVERED BY THIS LICENCE
32
+ --------------------------------------------------
33
+
34
+ src/anycubic_cloud_api/resources/
35
+ anycubic_mqqt_tls_ca.crt
36
+ anycubic_mqqt_tls_client.crt
37
+ anycubic_mqqt_tls_client.key
38
+
39
+ These are Anycubic's own X.509 certificates and the matching client key,
40
+ issued by "AC Root CA, O=Anycubic" to "CN=AnycubicSlicer". They are the
41
+ property of Shenzhen Anycubic Technology Co., Ltd.
42
+
43
+ They are NOT the work of the authors above, are NOT licensed under the GNU
44
+ General Public License, and no claim of ownership over them is made here.
45
+ They are included solely because Anycubic's MQTT broker requires mutual TLS
46
+ using this identity, and there is no other way for a third-party client to
47
+ connect to a service the user already has an account with.
48
+
49
+ They are a shared identity distributed inside Anycubic's own desktop slicer,
50
+ not a per-user credential, and were present in the upstream project this is
51
+ derived from.
52
+
53
+ If Anycubic would prefer these were not redistributed, contact the maintainer
54
+ and they will be removed.
@@ -0,0 +1,3 @@
1
+ include LICENSE
2
+ include COPYRIGHT
3
+ include README.md
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: anycubic-cloud-api
3
- Version: 0.4.2
3
+ Version: 0.4.4
4
4
  Summary: Async client for the Anycubic Cloud API and its MQTT stream
5
- Author: Nino Bondonno
5
+ Author: WaresWichall, Nino Bondonno
6
6
  Maintainer: Nino Bondonno
7
7
  License: GPL-3.0-or-later
8
8
  Project-URL: Homepage, https://github.com/Nino6689/anycubic-cloud-api
@@ -29,9 +29,33 @@ Dynamic: license-file
29
29
 
30
30
  Async Python client for the **Anycubic Cloud** API and its MQTT telemetry stream.
31
31
 
32
- Extracted from the [Home Assistant Anycubic Cloud integration](https://github.com/Nino6689/hass-anycubic_cloud)
32
+ Extracted from the [Home Assistant Anycubic integration](https://github.com/Nino6689/hass-anycubic)
33
33
  so it can be versioned, tested and used independently.
34
34
 
35
+ ## Attribution
36
+
37
+ **The bulk of this library is the work of [@WaresWichall](https://github.com/WaresWichall), from
38
+ [hass-anycubic_cloud](https://github.com/WaresWichall/hass-anycubic_cloud)** — the Anycubic cloud
39
+ API client, the MQTT layer and the printer data models all originated there, under GPL-3.0.
40
+
41
+ This package extracts that code so it can be versioned and tested on its own, and adds to it:
42
+ the LAN Mode client, the filament-usage maths, tolerant parsing of partial reports, and the test
43
+ suite. Those additions and modifications are by [@Nino6689](https://github.com/Nino6689), from
44
+ 2026 onwards.
45
+
46
+ It remains **GPL-3.0-or-later**, as it must.
47
+
48
+ ### Anycubic's certificates
49
+
50
+ This package ships Anycubic's own TLS certificates and client key, because their MQTT broker
51
+ requires mutual TLS using that identity and there is no other way for a third-party client to reach
52
+ it. **They are Anycubic's property, not covered by this licence, and no ownership is claimed** — see
53
+ [COPYRIGHT](COPYRIGHT). They are a shared identity taken from Anycubic's own slicer rather than a
54
+ per-user credential, and they came from the upstream project this is derived from.
55
+
56
+ The **LAN Mode** client needs none of this. If you only talk to the printer locally, no Anycubic
57
+ credential is involved at any point.
58
+
35
59
  ## Install
36
60
 
37
61
  ```bash
@@ -2,9 +2,33 @@
2
2
 
3
3
  Async Python client for the **Anycubic Cloud** API and its MQTT telemetry stream.
4
4
 
5
- Extracted from the [Home Assistant Anycubic Cloud integration](https://github.com/Nino6689/hass-anycubic_cloud)
5
+ Extracted from the [Home Assistant Anycubic integration](https://github.com/Nino6689/hass-anycubic)
6
6
  so it can be versioned, tested and used independently.
7
7
 
8
+ ## Attribution
9
+
10
+ **The bulk of this library is the work of [@WaresWichall](https://github.com/WaresWichall), from
11
+ [hass-anycubic_cloud](https://github.com/WaresWichall/hass-anycubic_cloud)** — the Anycubic cloud
12
+ API client, the MQTT layer and the printer data models all originated there, under GPL-3.0.
13
+
14
+ This package extracts that code so it can be versioned and tested on its own, and adds to it:
15
+ the LAN Mode client, the filament-usage maths, tolerant parsing of partial reports, and the test
16
+ suite. Those additions and modifications are by [@Nino6689](https://github.com/Nino6689), from
17
+ 2026 onwards.
18
+
19
+ It remains **GPL-3.0-or-later**, as it must.
20
+
21
+ ### Anycubic's certificates
22
+
23
+ This package ships Anycubic's own TLS certificates and client key, because their MQTT broker
24
+ requires mutual TLS using that identity and there is no other way for a third-party client to reach
25
+ it. **They are Anycubic's property, not covered by this licence, and no ownership is claimed** — see
26
+ [COPYRIGHT](COPYRIGHT). They are a shared identity taken from Anycubic's own slicer rather than a
27
+ per-user credential, and they came from the upstream project this is derived from.
28
+
29
+ The **LAN Mode** client needs none of this. If you only talk to the printer locally, no Anycubic
30
+ credential is involved at any point.
31
+
8
32
  ## Install
9
33
 
10
34
  ```bash
@@ -4,12 +4,16 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "anycubic-cloud-api"
7
- version = "0.4.2"
7
+ version = "0.4.4"
8
8
  description = "Async client for the Anycubic Cloud API and its MQTT stream"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
11
11
  license = { text = "GPL-3.0-or-later" }
12
+ # Most of this library originated in WaresWichall's Home Assistant
13
+ # integration; it is extracted, modified and extended here. See the
14
+ # attribution section of the README.
12
15
  authors = [
16
+ { name = "WaresWichall" },
13
17
  { name = "Nino Bondonno" },
14
18
  ]
15
19
  maintainers = [
@@ -15,6 +15,8 @@ class AnycubicPrintStatus(IntEnum):
15
15
  Checking = 5
16
16
  Preheating = 6
17
17
  Slicing = 7
18
+ # 8 is unclaimed -- no printer has been observed reporting it.
19
+ Levelling = 9
18
20
 
19
21
 
20
22
  class AnycubicOrderID(IntEnum):
@@ -1018,10 +1018,12 @@ class AnycubicProject:
1018
1018
  return "preheating"
1019
1019
  elif self._print_status == AnycubicPrintStatus.Slicing:
1020
1020
  return "slicing"
1021
+ elif self._print_status == AnycubicPrintStatus.Levelling:
1022
+ return "levelling"
1021
1023
 
1022
- # Newer firmware reports codes this enum doesn't cover -- a Kobra S1
1023
- # sends 9 while levelling. The printer also sends a plain-text phase
1024
- # alongside it, which is far more useful than "unknown", so prefer it.
1024
+ # Newer firmware still reports codes this enum doesn't cover. The
1025
+ # printer sends a plain-text phase alongside the code, which is far
1026
+ # more useful than "unknown", so prefer it over giving up.
1025
1027
  reported_state = self._get_print_setting('state')
1026
1028
 
1027
1029
  if reported_state:
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: anycubic-cloud-api
3
- Version: 0.4.2
3
+ Version: 0.4.4
4
4
  Summary: Async client for the Anycubic Cloud API and its MQTT stream
5
- Author: Nino Bondonno
5
+ Author: WaresWichall, Nino Bondonno
6
6
  Maintainer: Nino Bondonno
7
7
  License: GPL-3.0-or-later
8
8
  Project-URL: Homepage, https://github.com/Nino6689/anycubic-cloud-api
@@ -29,9 +29,33 @@ Dynamic: license-file
29
29
 
30
30
  Async Python client for the **Anycubic Cloud** API and its MQTT telemetry stream.
31
31
 
32
- Extracted from the [Home Assistant Anycubic Cloud integration](https://github.com/Nino6689/hass-anycubic_cloud)
32
+ Extracted from the [Home Assistant Anycubic integration](https://github.com/Nino6689/hass-anycubic)
33
33
  so it can be versioned, tested and used independently.
34
34
 
35
+ ## Attribution
36
+
37
+ **The bulk of this library is the work of [@WaresWichall](https://github.com/WaresWichall), from
38
+ [hass-anycubic_cloud](https://github.com/WaresWichall/hass-anycubic_cloud)** — the Anycubic cloud
39
+ API client, the MQTT layer and the printer data models all originated there, under GPL-3.0.
40
+
41
+ This package extracts that code so it can be versioned and tested on its own, and adds to it:
42
+ the LAN Mode client, the filament-usage maths, tolerant parsing of partial reports, and the test
43
+ suite. Those additions and modifications are by [@Nino6689](https://github.com/Nino6689), from
44
+ 2026 onwards.
45
+
46
+ It remains **GPL-3.0-or-later**, as it must.
47
+
48
+ ### Anycubic's certificates
49
+
50
+ This package ships Anycubic's own TLS certificates and client key, because their MQTT broker
51
+ requires mutual TLS using that identity and there is no other way for a third-party client to reach
52
+ it. **They are Anycubic's property, not covered by this licence, and no ownership is claimed** — see
53
+ [COPYRIGHT](COPYRIGHT). They are a shared identity taken from Anycubic's own slicer rather than a
54
+ per-user credential, and they came from the upstream project this is derived from.
55
+
56
+ The **LAN Mode** client needs none of this. If you only talk to the printer locally, no Anycubic
57
+ credential is involved at any point.
58
+
35
59
  ## Install
36
60
 
37
61
  ```bash
@@ -1,4 +1,6 @@
1
+ COPYRIGHT
1
2
  LICENSE
3
+ MANIFEST.in
2
4
  README.md
3
5
  pyproject.toml
4
6
  src/anycubic_cloud_api/__init__.py
@@ -415,3 +415,67 @@ class TestWhatTheCloudWouldHaveSaid:
415
415
  )
416
416
 
417
417
  assert printer.supports_function_multi_color_box is True
418
+
419
+
420
+ class TestLevellingStatus:
421
+ """Upstream issue #55: job state read 'unknown' while the printer levelled.
422
+
423
+ The status enum stopped at 7, so code 9 fell through as unrecognised.
424
+ """
425
+
426
+ def test_levelling_is_a_known_status(self):
427
+ from anycubic_cloud_api.const.enums import AnycubicPrintStatus
428
+
429
+ assert AnycubicPrintStatus(9).name == "Levelling"
430
+
431
+ def test_the_existing_statuses_are_unchanged(self):
432
+ """Their numbers are on the wire; renumbering would break history."""
433
+ from anycubic_cloud_api.const.enums import AnycubicPrintStatus
434
+
435
+ assert [(s.name, s.value) for s in AnycubicPrintStatus] == [
436
+ ("Printing", 1),
437
+ ("Complete", 2),
438
+ ("Cancelled", 3),
439
+ ("Downloading", 4),
440
+ ("Checking", 5),
441
+ ("Preheating", 6),
442
+ ("Slicing", 7),
443
+ ("Levelling", 9),
444
+ ]
445
+
446
+
447
+ class TestLevellingReadsAsLevelling:
448
+ """The job state should say what the printer is doing, not "unknown"."""
449
+
450
+ def _status(self, code, reported=None):
451
+ from anycubic_cloud_api.data_models.project import AnycubicProject
452
+
453
+ class Stub(AnycubicProject):
454
+ """Only the two inputs print_status reads, so no full project."""
455
+
456
+ __slots__ = ("_reported",)
457
+
458
+ def __init__(self, code, reported):
459
+ self._print_status = code
460
+ self._reported = reported
461
+
462
+ @property
463
+ def print_is_paused(self):
464
+ return False
465
+
466
+ def _get_print_setting(self, key):
467
+ return self._reported if key == "state" else None
468
+
469
+ return Stub(code, reported).print_status
470
+
471
+ def test_levelling(self):
472
+ assert self._status(9) == "levelling"
473
+
474
+ def test_printing_is_unaffected(self):
475
+ assert self._status(1) == "printing"
476
+
477
+ def test_an_unmapped_code_prefers_the_printers_own_words(self):
478
+ assert self._status(99, reported="calibrating") == "calibrating"
479
+
480
+ def test_an_unmapped_code_with_no_text_is_unknown(self):
481
+ assert self._status(99) == "unknown"