mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 16:57:53 +00:00
Fix Fully Kiosk Browser merging entities when MAC empty (#87743)
* Fix FKB merging entities when MAC empty Fully Kiosk Browser will sometimes return an empty MAC address in the device_info API call. When two Fully Kiosk devices are added with missing MAC addresses, HA will assume the two devices are the same and merge the entities. This fixes that problem. Fixes #77722 * Update homeassistant/components/fully_kiosk/entity.py Co-authored-by: Erik Montnemery <erik@montnemery.com> --------- Co-authored-by: Erik Montnemery <erik@montnemery.com>
This commit is contained in:
parent
3057dd241a
commit
b5dfd83c46
@ -17,12 +17,16 @@ class FullyKioskEntity(CoordinatorEntity[FullyKioskDataUpdateCoordinator], Entit
|
||||
def __init__(self, coordinator: FullyKioskDataUpdateCoordinator) -> None:
|
||||
"""Initialize the Fully Kiosk Browser entity."""
|
||||
super().__init__(coordinator=coordinator)
|
||||
self._attr_device_info = DeviceInfo(
|
||||
device_info = DeviceInfo(
|
||||
identifiers={(DOMAIN, coordinator.data["deviceID"])},
|
||||
name=coordinator.data["deviceName"],
|
||||
manufacturer=coordinator.data["deviceManufacturer"],
|
||||
model=coordinator.data["deviceModel"],
|
||||
sw_version=coordinator.data["appVersionName"],
|
||||
configuration_url=f"http://{coordinator.data['ip4']}:2323",
|
||||
connections={(CONNECTION_NETWORK_MAC, coordinator.data["Mac"])},
|
||||
)
|
||||
if "Mac" in coordinator.data and coordinator.data["Mac"]:
|
||||
device_info["connections"] = {
|
||||
(CONNECTION_NETWORK_MAC, coordinator.data["Mac"])
|
||||
}
|
||||
self._attr_device_info = device_info
|
||||
|
@ -0,0 +1,79 @@
|
||||
{
|
||||
"deviceName": "Test Kiosk 1",
|
||||
"batteryLevel": 100,
|
||||
"isPlugged": true,
|
||||
"SSID": "\"freewifi\"",
|
||||
"Mac": "",
|
||||
"ip4": "192.168.1.1",
|
||||
"ip6": "FE80::1874:2EFF:FEA2:1111",
|
||||
"hostname4": "192.168.1.1",
|
||||
"hostname6": "fe80::1874:2eff:fea2:1111%p2p0",
|
||||
"wifiSignalLevel": 7,
|
||||
"isMobileDataEnabled": true,
|
||||
"screenOrientation": 90,
|
||||
"screenBrightness": 9,
|
||||
"screenLocked": false,
|
||||
"screenOn": true,
|
||||
"batteryTemperature": 27,
|
||||
"plugged": true,
|
||||
"keyguardLocked": false,
|
||||
"locale": "en_US",
|
||||
"serial": "ABCDEF1234567890",
|
||||
"build": "cm_douglas-userdebug 5.1.1 LMY49M 731a881f9d test-keys",
|
||||
"androidVersion": "5.1.1",
|
||||
"webviewUA": "Mozilla/5.0 (Linux; Android 5.1.1; KFDOWI Build/LMY49M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/81.0.4044.117 Safari/537.36",
|
||||
"motionDetectorStatus": 0,
|
||||
"isDeviceAdmin": true,
|
||||
"isDeviceOwner": false,
|
||||
"internalStorageFreeSpace": 11675512832,
|
||||
"internalStorageTotalSpace": 12938534912,
|
||||
"ramUsedMemory": 1077755904,
|
||||
"ramFreeMemory": 362373120,
|
||||
"ramTotalMemory": 1440129024,
|
||||
"appUsedMemory": 24720592,
|
||||
"appFreeMemory": 59165440,
|
||||
"appTotalMemory": 83886080,
|
||||
"displayHeightPixels": 800,
|
||||
"displayWidthPixels": 1280,
|
||||
"isMenuOpen": false,
|
||||
"topFragmentTag": "",
|
||||
"isInDaydream": false,
|
||||
"isRooted": true,
|
||||
"isLicensed": true,
|
||||
"isInScreensaver": false,
|
||||
"kioskLocked": true,
|
||||
"isInForcedSleep": false,
|
||||
"maintenanceMode": false,
|
||||
"kioskMode": true,
|
||||
"startUrl": "https://homeassistant.local",
|
||||
"currentTabIndex": 0,
|
||||
"mqttConnected": true,
|
||||
"deviceID": "abcdef-111111",
|
||||
"appVersionCode": 875,
|
||||
"appVersionName": "1.42.5",
|
||||
"androidSdk": 22,
|
||||
"deviceModel": "KFDOWI",
|
||||
"deviceManufacturer": "amzn",
|
||||
"foregroundApp": "de.ozerov.fully",
|
||||
"currentPage": "https://homeassistant.local",
|
||||
"lastAppStart": "8/13/2022 1:00:47 AM",
|
||||
"sensorInfo": [
|
||||
{
|
||||
"type": 8,
|
||||
"name": "PROXIMITY",
|
||||
"vendor": "MTK",
|
||||
"version": 1,
|
||||
"accuracy": -1
|
||||
},
|
||||
{
|
||||
"type": 5,
|
||||
"name": "LIGHT",
|
||||
"vendor": "MTK",
|
||||
"version": 1,
|
||||
"accuracy": 3,
|
||||
"values": [0, 0, 0],
|
||||
"lastValuesTime": 1660435566561,
|
||||
"lastAccuracyTime": 1660366847543
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
{
|
||||
"deviceName": "Test Kiosk 2",
|
||||
"batteryLevel": 100,
|
||||
"isPlugged": true,
|
||||
"SSID": "\"freewifi\"",
|
||||
"Mac": "",
|
||||
"ip4": "192.168.1.2",
|
||||
"ip6": "FE80::1874:2EFF:FEA2:2222",
|
||||
"hostname4": "192.168.1.2",
|
||||
"hostname6": "fe80::1874:2eff:fea2:2222%p2p0",
|
||||
"wifiSignalLevel": 7,
|
||||
"isMobileDataEnabled": true,
|
||||
"screenOrientation": 90,
|
||||
"screenBrightness": 9,
|
||||
"screenLocked": false,
|
||||
"screenOn": true,
|
||||
"batteryTemperature": 27,
|
||||
"plugged": true,
|
||||
"keyguardLocked": false,
|
||||
"locale": "en_US",
|
||||
"serial": "ABCDEF1234567890",
|
||||
"build": "cm_douglas-userdebug 5.1.1 LMY49M 731a881f9d test-keys",
|
||||
"androidVersion": "5.1.1",
|
||||
"webviewUA": "Mozilla/5.0 (Linux; Android 5.1.1; KFDOWI Build/LMY49M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/81.0.4044.117 Safari/537.36",
|
||||
"motionDetectorStatus": 0,
|
||||
"isDeviceAdmin": true,
|
||||
"isDeviceOwner": false,
|
||||
"internalStorageFreeSpace": 11675512832,
|
||||
"internalStorageTotalSpace": 12938534912,
|
||||
"ramUsedMemory": 1077755904,
|
||||
"ramFreeMemory": 362373120,
|
||||
"ramTotalMemory": 1440129024,
|
||||
"appUsedMemory": 24720592,
|
||||
"appFreeMemory": 59165440,
|
||||
"appTotalMemory": 83886080,
|
||||
"displayHeightPixels": 800,
|
||||
"displayWidthPixels": 1280,
|
||||
"isMenuOpen": false,
|
||||
"topFragmentTag": "",
|
||||
"isInDaydream": false,
|
||||
"isRooted": true,
|
||||
"isLicensed": true,
|
||||
"isInScreensaver": false,
|
||||
"kioskLocked": true,
|
||||
"isInForcedSleep": false,
|
||||
"maintenanceMode": false,
|
||||
"kioskMode": true,
|
||||
"startUrl": "https://homeassistant.local",
|
||||
"currentTabIndex": 0,
|
||||
"mqttConnected": true,
|
||||
"deviceID": "abcdef-222222",
|
||||
"appVersionCode": 875,
|
||||
"appVersionName": "1.42.5",
|
||||
"androidSdk": 22,
|
||||
"deviceModel": "KFDOWI",
|
||||
"deviceManufacturer": "amzn",
|
||||
"foregroundApp": "de.ozerov.fully",
|
||||
"currentPage": "https://homeassistant.local",
|
||||
"lastAppStart": "8/13/2022 1:00:47 AM",
|
||||
"sensorInfo": [
|
||||
{
|
||||
"type": 8,
|
||||
"name": "PROXIMITY",
|
||||
"vendor": "MTK",
|
||||
"version": 1,
|
||||
"accuracy": -1
|
||||
},
|
||||
{
|
||||
"type": 5,
|
||||
"name": "LIGHT",
|
||||
"vendor": "MTK",
|
||||
"version": 1,
|
||||
"accuracy": 3,
|
||||
"values": [0, 0, 0],
|
||||
"lastValuesTime": 1660435566561,
|
||||
"lastAccuracyTime": 1660366847543
|
||||
}
|
||||
]
|
||||
}
|
@ -1,15 +1,18 @@
|
||||
"""Tests for the Fully Kiosk Browser integration."""
|
||||
import asyncio
|
||||
from unittest.mock import MagicMock
|
||||
import json
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from fullykiosk import FullyKioskError
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.fully_kiosk.const import DOMAIN
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
from homeassistant.const import CONF_HOST, CONF_MAC, CONF_PASSWORD
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
from tests.common import MockConfigEntry, load_fixture
|
||||
|
||||
|
||||
async def test_load_unload_config_entry(
|
||||
@ -51,3 +54,83 @@ async def test_config_entry_not_ready(
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY
|
||||
|
||||
|
||||
async def _load_config(
|
||||
hass: HomeAssistant,
|
||||
config_entry: MockConfigEntry,
|
||||
device_info_fixture: str,
|
||||
) -> None:
|
||||
with patch(
|
||||
"homeassistant.components.fully_kiosk.coordinator.FullyKiosk",
|
||||
autospec=True,
|
||||
) as client_mock:
|
||||
client = client_mock.return_value
|
||||
client.getDeviceInfo.return_value = json.loads(
|
||||
load_fixture(device_info_fixture, DOMAIN)
|
||||
)
|
||||
client.getSettings.return_value = json.loads(
|
||||
load_fixture("listsettings.json", DOMAIN)
|
||||
)
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
||||
async def test_multiple_kiosk_with_empty_mac(
|
||||
hass: HomeAssistant,
|
||||
) -> None:
|
||||
"""Test that multiple kiosk devices with empty MAC don't get merged."""
|
||||
entity_registry = er.async_get(hass)
|
||||
device_registry = dr.async_get(hass)
|
||||
|
||||
config_entry1 = MockConfigEntry(
|
||||
title="Test device 1",
|
||||
domain=DOMAIN,
|
||||
data={
|
||||
CONF_HOST: "127.0.0.1",
|
||||
CONF_PASSWORD: "mocked-password",
|
||||
CONF_MAC: "",
|
||||
},
|
||||
unique_id="111111",
|
||||
)
|
||||
await _load_config(hass, config_entry1, "deviceinfo_empty_mac1.json")
|
||||
assert len(device_registry.devices) == 1
|
||||
|
||||
config_entry2 = MockConfigEntry(
|
||||
title="Test device 2",
|
||||
domain=DOMAIN,
|
||||
data={
|
||||
CONF_HOST: "127.0.0.2",
|
||||
CONF_PASSWORD: "mocked-password",
|
||||
CONF_MAC: "",
|
||||
},
|
||||
unique_id="22222",
|
||||
)
|
||||
await _load_config(hass, config_entry2, "deviceinfo_empty_mac2.json")
|
||||
assert len(device_registry.devices) == 2
|
||||
|
||||
state1 = hass.states.get("sensor.test_kiosk_1_battery")
|
||||
assert state1
|
||||
|
||||
state2 = hass.states.get("sensor.test_kiosk_2_battery")
|
||||
assert state2
|
||||
|
||||
entry1 = entity_registry.async_get("sensor.test_kiosk_1_battery")
|
||||
assert entry1
|
||||
assert entry1.unique_id == "abcdef-111111-batteryLevel"
|
||||
|
||||
entry2 = entity_registry.async_get("sensor.test_kiosk_2_battery")
|
||||
assert entry2
|
||||
assert entry2.unique_id == "abcdef-222222-batteryLevel"
|
||||
|
||||
assert entry1.device_id != entry2.device_id
|
||||
|
||||
device1 = device_registry.async_get(entry1.device_id)
|
||||
assert device1
|
||||
|
||||
device2 = device_registry.async_get(entry2.device_id)
|
||||
assert device2
|
||||
|
||||
assert device1 != device2
|
||||
|
Loading…
x
Reference in New Issue
Block a user