test_h2d_tray_now_same_frame_g11.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. """H2D active tray: the extruder block of a frame is read before its AMS block.
  2. An H2D reports tray_now as a bare slot (0-3) and names the AMS in each
  3. extruder's ``snow``. Both often arrive in one frame, but the AMS block was
  4. handled first, so tray_now was resolved against the previous frame's snow --
  5. and on a disagreement that stale snow won. Now a frame's snow is read first,
  6. and a snow from an earlier frame no longer overrides the slot the printer just
  7. reported: the AMS-to-nozzle map places it instead.
  8. """
  9. import pytest
  10. from backend.app.services.bambu_mqtt import BambuMQTTClient
  11. def _frame(*, tray_now=None, snow_right=None, state=0x0000):
  12. print_data: dict = {}
  13. if snow_right is not None:
  14. print_data["device"] = {
  15. "extruder": {
  16. "info": [{"id": 0, "snow": snow_right}, {"id": 1, "snow": 0xFFFF}],
  17. "state": state,
  18. }
  19. }
  20. if tray_now is not None:
  21. print_data["ams"] = {"tray_now": str(tray_now)}
  22. return {"print": print_data}
  23. @pytest.fixture
  24. def h2d():
  25. """H2D, right nozzle active, AMS 0 on the right nozzle, AMS-HT 128 on the left."""
  26. client = BambuMQTTClient(ip_address="10.0.0.2", serial_number="TEST_H2D_G11", access_code="x")
  27. client._process_message(
  28. {
  29. "print": {
  30. "device": {"extruder": {"info": [{"id": 0, "snow": 0xFFFF}, {"id": 1, "snow": 0xFFFF}], "state": 0}},
  31. "ams": {
  32. "ams": [
  33. {"id": 0, "info": "2003", "tray": [{"id": i} for i in range(4)]},
  34. {"id": 128, "info": "2104", "tray": [{"id": 0}]},
  35. ],
  36. "tray_now": "255",
  37. },
  38. }
  39. }
  40. )
  41. assert client._is_dual_nozzle
  42. return client
  43. def test_a_frame_carrying_both_uses_its_own_snow(h2d):
  44. h2d._process_message(_frame(tray_now=0, snow_right=0x0000)) # AMS 0 slot 0
  45. assert h2d.state.tray_now == 0
  46. h2d._process_message(_frame(tray_now=2, snow_right=0x0002)) # swap to AMS 0 slot 2
  47. assert h2d.state.tray_now == 2
  48. def test_a_stale_snow_does_not_override_the_reported_slot(h2d):
  49. h2d._process_message(_frame(tray_now=0, snow_right=0x0000))
  50. h2d._process_message(_frame(tray_now=2)) # no extruder block in this frame
  51. # One AMS on the active nozzle: the map places slot 2 there.
  52. assert h2d.state.tray_now == 2
  53. def test_a_fresh_snow_still_wins_a_disagreement(h2d):
  54. """The extruder's own report of its slot is the newer, complete answer."""
  55. h2d._process_message(_frame(tray_now=0, snow_right=0x0003))
  56. assert h2d.state.tray_now == 3
  57. def test_extruder_info_without_snow_is_not_a_fresh_snow(h2d):
  58. """A temperature-only update of the extruder block names no tray."""
  59. h2d._process_message(_frame(tray_now=0, snow_right=0x0000))
  60. h2d._process_message(
  61. {
  62. "print": {
  63. "device": {"extruder": {"info": [{"id": 0, "temp": 200}, {"id": 1, "temp": 30}], "state": 0}},
  64. "ams": {"tray_now": "2"},
  65. }
  66. }
  67. )
  68. assert h2d.state.tray_now == 2
  69. def test_a_nozzle_switch_in_the_same_frame_uses_the_new_nozzle(h2d):
  70. """Left nozzle (bit 8) feeds from the AMS-HT 128, whose one tray is slot 0."""
  71. h2d._process_message(
  72. {
  73. "print": {
  74. "device": {
  75. "extruder": {"info": [{"id": 0, "snow": 0x0002}, {"id": 1, "snow": 128 << 8}], "state": 0x100}
  76. },
  77. "ams": {"tray_now": "0"},
  78. }
  79. }
  80. )
  81. assert h2d.state.active_extruder == 1
  82. assert h2d.state.tray_now == 128
  83. @pytest.mark.parametrize(
  84. "info", [[{"id": 0, "snow": "x2"}, {"id": 1, "snow": 65535}], ["junk", {"id": "x", "snow": 1}]]
  85. )
  86. def test_malformed_extruder_data_does_not_lose_the_frame(h2d, info):
  87. h2d._process_message(
  88. {
  89. "print": {
  90. "device": {"extruder": {"info": info, "state": 0}},
  91. "ams": {"tray_now": "1"},
  92. "gcode_state": "RUNNING",
  93. }
  94. }
  95. )
  96. assert h2d.state.state == "RUNNING"
  97. assert h2d.state.tray_now == 1