Skip to content

Commit 13155b3

Browse files
committed
ipp: Make IPP protocol version configurable
Adds a checkbox to configure a printer with legacy IPP v1.1 instead of the default v2.0. Fixes: #93211
1 parent 1254667 commit 13155b3

File tree

10 files changed

+74
-9
lines changed

10 files changed

+74
-9
lines changed

homeassistant/components/ipp/__init__.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
)
1313
from homeassistant.core import HomeAssistant
1414

15-
from .const import CONF_BASE_PATH
15+
from .const import CONF_BASE_PATH, CONF_PROTO_LEGACY
1616
from .coordinator import IPPDataUpdateCoordinator
1717

1818
PLATFORMS = [Platform.SENSOR]
@@ -31,6 +31,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: IPPConfigEntry) -> bool:
3131
host=entry.data[CONF_HOST],
3232
port=entry.data[CONF_PORT],
3333
base_path=entry.data[CONF_BASE_PATH],
34+
proto_legacy=entry.data[CONF_PROTO_LEGACY],
3435
tls=entry.data[CONF_SSL],
3536
verify_ssl=entry.data[CONF_VERIFY_SSL],
3637
device_id=device_id,

homeassistant/components/ipp/config_flow.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@
2929
from homeassistant.core import HomeAssistant
3030
from homeassistant.helpers.aiohttp_client import async_get_clientsession
3131

32-
from .const import CONF_BASE_PATH, CONF_SERIAL, DOMAIN
32+
from .const import CONF_BASE_PATH, CONF_PROTO_LEGACY, CONF_SERIAL, DOMAIN, \
33+
IPP_PROTO_VERSION_DEFAULT, IPP_PROTO_VERSION_LEGACY
3334

3435
_LOGGER = logging.getLogger(__name__)
3536

@@ -47,6 +48,7 @@ async def validate_input(hass: HomeAssistant, data: dict) -> dict[str, Any]:
4748
tls=data[CONF_SSL],
4849
verify_ssl=data[CONF_VERIFY_SSL],
4950
session=session,
51+
ipp_version=IPP_PROTO_VERSION_LEGACY if data[CONF_PROTO_LEGACY] else IPP_PROTO_VERSION_DEFAULT,
5052
)
5153

5254
printer = await ipp.printer()
@@ -57,8 +59,6 @@ async def validate_input(hass: HomeAssistant, data: dict) -> dict[str, Any]:
5759
class IPPFlowHandler(ConfigFlow, domain=DOMAIN):
5860
"""Handle an IPP config flow."""
5961

60-
VERSION = 1
61-
6262
def __init__(self) -> None:
6363
"""Set up the instance."""
6464
self.discovery_info: dict[str, Any] = {}
@@ -127,6 +127,7 @@ async def async_step_zeroconf(
127127
CONF_BASE_PATH: f"/{base_path}",
128128
CONF_NAME: name,
129129
CONF_UUID: unique_id,
130+
CONF_PROTO_LEGACY: False,
130131
}
131132
)
132133

@@ -215,6 +216,7 @@ def _show_setup_form(self, errors: dict | None = None) -> ConfigFlowResult:
215216
vol.Required(CONF_BASE_PATH, default="/ipp/print"): str,
216217
vol.Required(CONF_SSL, default=False): bool,
217218
vol.Required(CONF_VERIFY_SSL, default=False): bool,
219+
vol.Required(CONF_PROTO_LEGACY, default=False): bool,
218220
}
219221
),
220222
errors=errors or {},

homeassistant/components/ipp/const.py

+4
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,9 @@
1616

1717
# Config Keys
1818
CONF_BASE_PATH = "base_path"
19+
CONF_PROTO_LEGACY = "proto_legacy"
1920
CONF_SERIAL = "serial"
2021
CONF_TLS = "tls"
22+
23+
IPP_PROTO_VERSION_LEGACY = (1, 1)
24+
IPP_PROTO_VERSION_DEFAULT = (2, 0)

homeassistant/components/ipp/coordinator.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from homeassistant.helpers.aiohttp_client import async_get_clientsession
1212
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
1313

14-
from .const import DOMAIN
14+
from .const import DOMAIN, IPP_PROTO_VERSION_DEFAULT, IPP_PROTO_VERSION_LEGACY
1515

1616
SCAN_INTERVAL = timedelta(seconds=60)
1717

@@ -30,6 +30,7 @@ def __init__(
3030
base_path: str,
3131
tls: bool,
3232
verify_ssl: bool,
33+
proto_legacy: bool,
3334
device_id: str,
3435
) -> None:
3536
"""Initialize global IPP data updater."""
@@ -41,6 +42,7 @@ def __init__(
4142
tls=tls,
4243
verify_ssl=verify_ssl,
4344
session=async_get_clientsession(hass, verify_ssl),
45+
ipp_version=IPP_PROTO_VERSION_LEGACY if data[CONF_PROTO_LEGACY] else IPP_PROTO_VERSION_DEFAULT,
4446
)
4547

4648
super().__init__(

homeassistant/components/ipp/strings.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
"port": "[%key:common::config_flow::data::port%]",
1111
"base_path": "Relative path to the printer",
1212
"ssl": "[%key:common::config_flow::data::ssl%]",
13-
"verify_ssl": "[%key:common::config_flow::data::verify_ssl%]"
13+
"verify_ssl": "[%key:common::config_flow::data::verify_ssl%]",
14+
"proto_legacy": "Use IPP v1.1 for compatibility with older printers"
1415
}
1516
},
1617
"zeroconf_confirm": {

tests/components/ipp/__init__.py

+11-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from ipaddress import ip_address
44

55
from homeassistant.components import zeroconf
6-
from homeassistant.components.ipp.const import CONF_BASE_PATH
6+
from homeassistant.components.ipp.const import CONF_BASE_PATH, CONF_PROTO_LEGACY
77
from homeassistant.const import CONF_HOST, CONF_PORT, CONF_SSL, CONF_VERIFY_SSL
88

99
ATTR_HOSTNAME = "hostname"
@@ -28,6 +28,16 @@
2828
CONF_SSL: False,
2929
CONF_VERIFY_SSL: False,
3030
CONF_BASE_PATH: BASE_PATH,
31+
CONF_PROTO_LEGACY: False,
32+
}
33+
34+
MOCK_USER_INPUT_PROTO_LEGACY = {
35+
CONF_HOST: "192.168.1.32",
36+
CONF_PORT: PORT,
37+
CONF_SSL: False,
38+
CONF_VERIFY_SSL: False,
39+
CONF_BASE_PATH: "/ipp",
40+
CONF_PROTO_LEGACY: True,
3141
}
3242

3343
MOCK_ZEROCONF_IPP_SERVICE_INFO = zeroconf.ZeroconfServiceInfo(

tests/components/ipp/conftest.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from pyipp import Printer
88
import pytest
99

10-
from homeassistant.components.ipp.const import CONF_BASE_PATH, DOMAIN
10+
from homeassistant.components.ipp.const import CONF_BASE_PATH, CONF_PROTO_LEGACY, DOMAIN
1111
from homeassistant.const import (
1212
CONF_HOST,
1313
CONF_PORT,
@@ -33,6 +33,7 @@ def mock_config_entry() -> MockConfigEntry:
3333
CONF_VERIFY_SSL: True,
3434
CONF_BASE_PATH: "/ipp/print",
3535
CONF_UUID: "cfe92100-67c4-11d4-a45f-f8d027761251",
36+
CONF_PROTO_LEGACY: False,
3637
},
3738
unique_id="cfe92100-67c4-11d4-a45f-f8d027761251",
3839
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"printer-state": "idle",
3+
"printer-name": "Test Legacy Printer",
4+
"printer-location": null,
5+
"printer-make-and-model": "Test C822 Series",
6+
"printer-uri-supported": [
7+
"http://192.168.1.32/ipp",
8+
"http://192.168.1.32:631/ipp",
9+
"http://192.168.1.32/ipp/lp",
10+
"http://192.168.1.32:631/ipp/lp",
11+
"ipp://192.168.1.32/ipp",
12+
"ipp://192.168.1.32:631/ipp",
13+
"ipp://192.168.1.32/ipp/lp",
14+
"ipp://192.168.1.32:631/ipp/lp"
15+
],
16+
"printer-info": "PCL,XPS,IBMPPR,EPSONFX",
17+
"printer-more-info": null
18+
}

tests/components/ipp/snapshots/test_diagnostics.ambr

+1
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
'base_path': '/ipp/print',
9292
'host': '192.168.1.31',
9393
'port': 631,
94+
'proto_legacy': False,
9495
'ssl': False,
9596
'uuid': 'cfe92100-67c4-11d4-a45f-f8d027761251',
9697
'verify_ssl': True,

tests/components/ipp/test_config_flow.py

+26-1
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,15 @@
1515
)
1616
import pytest
1717

18-
from homeassistant.components.ipp.const import CONF_BASE_PATH, DOMAIN
18+
from homeassistant.components.ipp.const import CONF_BASE_PATH, CONF_PROTO_LEGACY, DOMAIN
1919
from homeassistant.config_entries import SOURCE_USER, SOURCE_ZEROCONF
2020
from homeassistant.const import CONF_HOST, CONF_NAME, CONF_SSL, CONF_UUID
2121
from homeassistant.core import HomeAssistant
2222
from homeassistant.data_entry_flow import FlowResultType
2323

2424
from . import (
2525
MOCK_USER_INPUT,
26+
MOCK_USER_INPUT_PROTO_LEGACY,
2627
MOCK_ZEROCONF_IPP_SERVICE_INFO,
2728
MOCK_ZEROCONF_IPPS_SERVICE_INFO,
2829
)
@@ -131,6 +132,30 @@ async def test_user_connection_upgrade_required(
131132
assert result["type"] is FlowResultType.FORM
132133
assert result["errors"] == {"base": "connection_upgrade"}
133134

135+
async def test_user_legacy_printer(hass: HomeAssistant) -> None:
136+
"""Test that a legacy printer can be added."""
137+
fixture = await hass.async_add_executor_job(
138+
load_fixture, "ipp/printer_proto_legacy.json"
139+
)
140+
mock_legacy_printer = Printer.from_dict(json.loads(fixture))
141+
user_input = MOCK_USER_INPUT_PROTO_LEGACY.copy()
142+
with patch(
143+
"homeassistant.components.ipp.config_flow.IPP", autospec=True
144+
) as ipp_mock:
145+
client = ipp_mock.return_value
146+
client.printer.return_value = mock_legacy_printer
147+
result = await hass.config_entries.flow.async_init(
148+
DOMAIN,
149+
context={"source": SOURCE_USER},
150+
data=user_input,
151+
)
152+
153+
assert result["type"] is FlowResultType.CREATE_ENTRY
154+
assert result["title"] == "192.168.1.32"
155+
156+
assert result["data"]
157+
assert result["data"][CONF_HOST] == "192.168.1.32"
158+
assert result["data"][CONF_PROTO_LEGACY] is True
134159

135160
async def test_zeroconf_connection_upgrade_required(
136161
hass: HomeAssistant,

0 commit comments

Comments
 (0)