Skip to content

Commit

Permalink
feat(controller): allow adding the seconds directly to action_delay
Browse files Browse the repository at this point in the history
This will affect all actions at once without needing to add the same delay to all actions individually
  • Loading branch information
xaviml committed Feb 6, 2021
1 parent 853eada commit 15634e6
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 17 deletions.
22 changes: 17 additions & 5 deletions apps/controllerx/cx_core/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,9 @@ async def init(self) -> None:
)

# Action delay
default_action_delay = {action_key: 0 for action_key in self.actions_mapping}
self.action_delay = {
**default_action_delay,
**self.args.get("action_delay", {}),
}
self.action_delay = self.get_mapping_per_action(
self.actions_mapping, custom=self.args.get("action_delay"), default=0
)
self.action_delay_handles = defaultdict(lambda: None)
self.action_handles = defaultdict(lambda: None)

Expand Down Expand Up @@ -209,6 +207,20 @@ def get_list(self, entities: Union[List[T], T]) -> List[T]:
return list(entities)
return [entities]

def get_mapping_per_action(
self,
actions_mapping: ActionsMapping,
*,
custom: Optional[Union[T, Dict[ActionEvent, T]]],
default: T,
) -> Dict[ActionEvent, T]:
if custom is not None and not isinstance(custom, dict):
default = custom
mapping = {action: default for action in actions_mapping}
if custom is not None and isinstance(custom, dict):
mapping.update(custom)
return mapping

def parse_action_mapping(self, mapping: CustomActionsMapping) -> ActionsMapping:
return {event: parse_actions(self, action) for event, action in mapping.items()}

Expand Down
23 changes: 12 additions & 11 deletions docs/start/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,17 +63,17 @@ otherwise they will be parsed as boolean variables (True and False).

These are the generic app parameters for all type of controllers. You can see the rest in [here](type-configuration).

| key | type | value | description |
| ---------------------- | -------------- | ------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `module`\* | string | `controllerx` | The Python module |
| `class`\* | string | `E1810Controller` | The Python class. Check the classes for each controller on the [supported controllers](/controllerx/controllers) page. |
| `controller`\* | string \| list | `sensor.controller` or `hue_switch1, hue_switch2` | This is the controller id, which will depend on the integration. See [here](/controllerx/others/extract-controller-id) to know how to get the controller id. |
| `integration`\* | string \| dict | `z2m`, `deconz` or `zha` | This is the integration that the device was integrated. |
| `actions` | list | All actions | This is a list of actions to be included and controlled by the app. To see which actions has each controller check the individual controller pages in [here](/controllerx/controllers). This attribute cannot be used together with `excluded_actions`. |
| `excluded_actions` | list | Empty list | This is a list of actions to be excluded. To see which actions has each controller check the individual controller pages in [here](/controllerx/controllers). This attribute cannot be used together with `actions`. |
| `action_delta` | int | 300 | This is the threshold time between the previous action and the next one (being the same action). If the time difference between the two actions is less than this attribute, then the action won't be called. I recommend changing this if you see the same action being called twice. |
| `multiple_click_delay` | int | 500 | Indicates the delay (in milliseconds) when a multiple click action should be trigger. The higher the number, the more time there can be between clicks, but there will be more delay for the action to be triggered. |
| `action_delay` | dict | - | This can be used to set a delay to each action. By default, the delay for all actions is 0. The key for the map is the action and the value is the delay in seconds. |
| key | type | value | description |
| ---------------------- | -------------- | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `module`\* | string | `controllerx` | The Python module |
| `class`\* | string | `E1810Controller` | The Python class. Check the classes for each controller on the [supported controllers](/controllerx/controllers) page. |
| `controller`\* | string \| list | `sensor.controller` or `hue_switch1, hue_switch2` | This is the controller id, which will depend on the integration. See [here](/controllerx/others/extract-controller-id) to know how to get the controller id. |
| `integration`\* | string \| dict | `z2m`, `deconz` or `zha` | This is the integration that the device was integrated. |
| `actions` | list | All actions | This is a list of actions to be included and controlled by the app. To see which actions has each controller check the individual controller pages in [here](/controllerx/controllers). This attribute cannot be used together with `excluded_actions`. |
| `excluded_actions` | list | Empty list | This is a list of actions to be excluded. To see which actions has each controller check the individual controller pages in [here](/controllerx/controllers). This attribute cannot be used together with `actions`. |
| `action_delta` | int | 300 | This is the threshold time between the previous action and the next one (being the same action). If the time difference between the two actions is less than this attribute, then the action won't be called. I recommend changing this if you see the same action being called twice. |
| `multiple_click_delay` | int | 500 | Indicates the delay (in milliseconds) when a multiple click action should be trigger. The higher the number, the more time there can be between clicks, but there will be more delay for the action to be triggered. |
| `action_delay` | dict \| int | - | This can be used to set a delay to each action. By default, the delay for all actions is 0. If defining a map, the key for the map is the action and the value is the delay in seconds. Otherwise, we can set a default time like `action_delay: 10`, and this will add a delay to all actions. |
| `mapping` | dict | - | This can be used to replace the behaviour of the controller and manually select what each button should be doing. By default it will ignore this parameter. Read more about it in [here](/controllerx/advanced/custom-controllers). The functionality included in this attribute will remove the default mapping. |
| `merge_mapping` | dict | - | This can be used to merge the default mapping from the controller and manually select what each button should be doing. By default it will ignore this parameter. Read more about it in [here](/controllerx/advanced/custom-controllers). The functionality included in this attribute is added on top of the default mapping. |

Expand All @@ -88,6 +88,7 @@ In addition, you can add arguments. Each [integration](/controllerx/others/integ
_\* Required fields_

#### Explained with YAML

```yaml
example_app: # It can be anything
module: controllerx
Expand Down
55 changes: 54 additions & 1 deletion tests/unit_tests/cx_core/controller_test.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from collections import defaultdict
from typing import Any, Dict, List, Optional, Union
from typing import Any, Dict, List, Optional, Set, Union

import appdaemon.plugins.hass.hassapi as hass
import pytest
Expand Down Expand Up @@ -242,6 +242,59 @@ def test_get_list(
assert output == expected


@pytest.mark.parametrize(
"actions, custom, default, expected",
[
(
{"action1", "action2", "action3"},
None,
0,
{"action1": 0, "action2": 0, "action3": 0},
),
(
{"action1", "action2", "action3"},
{"action1": 10},
0,
{"action1": 10, "action2": 0, "action3": 0},
),
(
{"action1", "action2", "action3"},
10,
0,
{"action1": 10, "action2": 10, "action3": 10},
),
(
{"action1", "action2", "action3"},
None,
"restart",
{"action1": "restart", "action2": "restart", "action3": "restart"},
),
(
{"action1", "action2", "action3"},
"single",
"restart",
{"action1": "single", "action2": "single", "action3": "single"},
),
(
{"action1", "action2", "action3"},
{"action2": "single", "action3": "another"},
"restart",
{"action1": "restart", "action2": "single", "action3": "another"},
),
],
)
def test_get_mapping_per_action(
sut: Controller,
actions: Set[ActionEvent],
custom: Optional[Dict[ActionEvent, Any]],
default: Any,
expected: Dict[ActionEvent, Any],
) -> None:
actions_mapping: ActionsMapping = {action: [] for action in actions}
output = sut.get_mapping_per_action(actions_mapping, custom=custom, default=default)
assert output == expected


@pytest.mark.parametrize(
"mapping, expected",
[
Expand Down

0 comments on commit 15634e6

Please sign in to comment.