| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- """An AMS change no longer re-selects a spool's stored K-profile itself.
- It used to set the slot back to the stored profile whenever its cali_idx
- differed, so a profile picked on purpose in Bambu Studio or on the printer's
- screen was undone by the next AMS report that changed the slot. The #3219
- drift check already puts back a *lost* selection (cali_idx -1 or missing)
- while the printer is idle, and leaves a different real profile, a deliberate
- "Default" and the other hotend's calibration alone. It is now the only path.
- """
- from unittest.mock import AsyncMock, MagicMock, patch
- import pytest
- from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker
- from backend.app.models.spool import Spool
- from backend.app.models.spool_assignment import SpoolAssignment
- from backend.app.models.spool_k_profile import SpoolKProfile
- from backend.app.services import kprofile_drift
- from backend.app.services.usage_tracker import _active_sessions
- TAG_UID = "A1B2C3D4E5F60708"
- TRAY_UUID = "0123456789ABCDEF0123456789ABCDEF"
- @pytest.fixture(autouse=True)
- def _no_sessions():
- _active_sessions.clear()
- yield
- _active_sessions.clear()
- async def _ams_push(test_engine, db_session, printer_factory, *, live_cali_idx, state="IDLE") -> MagicMock:
- from backend.app.main import on_ams_change
- printer = await printer_factory(name="X1C")
- spool = Spool(material="PLA", label_weight=1000, weight_used=0, tag_uid=TAG_UID, tray_uuid=TRAY_UUID)
- db_session.add(spool)
- await db_session.flush()
- db_session.add(
- SpoolKProfile(
- spool_id=spool.id, printer_id=printer.id, extruder=0, nozzle_diameter="0.4", k_value=0.02, cali_idx=7
- )
- )
- db_session.add(
- SpoolAssignment(
- spool_id=spool.id,
- printer_id=printer.id,
- ams_id=0,
- tray_id=0,
- fingerprint_color="FF0000FF",
- fingerprint_type="PLA",
- )
- )
- await db_session.commit()
- tray = {
- "id": 0,
- "tray_type": "PLA",
- "tray_color": "FF0000FF",
- "tag_uid": TAG_UID,
- "tray_uuid": TRAY_UUID,
- "tray_info_idx": "GFA00",
- "remain": -1,
- }
- if live_cali_idx is not None:
- tray["cali_idx"] = live_cali_idx
- ams_data = [{"id": 0, "tray": [tray]}]
- status = MagicMock()
- status.raw_data = {"ams": {"ams": ams_data}}
- status.state = state
- status.connected = True
- client = MagicMock()
- real_db = async_sessionmaker(test_engine, class_=AsyncSession, expire_on_commit=False)
- with (
- patch("backend.app.main.async_session", real_db),
- patch("backend.app.core.database.async_session", real_db),
- patch("backend.app.main.printer_manager") as mock_pm,
- patch("backend.app.main.mqtt_relay") as mock_relay,
- patch("backend.app.main.ws_manager") as mock_ws,
- ):
- mock_pm.get_printer.return_value = MagicMock(name="X1C", serial_number="KREAPPLY")
- mock_pm.get_status.return_value = status
- mock_pm.get_client.return_value = client
- mock_pm.get_model.return_value = "X1C"
- mock_relay.on_ams_change = AsyncMock()
- mock_ws.send_printer_status = AsyncMock()
- mock_ws.broadcast = AsyncMock()
- await on_ams_change(printer.id, ams_data)
- return client
- @pytest.mark.asyncio
- @pytest.mark.integration
- @pytest.mark.parametrize("live", [-1, None, 3])
- async def test_the_ams_change_leaves_the_selection_to_the_drift_check(test_engine, db_session, printer_factory, live):
- client = await _ams_push(test_engine, db_session, printer_factory, live_cali_idx=live)
- client.extrusion_cali_sel.assert_not_called()
- @pytest.mark.parametrize(("live", "picked_up"), [(-1, True), (None, True), (3, False)])
- def test_the_drift_check_picks_up_only_a_lost_selection(live, picked_up):
- kprofile_drift._watches.clear()
- tray = {"id": 0, "tray_type": "PLA"}
- if live is not None:
- tray["cali_idx"] = live
- state = MagicMock(connected=True, state="IDLE", raw_data={"ams": [{"id": 0, "tray": [tray]}]})
- try:
- assert kprofile_drift.needs_check(4242, state) is picked_up
- finally:
- kprofile_drift._watches.clear()
|