ucapi-framework 1.9.5__tar.gz → 1.9.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/PKG-INFO +1 -1
  2. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/pyproject.toml +1 -1
  3. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/tests/test_driver.py +28 -0
  4. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/ucapi_framework/driver.py +19 -0
  5. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/ucapi_framework.egg-info/PKG-INFO +1 -1
  6. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/README.md +0 -0
  7. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/setup.cfg +0 -0
  8. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/tests/test_button_entity.py +0 -0
  9. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/tests/test_climate_entity.py +0 -0
  10. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/tests/test_config.py +0 -0
  11. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/tests/test_cover_entity.py +0 -0
  12. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/tests/test_device.py +0 -0
  13. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/tests/test_discovery.py +0 -0
  14. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/tests/test_entity.py +0 -0
  15. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/tests/test_factory_pattern.py +0 -0
  16. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/tests/test_helpers.py +0 -0
  17. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/tests/test_ir_emitter_entity.py +0 -0
  18. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/tests/test_light_entity.py +0 -0
  19. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/tests/test_media_player_entity.py +0 -0
  20. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/tests/test_migration.py +0 -0
  21. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/tests/test_remote_entity.py +0 -0
  22. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/tests/test_select_entity.py +0 -0
  23. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/tests/test_sensor_entity.py +0 -0
  24. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/tests/test_setup.py +0 -0
  25. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/tests/test_switch_entity.py +0 -0
  26. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/tests/test_voice_assistant_entity.py +0 -0
  27. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/ucapi_framework/__init__.py +0 -0
  28. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/ucapi_framework/config.py +0 -0
  29. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/ucapi_framework/device.py +0 -0
  30. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/ucapi_framework/discovery.py +0 -0
  31. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/ucapi_framework/entities/__init__.py +0 -0
  32. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/ucapi_framework/entities/button.py +0 -0
  33. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/ucapi_framework/entities/climate.py +0 -0
  34. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/ucapi_framework/entities/cover.py +0 -0
  35. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/ucapi_framework/entities/ir_emitter.py +0 -0
  36. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/ucapi_framework/entities/light.py +0 -0
  37. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/ucapi_framework/entities/media_player.py +0 -0
  38. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/ucapi_framework/entities/remote.py +0 -0
  39. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/ucapi_framework/entities/select.py +0 -0
  40. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/ucapi_framework/entities/sensor.py +0 -0
  41. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/ucapi_framework/entities/switch.py +0 -0
  42. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/ucapi_framework/entities/voice_assistant.py +0 -0
  43. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/ucapi_framework/entity.py +0 -0
  44. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/ucapi_framework/helpers.py +0 -0
  45. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/ucapi_framework/migration.py +0 -0
  46. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/ucapi_framework/setup.py +0 -0
  47. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/ucapi_framework.egg-info/SOURCES.txt +0 -0
  48. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/ucapi_framework.egg-info/dependency_links.txt +0 -0
  49. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/ucapi_framework.egg-info/requires.txt +0 -0
  50. {ucapi_framework-1.9.5 → ucapi_framework-1.9.6}/ucapi_framework.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ucapi-framework
3
- Version: 1.9.5
3
+ Version: 1.9.6
4
4
  Summary: ucapi framework that provides core functionality for building integrations.
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ucapi-framework"
3
- version = "1.9.5"
3
+ version = "1.9.6"
4
4
  description = "ucapi framework that provides core functionality for building integrations."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -1442,6 +1442,34 @@ class TestHubBasedIntegration:
1442
1442
  # Device should be connected
1443
1443
  assert device.is_connected is True
1444
1444
 
1445
+ @pytest.mark.asyncio
1446
+ async def test_on_subscribe_entities_hub_based_existing_connected_unconfigured_entity(
1447
+ self,
1448
+ ):
1449
+ """Test subscribing registers hub entities when the device already connected."""
1450
+ loop = asyncio.get_event_loop()
1451
+ driver = ConcreteDriver(
1452
+ DeviceForTests,
1453
+ [media_player.MediaPlayer],
1454
+ require_connection_before_registry=True,
1455
+ loop=loop,
1456
+ )
1457
+ driver.api = MagicMock()
1458
+ driver.api.configured_entities = MockEntityCollection()
1459
+ driver.api.available_entities = MockEntityCollection()
1460
+ driver.api.set_device_state = AsyncMock()
1461
+
1462
+ config = DeviceConfigForTests("dev1", "Device 1", "192.168.1.1")
1463
+ driver._add_device_instance(config)
1464
+ device = driver._device_instances["dev1"]
1465
+ await device.connect()
1466
+ assert device.is_connected is True
1467
+ assert driver.api.configured_entities.get("media_player.dev1") is None
1468
+
1469
+ await driver.on_subscribe_entities(["media_player.dev1"])
1470
+
1471
+ assert driver.api.available_entities.contains("media_player.dev1")
1472
+
1445
1473
  @pytest.mark.asyncio
1446
1474
  async def test_on_subscribe_entities_hub_based_no_config(self):
1447
1475
  """Test subscribe entities with hub-based when device config not found."""
@@ -395,6 +395,25 @@ class BaseIntegrationDriver(Generic[DeviceT, ConfigT]):
395
395
  await self.async_register_available_entities(
396
396
  self.get_device_config(device_id), device
397
397
  )
398
+ elif (
399
+ device
400
+ and device.is_connected
401
+ and self.api.configured_entities.get(entity_id) is None
402
+ ):
403
+ # PATCHED: the device was already connected (e.g. by the
404
+ # generic CONNECT handler on Remote restart) before this
405
+ # SUBSCRIBE_ENTITIES call arrived, so the transition-only
406
+ # registration above never ran. Register now so the
407
+ # entity doesn't silently stay unconfigured.
408
+ _LOG.info(
409
+ "Device %s already connected but entity %s not configured "
410
+ "- registering now (post-restart fix)",
411
+ device_id,
412
+ entity_id,
413
+ )
414
+ await self.async_register_available_entities(
415
+ self.get_device_config(device_id), device
416
+ )
398
417
 
399
418
  # Path 2: Standard integrations - add devices for entities that aren't configured yet
400
419
  else:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ucapi-framework
3
- Version: 1.9.5
3
+ Version: 1.9.6
4
4
  Summary: ucapi framework that provides core functionality for building integrations.
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown