Files
core/tests/components/octoprint/test_number.py
2025-11-08 15:15:25 +01:00

247 lines
7.6 KiB
Python

"""The tests for OctoPrint number module."""
from datetime import UTC, datetime
from typing import Any
from unittest.mock import patch
import pytest
from syrupy.assertion import SnapshotAssertion
from homeassistant.components.number import (
ATTR_VALUE,
DOMAIN as NUMBER_DOMAIN,
SERVICE_SET_VALUE,
)
from homeassistant.const import ATTR_ENTITY_ID, STATE_UNKNOWN, Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from tests.common import MockConfigEntry, snapshot_platform
@pytest.fixture
def platform() -> Platform:
"""Fixture to specify platform."""
return Platform.NUMBER
@pytest.fixture
def job() -> dict[str, Any]:
"""Job fixture."""
return __standard_job()
@pytest.mark.parametrize(
"printer",
[
{
"state": {
"flags": {"printing": True},
"text": "Operational",
},
"temperature": {
"tool0": {"actual": 18.83136, "target": 37.83136},
"tool1": {"actual": 21.0, "target": 31.0},
"bed": {"actual": 25.5, "target": 60.0},
},
},
],
)
@pytest.mark.freeze_time(datetime(2020, 2, 20, 9, 10, 13, 543, tzinfo=UTC))
async def test_numbers(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
snapshot: SnapshotAssertion,
init_integration: MockConfigEntry,
) -> None:
"""Test the underlying number entities."""
await snapshot_platform(hass, entity_registry, snapshot, init_integration.entry_id)
@pytest.mark.parametrize(
"printer",
[
{
"state": {
"flags": {"printing": True, "paused": False},
"text": "Operational",
},
"temperature": {
"tool0": {"actual": 18.83136, "target": None},
"bed": {"actual": 25.5, "target": None},
},
},
],
)
@pytest.mark.freeze_time(datetime(2020, 2, 20, 9, 10, 0))
@pytest.mark.usefixtures("init_integration")
async def test_numbers_no_target_temp(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
) -> None:
"""Test the number entities when target temperature is None."""
state = hass.states.get("number.octoprint_extruder_temperature")
assert state is not None
assert state.state == STATE_UNKNOWN
assert state.name == "OctoPrint Extruder temperature"
entry = entity_registry.async_get("number.octoprint_extruder_temperature")
assert entry.unique_id == "uuid_tool0_temperature"
state = hass.states.get("number.octoprint_bed_temperature")
assert state is not None
assert state.state == STATE_UNKNOWN
assert state.name == "OctoPrint Bed temperature"
entry = entity_registry.async_get("number.octoprint_bed_temperature")
assert entry.unique_id == "uuid_bed_temperature"
@pytest.mark.parametrize(
"printer",
[
{
"state": {
"flags": {"printing": False},
"text": "Operational",
},
"temperature": {"tool0": {"actual": 18.83136, "target": 25.0}},
},
],
)
@pytest.mark.freeze_time(datetime(2020, 2, 20, 9, 10, 0))
@pytest.mark.usefixtures("init_integration")
async def test_set_tool_temp(
hass: HomeAssistant,
) -> None:
"""Test setting tool temperature via number entity."""
with patch(
"pyoctoprintapi.OctoprintClient.set_tool_temperature"
) as mock_set_tool_temp:
entity_component = hass.data[NUMBER_DOMAIN]
entity = entity_component.get_entity("number.octoprint_extruder_temperature")
assert entity is not None
await hass.services.async_call(
NUMBER_DOMAIN,
SERVICE_SET_VALUE,
{ATTR_ENTITY_ID: entity.entity_id, ATTR_VALUE: 200.4},
blocking=True,
)
assert len(mock_set_tool_temp.mock_calls) == 1
# Verify that we pass integer, expected by the pyoctoprintapi
mock_set_tool_temp.assert_called_with("tool0", 200)
@pytest.mark.parametrize(
"printer",
[
{
"state": {
"flags": {"printing": False},
"text": "Operational",
},
"temperature": {"bed": {"actual": 20.0, "target": 50.0}},
},
],
)
@pytest.mark.freeze_time(datetime(2020, 2, 20, 9, 10, 0))
@pytest.mark.usefixtures("init_integration")
async def test_set_bed_temp(
hass: HomeAssistant,
) -> None:
"""Test setting bed temperature via number entity."""
with patch(
"pyoctoprintapi.OctoprintClient.set_bed_temperature"
) as mock_set_bed_temp:
entity_component = hass.data[NUMBER_DOMAIN]
entity = entity_component.get_entity("number.octoprint_bed_temperature")
assert entity is not None
await hass.services.async_call(
NUMBER_DOMAIN,
SERVICE_SET_VALUE,
{ATTR_ENTITY_ID: entity.entity_id, ATTR_VALUE: 80.6},
blocking=True,
)
assert len(mock_set_bed_temp.mock_calls) == 1
# Verify that we pass integer, expected by the pyoctoprintapi, and that it's rounded down
mock_set_bed_temp.assert_called_with(80)
@pytest.mark.parametrize(
"printer",
[
{
"state": {
"flags": {"printing": False},
"text": "Operational",
},
"temperature": {
"tool0": {"actual": 20.0, "target": 30.0},
"tool1": {"actual": 21.0, "target": 31.0},
},
},
],
)
@pytest.mark.freeze_time(datetime(2020, 2, 20, 9, 10, 0))
@pytest.mark.usefixtures("init_integration")
async def test_set_tool_n_temp(
hass: HomeAssistant,
) -> None:
"""Test setting tool temperature via number entity when multiple tools are present."""
with patch(
"pyoctoprintapi.OctoprintClient.set_tool_temperature"
) as mock_set_tool_temp:
entity_component = hass.data[NUMBER_DOMAIN]
entity = entity_component.get_entity("number.octoprint_extruder_1_temperature")
assert entity is not None
await hass.services.async_call(
NUMBER_DOMAIN,
SERVICE_SET_VALUE,
{ATTR_ENTITY_ID: entity.entity_id, ATTR_VALUE: 41.0},
blocking=True,
)
assert len(mock_set_tool_temp.mock_calls) == 1
# Verify that we pass integer, expected by the pyoctoprintapi
mock_set_tool_temp.assert_called_with("tool1", 41)
@pytest.mark.parametrize("printer", [None])
@pytest.mark.freeze_time(datetime(2020, 2, 20, 9, 10, 0))
@pytest.mark.usefixtures("init_integration")
async def test_numbers_printer_disconnected(
hass: HomeAssistant,
) -> None:
"""Test number entities when printer is disconnected."""
# When printer is disconnected, no number entities should be created
state = hass.states.get("number.octoprint_tool0_temperature")
assert state is None
state = hass.states.get("number.octoprint_bed_temperature")
assert state is None
def __standard_job():
return {
"job": {
"averagePrintTime": 6500,
"estimatedPrintTime": 6000,
"filament": {"tool0": {"length": 3000, "volume": 7}},
"file": {
"date": 1577836800,
"display": "Test File Name",
"name": "Test_File_Name.gcode",
"origin": "local",
"path": "Folder1/Folder2/Test_File_Name.gcode",
"size": 123456789,
},
"lastPrintTime": 12345.678,
"user": "testUser",
},
"progress": {"completion": 50, "printTime": 600, "printTimeLeft": 6000},
"state": "Printing",
}