33from datetime import timedelta
44from unittest .mock import AsyncMock , Mock , call , patch
55
6- from aioshelly .const import MODEL_BULB , MODEL_BUTTON1
6+ from aioshelly .const import MODEL_2PM_G3 , MODEL_BULB , MODEL_BUTTON1
77from aioshelly .exceptions import DeviceConnectionError , InvalidAuthError
88from freezegun .api import FrozenDateTimeFactory
99import pytest
2929from homeassistant .const import ATTR_DEVICE_ID , STATE_ON , STATE_UNAVAILABLE
3030from homeassistant .core import Event , HomeAssistant , State
3131from homeassistant .helpers import device_registry as dr , issue_registry as ir
32+ from homeassistant .helpers .device_registry import CONNECTION_NETWORK_MAC , DeviceRegistry
33+ from homeassistant .helpers .entity_registry import EntityRegistry
3234
3335from . import (
3436 MOCK_MAC ,
4042 register_entity ,
4143)
4244
43- from tests .common import async_fire_time_changed , mock_restore_cache
45+ from tests .common import (
46+ async_fire_time_changed ,
47+ async_load_json_object_fixture ,
48+ mock_restore_cache ,
49+ )
4450
4551RELAY_BLOCK_ID = 0
4652LIGHT_BLOCK_ID = 2
@@ -927,6 +933,7 @@ async def test_rpc_runs_connected_events_when_initialized(
927933 hass : HomeAssistant ,
928934 mock_rpc_device : Mock ,
929935 monkeypatch : pytest .MonkeyPatch ,
936+ caplog : pytest .LogCaptureFixture ,
930937 supports_scripts : bool ,
931938 zigbee_firmware : bool ,
932939 result : bool ,
@@ -950,6 +957,13 @@ async def test_rpc_runs_connected_events_when_initialized(
950957 # BLE script list is called during connected events if device supports scripts
951958 # and Zigbee is disabled
952959 assert bool (call .script_list () in mock_rpc_device .mock_calls ) == result
960+ assert "Device Test name already connected" not in caplog .text
961+
962+ # Mock initialized event after already initialized
963+ caplog .clear ()
964+ mock_rpc_device .mock_initialized ()
965+ await hass .async_block_till_done ()
966+ assert "Device Test name already connected" in caplog .text
953967
954968
955969async def test_rpc_sleeping_device_unload_ignore_ble_scanner (
@@ -1139,3 +1153,70 @@ async def test_xmod_model_lookup(
11391153 )
11401154 assert device
11411155 assert device .model == xmod_model
1156+
1157+
1158+ async def test_sub_device_area_from_main_device (
1159+ hass : HomeAssistant ,
1160+ mock_rpc_device : Mock ,
1161+ entity_registry : EntityRegistry ,
1162+ device_registry : DeviceRegistry ,
1163+ monkeypatch : pytest .MonkeyPatch ,
1164+ ) -> None :
1165+ """Test Shelly sub-device area is set to main device area when created."""
1166+ device_fixture = await async_load_json_object_fixture (hass , "2pm_gen3.json" , DOMAIN )
1167+ monkeypatch .setattr (mock_rpc_device , "shelly" , device_fixture ["shelly" ])
1168+ monkeypatch .setattr (mock_rpc_device , "status" , device_fixture ["status" ])
1169+ monkeypatch .setattr (mock_rpc_device , "config" , device_fixture ["config" ])
1170+
1171+ config_entry = await init_integration (
1172+ hass , gen = 3 , model = MODEL_2PM_G3 , skip_setup = True
1173+ )
1174+
1175+ # create main device and set area
1176+ device_entry = device_registry .async_get_or_create (
1177+ config_entry_id = config_entry .entry_id ,
1178+ name = "Test name" ,
1179+ connections = {(CONNECTION_NETWORK_MAC , MOCK_MAC )},
1180+ identifiers = {(DOMAIN , MOCK_MAC )},
1181+ suggested_area = "living_room" ,
1182+ )
1183+
1184+ await hass .config_entries .async_setup (config_entry .entry_id )
1185+ await hass .async_block_till_done ()
1186+
1187+ # verify sub-devices have the same area as main device
1188+ for relay_index in range (2 ):
1189+ entity_id = f"switch.test_name_switch_{ relay_index } "
1190+ assert hass .states .get (entity_id ) is not None
1191+ entry = entity_registry .async_get (entity_id )
1192+ assert entry
1193+
1194+ device_entry = device_registry .async_get (entry .device_id )
1195+ assert device_entry
1196+ assert device_entry .area_id == "living_room"
1197+
1198+
1199+ @pytest .mark .parametrize ("restart_required" , [True , False ])
1200+ async def test_rpc_ble_scanner_enable_reboot (
1201+ hass : HomeAssistant ,
1202+ mock_rpc_device ,
1203+ monkeypatch : pytest .MonkeyPatch ,
1204+ caplog : pytest .LogCaptureFixture ,
1205+ restart_required : bool ,
1206+ ) -> None :
1207+ """Test RPC BLE scanner enabling requires reboot."""
1208+ monkeypatch .setattr (
1209+ mock_rpc_device ,
1210+ "ble_getconfig" ,
1211+ AsyncMock (return_value = {"enable" : False }),
1212+ )
1213+ monkeypatch .setattr (
1214+ mock_rpc_device ,
1215+ "ble_setconfig" ,
1216+ AsyncMock (return_value = {"restart_required" : restart_required }),
1217+ )
1218+ await init_integration (
1219+ hass , 2 , options = {CONF_BLE_SCANNER_MODE : BLEScannerMode .ACTIVE }
1220+ )
1221+ assert bool ("BLE enable required a reboot" in caplog .text ) == restart_required
1222+ assert mock_rpc_device .trigger_reboot .call_count == int (restart_required )
0 commit comments