Fix Rainbird unique to use a more reliable source (mac address) (#101603)
* Fix rainbird unique id to use a mac address for new entries * Fix typo * Normalize mac address before using as unique id * Apply suggestions from code review Co-authored-by: Martin Hjelmare <marhje52@gmail.com> * Update test check and remove dead code * Update all config entries to the new format * Update config entry tests for migration * Fix rainbird entity unique ids * Add test coverage for repair failure * Apply suggestions from code review Co-authored-by: Martin Hjelmare <marhje52@gmail.com> * Apply suggestions from code review Co-authored-by: Martin Hjelmare <marhje52@gmail.com> * Remove unnecessary migration failure checks * Remove invalid config entries * Update entry when entering a different hostname for an existing host. --------- Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
parent
48a8ae4df5
commit
25650563fe
10 changed files with 515 additions and 161 deletions
|
@ -3,6 +3,7 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from http import HTTPStatus
|
||||
import json
|
||||
from typing import Any
|
||||
from unittest.mock import patch
|
||||
|
||||
|
@ -24,6 +25,8 @@ HOST = "example.com"
|
|||
URL = "http://example.com/stick"
|
||||
PASSWORD = "password"
|
||||
SERIAL_NUMBER = 0x12635436566
|
||||
MAC_ADDRESS = "4C:A1:61:00:11:22"
|
||||
MAC_ADDRESS_UNIQUE_ID = "4c:a1:61:00:11:22"
|
||||
|
||||
#
|
||||
# Response payloads below come from pyrainbird test cases.
|
||||
|
@ -50,6 +53,20 @@ RAIN_DELAY = "B60010" # 0x10 is 16
|
|||
RAIN_DELAY_OFF = "B60000"
|
||||
# ACK command 0x10, Echo 0x06
|
||||
ACK_ECHO = "0106"
|
||||
WIFI_PARAMS_RESPONSE = {
|
||||
"macAddress": MAC_ADDRESS,
|
||||
"localIpAddress": "1.1.1.38",
|
||||
"localNetmask": "255.255.255.0",
|
||||
"localGateway": "1.1.1.1",
|
||||
"rssi": -61,
|
||||
"wifiSsid": "wifi-ssid-name",
|
||||
"wifiPassword": "wifi-password-name",
|
||||
"wifiSecurity": "wpa2-aes",
|
||||
"apTimeoutNoLan": 20,
|
||||
"apTimeoutIdle": 20,
|
||||
"apSecurity": "unknown",
|
||||
"stickVersion": "Rain Bird Stick Rev C/1.63",
|
||||
}
|
||||
|
||||
|
||||
CONFIG = {
|
||||
|
@ -62,10 +79,16 @@ CONFIG = {
|
|||
}
|
||||
}
|
||||
|
||||
CONFIG_ENTRY_DATA_OLD_FORMAT = {
|
||||
"host": HOST,
|
||||
"password": PASSWORD,
|
||||
"serial_number": SERIAL_NUMBER,
|
||||
}
|
||||
CONFIG_ENTRY_DATA = {
|
||||
"host": HOST,
|
||||
"password": PASSWORD,
|
||||
"serial_number": SERIAL_NUMBER,
|
||||
"mac": MAC_ADDRESS,
|
||||
}
|
||||
|
||||
|
||||
|
@ -77,14 +100,23 @@ def platforms() -> list[Platform]:
|
|||
|
||||
@pytest.fixture
|
||||
async def config_entry_unique_id() -> str:
|
||||
"""Fixture for serial number used in the config entry."""
|
||||
"""Fixture for config entry unique id."""
|
||||
return MAC_ADDRESS_UNIQUE_ID
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
async def serial_number() -> int:
|
||||
"""Fixture for serial number used in the config entry data."""
|
||||
return SERIAL_NUMBER
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
async def config_entry_data() -> dict[str, Any]:
|
||||
async def config_entry_data(serial_number: int) -> dict[str, Any]:
|
||||
"""Fixture for MockConfigEntry data."""
|
||||
return CONFIG_ENTRY_DATA
|
||||
return {
|
||||
**CONFIG_ENTRY_DATA,
|
||||
"serial_number": serial_number,
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
@ -123,17 +155,24 @@ def setup_platforms(
|
|||
yield
|
||||
|
||||
|
||||
def rainbird_response(data: str) -> bytes:
|
||||
def rainbird_json_response(result: dict[str, str]) -> bytes:
|
||||
"""Create a fake API response."""
|
||||
return encryption.encrypt(
|
||||
'{"jsonrpc": "2.0", "result": {"data":"%s"}, "id": 1} ' % data,
|
||||
'{"jsonrpc": "2.0", "result": %s, "id": 1} ' % json.dumps(result),
|
||||
PASSWORD,
|
||||
)
|
||||
|
||||
|
||||
def mock_json_response(result: dict[str, str]) -> AiohttpClientMockResponse:
|
||||
"""Create a fake AiohttpClientMockResponse."""
|
||||
return AiohttpClientMockResponse(
|
||||
"POST", URL, response=rainbird_json_response(result)
|
||||
)
|
||||
|
||||
|
||||
def mock_response(data: str) -> AiohttpClientMockResponse:
|
||||
"""Create a fake AiohttpClientMockResponse."""
|
||||
return AiohttpClientMockResponse("POST", URL, response=rainbird_response(data))
|
||||
return mock_json_response({"data": data})
|
||||
|
||||
|
||||
def mock_response_error(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue