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:
Allen Porter 2023-11-11 23:36:30 -08:00 committed by GitHub
parent 48a8ae4df5
commit 25650563fe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 515 additions and 161 deletions

View file

@ -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(