From f11202fb1a91f7da81fd922b5b95fa7124a9542c Mon Sep 17 00:00:00 2001 From: ashionky <495519020@qq.com> Date: Wed, 12 Mar 2025 14:47:31 +0800 Subject: [PATCH 1/2] poll --- README.md | 29 +++++++++++- custom_components/refoss_rpc/__init__.py | 2 - custom_components/refoss_rpc/const.py | 8 +--- custom_components/refoss_rpc/coordinator.py | 46 +++++++------------ custom_components/refoss_rpc/entity.py | 7 --- custom_components/refoss_rpc/sensor.py | 3 -- custom_components/refoss_rpc/strings.json | 2 +- .../refoss_rpc/translations/en.json | 2 +- 8 files changed, 48 insertions(+), 51 deletions(-) diff --git a/README.md b/README.md index 11a5f63..89fbffa 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,29 @@ # refoss_rpc - Only support R11 +- Home Assistant version: 2025.2.5 or above + +## Installation + +### Custom Repositories in HACS (recommended) +- Make sure the [HACS integration](https://hacs.xyz/) is properly installed for your instance of home assistant. +- Reference [Custom Repositories](https://hacs.xyz/docs/faq/custom_repositories),In the HACS UI go to "Integrations", click on "+" in the lower right corner". +- Paste https://github.com/Refoss/refoss_rpc into the field that says "Add custom repository URL", select "Integration" from "Category" dropdown and click "Add". +- You should now see a card with the Refoss RPC integration in the HACS -> "Integrations" section. Click "Install". +- Select the latest version from the dropdown and click "Install". +- Restart Home Assistant. + +### Manual installation +- Using the tool of choice open the directory for your HA configuration (where you find configuration.yaml). +- If you do not have a custom_components directory there, you need to create it. +- In releases(https://github.com/Refoss/refoss_rpc/releases), download the version you need. +- In the downloaded file, locate the refoss_rpc directory and copy it to the custom_components directory. +- Restart Home Assistant. + +## Configuration +- In the HA UI go to "Configuration" -> "Integrations", click "+", search for "Refoss RPC", and select the "Refoss RPC" integration from the list. + Or click here: [![Start Config Flow](https://my.home-assistant.io/badges/config_flow_start.svg)](https://my.home-assistant.io/redirect/config_flow_start?domain=refoss_rpc) + +## Supported device models + +| Model | Version | +|-------------------------------------|--------------------| +| `Refoss Smart Wi-Fi Switch, R11` | `all` | diff --git a/custom_components/refoss_rpc/__init__.py b/custom_components/refoss_rpc/__init__.py index 90eb501..453021d 100644 --- a/custom_components/refoss_rpc/__init__.py +++ b/custom_components/refoss_rpc/__init__.py @@ -31,7 +31,6 @@ RefossConfigEntry, RefossCoordinator, RefossEntryData, - RefossPollingCoordinator, ) PLATFORMS: Final = [ @@ -73,7 +72,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: RefossConfigEntry) -> bo runtime_data.coordinator = RefossCoordinator(hass, entry, device) runtime_data.coordinator.async_setup() - runtime_data.poll_coordinator = RefossPollingCoordinator(hass, entry, device) await hass.config_entries.async_forward_entry_setups(entry, runtime_data.platforms) return True diff --git a/custom_components/refoss_rpc/const.py b/custom_components/refoss_rpc/const.py index 360d54b..98ec91a 100644 --- a/custom_components/refoss_rpc/const.py +++ b/custom_components/refoss_rpc/const.py @@ -9,12 +9,8 @@ LOGGER: Logger = getLogger(__package__) - -# Refresh interval for polling -REFOSS_SENSORS_POLLING_INTERVAL: Final = 60 - -# Reconnect interval for devices -REFOSS_RECONNECT_INTERVAL = 60 +#Check interval for devices +REFOSS_CHECK_INTERVAL = 60 # Button Click events for devices diff --git a/custom_components/refoss_rpc/coordinator.py b/custom_components/refoss_rpc/coordinator.py index fc5b080..602140a 100644 --- a/custom_components/refoss_rpc/coordinator.py +++ b/custom_components/refoss_rpc/coordinator.py @@ -42,8 +42,7 @@ OTA_ERROR, OTA_PROGRESS, OTA_SUCCESS, - REFOSS_RECONNECT_INTERVAL, - REFOSS_SENSORS_POLLING_INTERVAL, + REFOSS_CHECK_INTERVAL, ) from .utils import get_host, update_device_fw_info @@ -54,7 +53,6 @@ class RefossEntryData: platforms: list[Platform] coordinator: RefossCoordinator | None = None - poll_coordinator: RefossPollingCoordinator | None = None RefossConfigEntry = ConfigEntry[RefossEntryData] @@ -174,7 +172,7 @@ def __init__( ) -> None: """Initialize the Refoss coordinator.""" self.entry = entry - super().__init__(hass, entry, device, REFOSS_RECONNECT_INTERVAL) + super().__init__(hass, entry, device, REFOSS_CHECK_INTERVAL) self.connected = False self._connection_lock = asyncio.Lock() @@ -255,11 +253,22 @@ async def _async_update_data(self) -> None: """Fetch data.""" if self.hass.is_stopping: return + async with self._connection_lock: - if self.device.connected: # Already connected + if not self.device.connected: + if not await self._async_device_connect_task(): + raise UpdateFailed("Device reconnect error") return - if not await self._async_device_connect_task(): - raise UpdateFailed("Device reconnect error") + try: + LOGGER.debug("Polling Refoss Device - %s", self.name) + await self.device.poll() + except DeviceConnectionError as err: + raise UpdateFailed(f"Device disconnected: {err!r}") from err + except RpcCallError as err: + raise UpdateFailed(f"RPC call failed: {err!r}") from err + except InvalidAuthError: + await self.async_shutdown_device_and_start_reauth() + return async def _async_disconnected(self, reconnect: bool) -> None: """Handle device disconnected.""" @@ -346,29 +355,6 @@ async def shutdown(self) -> None: await self._async_disconnected(False) -class RefossPollingCoordinator(RefossCoordinatorBase): - """Polling coordinator for a Refoss device.""" - - def __init__( - self, hass: HomeAssistant, entry: RefossConfigEntry, device: RpcDevice - ) -> None: - """Initialize the polling coordinator.""" - super().__init__(hass, entry, device, REFOSS_SENSORS_POLLING_INTERVAL) - - async def _async_update_data(self) -> None: - """Fetch data.""" - if not self.device.connected: - raise UpdateFailed("Device disconnected") - - LOGGER.debug("Polling Refoss Device - %s", self.name) - try: - await self.device.poll() - except (DeviceConnectionError, RpcCallError) as err: - raise UpdateFailed(f"Device disconnected: {err!r}") from err - except InvalidAuthError: - await self.async_shutdown_device_and_start_reauth() - - def get_refoss_coordinator_by_device_id( hass: HomeAssistant, device_id: str ) -> RefossCoordinator | None: diff --git a/custom_components/refoss_rpc/entity.py b/custom_components/refoss_rpc/entity.py index d2a067e..06432de 100644 --- a/custom_components/refoss_rpc/entity.py +++ b/custom_components/refoss_rpc/entity.py @@ -39,8 +39,6 @@ def async_setup_entry_refoss( if not coordinator.device.initialized: return - polling_coordinator = config_entry.runtime_data.poll_coordinator - entities = [] for sensor_id in sensors: description = sensors[sensor_id] @@ -63,10 +61,6 @@ def async_setup_entry_refoss( domain = sensor_class.__module__.split(".")[-1] unique_id = f"{coordinator.mac}-{key}-{sensor_id}" async_remove_refoss_entity(hass, domain, unique_id) - elif description.use_polling_coordinator: - entities.append( - sensor_class(polling_coordinator, key, sensor_id, description) - ) else: entities.append(sensor_class(coordinator, key, sensor_id, description)) if not entities: @@ -84,7 +78,6 @@ class RefossEntityDescription(EntityDescription): value: Callable[[Any, Any], Any] | None = None removal_condition: Callable[[dict, dict, str], bool] | None = None - use_polling_coordinator: bool = False supported: Callable = lambda _: False diff --git a/custom_components/refoss_rpc/sensor.py b/custom_components/refoss_rpc/sensor.py index d1defb8..c155c76 100644 --- a/custom_components/refoss_rpc/sensor.py +++ b/custom_components/refoss_rpc/sensor.py @@ -93,7 +93,6 @@ class RefossSensorDescription(RefossEntityDescription, SensorEntityDescription): state_class=SensorStateClass.MEASUREMENT, entity_category=EntityCategory.DIAGNOSTIC, entity_registry_enabled_default=False, - use_polling_coordinator=True, ), "rssi": RefossSensorDescription( key="wifi", @@ -105,7 +104,6 @@ class RefossSensorDescription(RefossEntityDescription, SensorEntityDescription): removal_condition=is_refoss_wifi_stations_disabled, entity_category=EntityCategory.DIAGNOSTIC, entity_registry_enabled_default=False, - use_polling_coordinator=True, ), "uptime": RefossSensorDescription( key="sys", @@ -115,7 +113,6 @@ class RefossSensorDescription(RefossEntityDescription, SensorEntityDescription): device_class=SensorDeviceClass.TIMESTAMP, entity_category=EntityCategory.DIAGNOSTIC, entity_registry_enabled_default=False, - use_polling_coordinator=True, ), } diff --git a/custom_components/refoss_rpc/strings.json b/custom_components/refoss_rpc/strings.json index 47cad2b..f0fb6a3 100644 --- a/custom_components/refoss_rpc/strings.json +++ b/custom_components/refoss_rpc/strings.json @@ -3,7 +3,7 @@ "flow_title": "{name}", "step": { "user": { - "description": "Before setup, devices must be connected to the network.\n\nThis path can be configured for refoss product models including R11, etc. \n\nFor more information, please refer to 'Help'.", + "description": "Before setup, devices must be connected to the network.\n\nThis path can be configured for Refoss product models including R11, etc. \n\nFor more information, please refer to 'Help'.", "data": { "host": "[%key:common::config_flow::data::host%]" }, diff --git a/custom_components/refoss_rpc/translations/en.json b/custom_components/refoss_rpc/translations/en.json index 7b35f30..eec3b37 100644 --- a/custom_components/refoss_rpc/translations/en.json +++ b/custom_components/refoss_rpc/translations/en.json @@ -51,7 +51,7 @@ "data_description": { "host": "The hostname or IP address of the Refoss device to connect to." }, - "description": "Before setup, devices must be connected to the network.\n\nThis path can be configured for refoss product models including R11, etc. \n\nFor more information, please refer to 'Help'." + "description": "Before setup, devices must be connected to the network.\n\nThis path can be configured for Refoss product models including R11, etc. \n\nFor more information, please refer to 'Help'." } } }, From 5078f7c7c1f9b06115089502c7e17b806505f4e1 Mon Sep 17 00:00:00 2001 From: ashionky <495519020@qq.com> Date: Wed, 12 Mar 2025 16:00:19 +0800 Subject: [PATCH 2/2] const --- custom_components/refoss_rpc/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/refoss_rpc/const.py b/custom_components/refoss_rpc/const.py index 98ec91a..abe120d 100644 --- a/custom_components/refoss_rpc/const.py +++ b/custom_components/refoss_rpc/const.py @@ -37,7 +37,7 @@ UPTIME_DEVIATION: Final = 5 # Time to wait before reloading entry when device config change -ENTRY_RELOAD_COOLDOWN = 60 +ENTRY_RELOAD_COOLDOWN = 30 OTA_BEGIN = "ota_begin"