Skip to content

Invalid switch-entity command logic if switch only supports ON_OFF #4

@zehnm

Description

@zehnm

Is there an existing issue for this?

  • I have searched the existing issues

Description

Refers to:

While testing the referred issue, I noticed that the UI sends invalid switch commands.

How to Reproduce

  1. Create a demo integration with a switch having only the on_off feature
{"kind": "resp", "req_id": 5, "code": 200, "msg": "available_entities", "msg_data": {"available_entities": [{"entity_id": "switch1", "entity_type": "switch", "device_id": null, "features": ["on_off"], "name": {"en": "Demo switch"}, "area": null, "device_class": null}]}}
  1. Add entity to UI
  2. Press the switch. Expected: on or off command, but toggle is sent:
{"kind":"req","id":7,"msg":"entity_command","msg_data":{"cmd_id":"toggle","entity_id":"switch1","entity_type":"switch"}}

Expected behavior

If switch doesn't support the toggle feature and only on_off, the UI may not send a toggle command.

UI version

0.36.0

Additional context

Python demo integration:

#!/usr/bin/env python3
"""Switch entity integration example. Bare minimum of an integration driver."""
import asyncio
import logging
from typing import Any

import ucapi
from ucapi import switch

loop = asyncio.get_event_loop()
api = ucapi.IntegrationAPI(loop)


async def cmd_handler(
    entity: ucapi.Switch, cmd_id: str, _params: dict[str, Any] | None
) -> ucapi.StatusCodes:
    """
    Switch command handler.

    Called by the integration-API if a command is sent to a configured switch-entity.

    :param entity: switch entity
    :param cmd_id: command
    :param _params: optional command parameters
    :return: status of the command
    """
    print(f"Got {entity.id} command request: {cmd_id}")

    state = None
    if cmd_id == switch.Commands.ON:
        state = switch.States.ON
    elif cmd_id == switch.Commands.OFF:
        state = switch.States.OFF
    elif cmd_id == switch.Commands.TOGGLE:
        print("Toggle command should not be sent, entity only has on_off feature!")
        if entity.attributes[switch.Attributes.STATE] == switch.States.OFF:
            state = switch.States.ON
        else:
            state = switch.States.OFF

    if state:
        api.configured_entities.update_attributes(
            entity.id, {switch.Attributes.STATE: state}
        )

    return ucapi.StatusCodes.OK


@api.listens_to(ucapi.Events.CONNECT)
async def on_connect() -> None:
    # When the remote connects, we just set the device state. We are ready all the time!
    await api.set_device_state(ucapi.DeviceStates.CONNECTED)


if __name__ == "__main__":
    logging.basicConfig()

    entity = ucapi.Switch(
        "switch1",
        "Demo switch",
        [switch.Features.ON_OFF],
        {switch.Attributes.STATE: switch.States.OFF},
        cmd_handler=cmd_handler,
    )
    api.available_entities.add(entity)

    loop.run_until_complete(api.init("switch.json"))
    loop.run_forever()

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions