Skip to content

Add Fluss+ Button integration #139925

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 80 commits into
base: dev
Choose a base branch
from
Draft

Conversation

Marcello17
Copy link

@Marcello17 Marcello17 commented Mar 6, 2025

Type of change

  • Dependency upgrade
  • Bugfix (non-breaking change which fixes an issue)
  • New integration (thank you!)
  • New feature (which adds functionality to an existing integration)
  • Deprecation (breaking change to happen in the future)
  • Breaking change (fix/feature causing existing functionality to break)
  • Code quality improvements to existing code or addition of tests

Additional information

Checklist

  • The code change is tested and works locally.
  • Local tests pass. Your PR cannot be merged unless tests pass
  • There is no commented out code in this PR.
  • I have followed the development checklist
  • I have followed the perfect PR recommendations
  • The code has been formatted using Ruff (ruff format homeassistant tests)
  • Tests have been added to verify that the new code works.

If user exposed functionality or configuration variables are added/changed:

If the code communicates with devices, web services, or third-party tools:

  • The manifest file has all fields filled out correctly.
    Updated and included derived files by running: python3 -m script.hassfest.
  • New or updated dependencies have been added to requirements_all.txt.
    Updated by running python3 -m script.gen_requirements_all.
  • For the updated dependencies - a link to the changelog, or at minimum a diff between library versions is added to the PR description.

To help with the load of incoming pull requests:

NjDaGreat and others added 30 commits June 28, 2024 13:40
Added some contextual names
Co-authored-by: Josef Zweck <josef@zweck.dev>
Co-authored-by: Josef Zweck <josef@zweck.dev>
Co-authored-by: Josef Zweck <josef@zweck.dev>
Co-authored-by: Josef Zweck <josef@zweck.dev>
@Marcello17 Marcello17 marked this pull request as ready for review April 30, 2025 08:42
@home-assistant home-assistant bot requested a review from zweckj April 30, 2025 08:42
Comment on lines 35 to 38
await self.async_set_unique_id(DOMAIN)

if self._async_current_entries():
return self.async_abort(reason="single_instance_allowed")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we only allow one instance?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The user only needs to add it once since the api key is connect to their account which is able to get the devices they have access to.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, but why can't there be 2 users?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair point, removing the config for that.

@home-assistant home-assistant bot marked this pull request as draft May 14, 2025 09:55
@Marcello17 Marcello17 marked this pull request as ready for review May 16, 2025 12:57
@home-assistant home-assistant bot requested a review from joostlek May 16, 2025 12:57
Comment on lines 35 to 38
await self.async_set_unique_id(DOMAIN)

if self._async_current_entries():
return self.async_abort(reason="single_instance_allowed")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, but why can't there be 2 users?

@home-assistant home-assistant bot marked this pull request as draft June 12, 2025 16:00
@Marcello17 Marcello17 marked this pull request as ready for review June 17, 2025 08:02
@home-assistant home-assistant bot requested a review from joostlek June 17, 2025 08:02
@home-assistant home-assistant bot marked this pull request as draft June 17, 2025 08:10
@Marcello17 Marcello17 marked this pull request as ready for review June 18, 2025 06:04
@home-assistant home-assistant bot requested a review from joostlek June 18, 2025 06:04
Copy link
Member

@zweckj zweckj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry that took a while

Comment on lines +27 to +31
entities: list[FlussButton] = []
for device_id, device in devices.items():
entities.append(FlussButton(coordinator, device_id, device))

async_add_entities(entities)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
entities: list[FlussButton] = []
for device_id, device in devices.items():
entities.append(FlussButton(coordinator, device_id, device))
async_add_entities(entities)
async_add_entities(FlussButton(coordinator, device_id, device) for device_id, device in devices.items())

Comment on lines +50 to +53
@property
def available(self) -> bool:
"""Return if the entity is available."""
return self.coordinator.last_update_success
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@property
def available(self) -> bool:
"""Return if the entity is available."""
return self.coordinator.last_update_success

is the default for coordinator entities

Comment on lines +39 to +42
@property
def available(self) -> bool:
"""Return if the entity is available."""
return super().available and self.device_id in self.coordinator.data
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@property
def available(self) -> bool:
"""Return if the entity is available."""
return super().available and self.device_id in self.coordinator.data

not used atm

self,
coordinator: FlussDataUpdateCoordinator,
device_id: str,
device: dict | None = None,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why would the device even be None, we probably shouldn't setup the entity if we don't have that device. That'll also simplify the code below

Comment on lines +33 to +37
def name(self) -> str:
"""Use the deviceName field for the entity name."""
return (
self.device.get("deviceName", super().name) if self.device else super().name
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably rather add a proper home assistant device to your entity _attr_device_info. If that is the main entity of the device you can set _attr_name to None, so it'll take the device's name

assert result["errors"] == {}


async def test_step_user_success(config_flow: FlussConfigFlow) -> None:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

init your flows with

        result = await hass.config_entries.flow.async_init(
            DOMAIN, context={"source": SOURCE_USER}
        )

mock_client.return_value = None
result = await config_flow.async_step_user(user_input)

assert result["type"] == FlowResultType.CREATE_ENTRY
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
assert result["type"] == FlowResultType.CREATE_ENTRY
assert result["type"] is FlowResultType.CREATE_ENTRY

is to compare enums

Comment on lines +51 to +68
async def test_step_user_invalid_auth(config_flow: FlussConfigFlow) -> None:
"""Test invalid authentication."""
user_input = {CONF_API_KEY: "invalid_api_key"}

with patch("homeassistant.components.fluss.config_flow.FlussApiClient") as mock_client:
mock_client.side_effect = FlussApiClientAuthenticationError
result = await config_flow.async_step_user(user_input)

assert result["type"] == FlowResultType.FORM
assert result["step_id"] == "user"
assert result["errors"] == {"base": "invalid_auth"}


async def test_step_user_cannot_connect(config_flow: FlussConfigFlow) -> None:
"""Test connection failure."""
user_input = {CONF_API_KEY: "some_api_key"}

with patch("homeassistant.components.fluss.config_flow.FlussApiClient") as mock_client:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

those can be parametrized

Comment on lines +101 to +112
def test_data_schema_validation():
"""Test that the data schema enforces required string field."""
# Valid input
STEP_USER_DATA_SCHEMA({CONF_API_KEY: "test_key"})

# Missing key
with pytest.raises(vol.error.MultipleInvalid):
STEP_USER_DATA_SCHEMA({})

# Non-string value
with pytest.raises(vol.error.MultipleInvalid):
STEP_USER_DATA_SCHEMA({CONF_API_KEY: 123})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you don't need to test that, HA takes care of that

Comment on lines +19 to +27
@pytest.fixture
async def mock_hass():
"""Mock Hass Environment."""
hass = AsyncMock(spec=HomeAssistant)
hass.config_entries = AsyncMock()
hass.config_entries.async_forward_entry_setups = AsyncMock()
hass.config_entries.async_unload_platforms = AsyncMock()
hass.data = {}
return hass
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move common fixtures to conftest.py

@home-assistant home-assistant bot marked this pull request as draft July 16, 2025 09:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants