boneIO 1.3.1.dev1__py3-none-any.whl → 1.3.1.dev2__py3-none-any.whl

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 (78) hide show
  1. boneio/boards/0.2/input.yaml +0 -14
  2. boneio/boards/0.3/input.yaml +0 -14
  3. boneio/boards/0.4/input.yaml +0 -14
  4. boneio/boards/0.5/input.yaml +0 -12
  5. boneio/boards/0.6/input.yaml +0 -12
  6. boneio/boards/0.7/input.yaml +0 -12
  7. boneio/boards/0.8/input.yaml +0 -12
  8. boneio/components/cover/cover.py +47 -37
  9. boneio/components/cover/time_based.py +23 -26
  10. boneio/components/cover/venetian.py +13 -14
  11. boneio/components/group/output_group.py +2 -3
  12. boneio/components/irrigation/controller.py +2 -2
  13. boneio/components/output/basic.py +3 -1
  14. boneio/components/output/mcp.py +10 -18
  15. boneio/components/template/alarm_panel.py +2 -3
  16. boneio/components/template/gate_cover.py +15 -25
  17. boneio/components/template/thermostat.py +7 -8
  18. boneio/core/cloud/registration.py +10 -28
  19. boneio/core/config/migrations/v1_proxy_port.py +3 -4
  20. boneio/core/config/schema_converter.py +4 -5
  21. boneio/core/manager/action_conditions.py +2 -8
  22. boneio/core/manager/canopen.py +18 -52
  23. boneio/core/manager/inputs.py +12 -6
  24. boneio/core/manager/irrigation.py +20 -18
  25. boneio/core/manager/update.py +39 -41
  26. boneio/core/remote/base.py +3 -3
  27. boneio/core/system/host_data.py +2 -4
  28. boneio/core/utils/async_updater.py +35 -50
  29. boneio/core/utils/util.py +2 -2
  30. boneio/hardware/gpio/expanders/mcp23017.py +12 -14
  31. boneio/hardware/gpio/input/base.py +51 -43
  32. boneio/hardware/gpio/input/manager.py +72 -85
  33. boneio/hardware/i2c/bus.py +8 -12
  34. boneio/hardware/i2c/ina219.py +4 -2
  35. boneio/hardware/i2c/mcp9808.py +1 -1
  36. boneio/hardware/onewire/dallas.py +4 -6
  37. boneio/hardware/sensor/temperature/base.py +1 -1
  38. boneio/integration/homeassistant.py +40 -0
  39. boneio/migrations/actions.py +8 -4
  40. boneio/migrations/runner.py +2 -2
  41. boneio/modbus/cli.py +2 -4
  42. boneio/modbus/client.py +64 -64
  43. boneio/modbus/coordinator.py +27 -23
  44. boneio/modbus/entities/base.py +9 -3
  45. boneio/modbus/entities/derived/numeric.py +3 -1
  46. boneio/modbus/entities/sensor/numeric.py +3 -1
  47. boneio/modbus/entities/sensor/text.py +6 -2
  48. boneio/modbus/entities/writeable/binary.py +3 -1
  49. boneio/modbus/entities/writeable/numeric.py +3 -1
  50. boneio/schema/schema.yaml +8 -6
  51. boneio/version.py +1 -1
  52. boneio/webui/app.py +36 -92
  53. boneio/webui/frontend-dist/assets/{ConfigEditor-DcU5XNy1.js → ConfigEditor-wi_Mieo6.js} +1 -1
  54. boneio/webui/frontend-dist/assets/{index-BoLwm6vF.js → index-C_7FDXG5.js} +30 -30
  55. boneio/webui/frontend-dist/assets/{useTranslation-Dwuk-AFr.js → useTranslation-BsWm27qn.js} +2 -2
  56. boneio/webui/frontend-dist/index.html +2 -2
  57. boneio/webui/frontend-dist/schema/binary_sensor.schema.json +11 -2
  58. boneio/webui/frontend-dist/schema/config.schema.json +22 -4
  59. boneio/webui/frontend-dist/schema/event.schema.json +11 -2
  60. boneio/webui/frontend-dist/sw.js +1 -1
  61. boneio/webui/routes/__init__.py +1 -1
  62. boneio/webui/routes/caddy.py +4 -4
  63. boneio/webui/routes/config.py +3 -0
  64. boneio/webui/routes/outputs.py +1 -1
  65. boneio/webui/routes/timezone_sudoers.py +2 -3
  66. boneio/webui/routes/tools.py +4 -4
  67. boneio/webui/schema/binary_sensor.schema.json +11 -2
  68. boneio/webui/schema/config.schema.json +22 -4
  69. boneio/webui/schema/event.schema.json +11 -2
  70. boneio/webui/services/logs.py +2 -3
  71. boneio/webui/web_server.py +9 -5
  72. boneio/webui/websocket_manager.py +11 -13
  73. {boneio-1.3.1.dev1.dist-info → boneio-1.3.1.dev2.dist-info}/METADATA +1 -1
  74. {boneio-1.3.1.dev1.dist-info → boneio-1.3.1.dev2.dist-info}/RECORD +78 -78
  75. {boneio-1.3.1.dev1.dist-info → boneio-1.3.1.dev2.dist-info}/WHEEL +0 -0
  76. {boneio-1.3.1.dev1.dist-info → boneio-1.3.1.dev2.dist-info}/entry_points.txt +0 -0
  77. {boneio-1.3.1.dev1.dist-info → boneio-1.3.1.dev2.dist-info}/licenses/LICENSE +0 -0
  78. {boneio-1.3.1.dev1.dist-info → boneio-1.3.1.dev2.dist-info}/top_level.txt +0 -0
@@ -1,10 +1,8 @@
1
1
  input_mapping:
2
2
  in_01:
3
3
  pin: P8_37
4
- gpio_mode: gpio_pu
5
4
  in_02:
6
5
  pin: P8_38
7
- gpio_mode: gpio_pu
8
6
  in_03:
9
7
  pin: P8_39
10
8
  in_04:
@@ -19,10 +17,8 @@ input_mapping:
19
17
  pin: P8_44
20
18
  in_09:
21
19
  pin: P8_45
22
- gpio_mode: gpio_pu
23
20
  in_10:
24
21
  pin: P8_46
25
- gpio_mode: gpio_pu
26
22
  in_11:
27
23
  pin: P9_42
28
24
  in_12:
@@ -41,10 +37,8 @@ input_mapping:
41
37
  pin: P9_23
42
38
  in_19:
43
39
  pin: P9_22
44
- gpio_mode: gpio_pu
45
40
  in_20:
46
41
  pin: P9_21
47
- gpio_mode: gpio_pu
48
42
  in_21:
49
43
  pin: P9_18
50
44
  in_22:
@@ -59,28 +53,20 @@ input_mapping:
59
53
  pin: P9_13
60
54
  in_27:
61
55
  pin: P9_12
62
- gpio_mode: gpio_pu
63
56
  in_28:
64
57
  pin: P9_11
65
- gpio_mode: gpio_pu
66
58
  in_29:
67
59
  pin: P8_36
68
- gpio_mode: gpio_pu
69
60
  in_30:
70
61
  pin: P8_35
71
- gpio_mode: gpio_pu
72
62
  in_31:
73
63
  pin: P8_34
74
- gpio_mode: gpio_pu
75
64
  in_32:
76
65
  pin: P8_33
77
- gpio_mode: gpio_pu
78
66
  in_33:
79
67
  pin: P8_32
80
- gpio_mode: gpio_pu
81
68
  in_34:
82
69
  pin: P8_31
83
- gpio_mode: gpio_pu
84
70
  in_35:
85
71
  pin: P8_30
86
72
  in_36:
@@ -1,10 +1,8 @@
1
1
  input_mapping:
2
2
  in_01:
3
3
  pin: P8_37
4
- gpio_mode: gpio_pu
5
4
  in_02:
6
5
  pin: P8_38
7
- gpio_mode: gpio_pu
8
6
  in_03:
9
7
  pin: P8_39
10
8
  in_04:
@@ -19,10 +17,8 @@ input_mapping:
19
17
  pin: P8_44
20
18
  in_09:
21
19
  pin: P8_45
22
- gpio_mode: gpio_pu
23
20
  in_10:
24
21
  pin: P8_46
25
- gpio_mode: gpio_pu
26
22
  in_11:
27
23
  pin: P9_42
28
24
  in_12:
@@ -41,10 +37,8 @@ input_mapping:
41
37
  pin: P9_23
42
38
  in_19:
43
39
  pin: P9_22
44
- gpio_mode: gpio_pu
45
40
  in_20:
46
41
  pin: P9_21
47
- gpio_mode: gpio_pu
48
42
  in_21:
49
43
  pin: P9_18
50
44
  in_22:
@@ -59,28 +53,20 @@ input_mapping:
59
53
  pin: P9_13
60
54
  in_27:
61
55
  pin: P9_12
62
- gpio_mode: gpio_pu
63
56
  in_28:
64
57
  pin: P9_11
65
- gpio_mode: gpio_pu
66
58
  in_29:
67
59
  pin: P8_36
68
- gpio_mode: gpio_pu
69
60
  in_30:
70
61
  pin: P8_35
71
- gpio_mode: gpio_pu
72
62
  in_31:
73
63
  pin: P8_34
74
- gpio_mode: gpio_pu
75
64
  in_32:
76
65
  pin: P8_33
77
- gpio_mode: gpio_pu
78
66
  in_33:
79
67
  pin: P8_32
80
- gpio_mode: gpio_pu
81
68
  in_34:
82
69
  pin: P8_31
83
- gpio_mode: gpio_pu
84
70
  in_35:
85
71
  pin: P8_30
86
72
  in_36:
@@ -1,10 +1,8 @@
1
1
  input_mapping:
2
2
  in_01:
3
3
  pin: P8_37
4
- gpio_mode: gpio_pu
5
4
  in_02:
6
5
  pin: P8_38
7
- gpio_mode: gpio_pu
8
6
  in_03:
9
7
  pin: P8_39
10
8
  in_04:
@@ -19,10 +17,8 @@ input_mapping:
19
17
  pin: P8_44
20
18
  in_09:
21
19
  pin: P8_45
22
- gpio_mode: gpio_pu
23
20
  in_10:
24
21
  pin: P8_46
25
- gpio_mode: gpio_pu
26
22
  in_11:
27
23
  pin: P9_42
28
24
  in_12:
@@ -41,10 +37,8 @@ input_mapping:
41
37
  pin: P9_23
42
38
  in_19:
43
39
  pin: P9_22
44
- gpio_mode: gpio_pu
45
40
  in_20:
46
41
  pin: P9_21
47
- gpio_mode: gpio_pu
48
42
  in_21:
49
43
  pin: P9_18
50
44
  in_22:
@@ -59,28 +53,20 @@ input_mapping:
59
53
  pin: P9_13
60
54
  in_27:
61
55
  pin: P9_12
62
- gpio_mode: gpio_pu
63
56
  in_28:
64
57
  pin: P9_11
65
- gpio_mode: gpio_pu
66
58
  in_29:
67
59
  pin: P8_36
68
- gpio_mode: gpio_pu
69
60
  in_30:
70
61
  pin: P8_35
71
- gpio_mode: gpio_pu
72
62
  in_31:
73
63
  pin: P8_34
74
- gpio_mode: gpio_pu
75
64
  in_32:
76
65
  pin: P8_33
77
- gpio_mode: gpio_pu
78
66
  in_33:
79
67
  pin: P8_32
80
- gpio_mode: gpio_pu
81
68
  in_34:
82
69
  pin: P8_31
83
- gpio_mode: gpio_pu
84
70
  in_35:
85
71
  pin: P8_30
86
72
  in_36:
@@ -1,10 +1,8 @@
1
1
  input_mapping:
2
2
  in_01:
3
3
  pin: P8_37
4
- gpio_mode: gpio_pu
5
4
  in_02:
6
5
  pin: P8_38
7
- gpio_mode: gpio_pu
8
6
  in_03:
9
7
  pin: P8_39
10
8
  in_04:
@@ -19,10 +17,8 @@ input_mapping:
19
17
  pin: P8_44
20
18
  in_09:
21
19
  pin: P8_45
22
- gpio_mode: gpio_pu
23
20
  in_10:
24
21
  pin: P8_46
25
- gpio_mode: gpio_pu
26
22
  in_11:
27
23
  pin: P9_42
28
24
  in_12:
@@ -41,10 +37,8 @@ input_mapping:
41
37
  pin: P9_23
42
38
  in_19:
43
39
  pin: P9_22
44
- gpio_mode: gpio_pu
45
40
  in_20:
46
41
  pin: P9_21
47
- gpio_mode: gpio_pu
48
42
  in_21:
49
43
  pin: P9_18
50
44
  in_22:
@@ -63,22 +57,16 @@ input_mapping:
63
57
  pin: P8_9
64
58
  in_29:
65
59
  pin: P8_36
66
- gpio_mode: gpio_pu
67
60
  in_30:
68
61
  pin: P8_35
69
- gpio_mode: gpio_pu
70
62
  in_31:
71
63
  pin: P8_34
72
- gpio_mode: gpio_pu
73
64
  in_32:
74
65
  pin: P8_33
75
- gpio_mode: gpio_pu
76
66
  in_33:
77
67
  pin: P8_32
78
- gpio_mode: gpio_pu
79
68
  in_34:
80
69
  pin: P8_31
81
- gpio_mode: gpio_pu
82
70
  in_35:
83
71
  pin: P8_30
84
72
  in_36:
@@ -1,10 +1,8 @@
1
1
  input_mapping:
2
2
  in_01:
3
3
  pin: P8_37
4
- gpio_mode: gpio_pu
5
4
  in_02:
6
5
  pin: P8_38
7
- gpio_mode: gpio_pu
8
6
  in_03:
9
7
  pin: P8_39
10
8
  in_04:
@@ -19,10 +17,8 @@ input_mapping:
19
17
  pin: P8_44
20
18
  in_09:
21
19
  pin: P8_45
22
- gpio_mode: gpio_pu
23
20
  in_10:
24
21
  pin: P8_46
25
- gpio_mode: gpio_pu
26
22
  in_11:
27
23
  pin: P9_42
28
24
  in_12:
@@ -41,10 +37,8 @@ input_mapping:
41
37
  pin: P9_23
42
38
  in_19:
43
39
  pin: P9_22
44
- gpio_mode: gpio_pu
45
40
  in_20:
46
41
  pin: P9_21
47
- gpio_mode: gpio_pu
48
42
  in_21:
49
43
  pin: P9_18
50
44
  in_22:
@@ -63,22 +57,16 @@ input_mapping:
63
57
  pin: P8_9
64
58
  in_29:
65
59
  pin: P8_36
66
- gpio_mode: gpio_pu
67
60
  in_30:
68
61
  pin: P8_35
69
- gpio_mode: gpio_pu
70
62
  in_31:
71
63
  pin: P8_34
72
- gpio_mode: gpio_pu
73
64
  in_32:
74
65
  pin: P8_33
75
- gpio_mode: gpio_pu
76
66
  in_33:
77
67
  pin: P8_32
78
- gpio_mode: gpio_pu
79
68
  in_34:
80
69
  pin: P8_31
81
- gpio_mode: gpio_pu
82
70
  in_35:
83
71
  pin: P8_30
84
72
  in_36:
@@ -1,10 +1,8 @@
1
1
  input_mapping:
2
2
  in_01:
3
3
  pin: P8_37
4
- gpio_mode: gpio_pu
5
4
  in_02:
6
5
  pin: P8_38
7
- gpio_mode: gpio_pu
8
6
  in_03:
9
7
  pin: P8_39
10
8
  in_04:
@@ -19,10 +17,8 @@ input_mapping:
19
17
  pin: P8_44
20
18
  in_09:
21
19
  pin: P8_45
22
- gpio_mode: gpio_pu
23
20
  in_10:
24
21
  pin: P8_46
25
- gpio_mode: gpio_pu
26
22
  in_11:
27
23
  pin: P9_42
28
24
  in_12:
@@ -41,10 +37,8 @@ input_mapping:
41
37
  pin: P9_23
42
38
  in_19:
43
39
  pin: P9_22
44
- gpio_mode: gpio_pu
45
40
  in_20:
46
41
  pin: P9_21
47
- gpio_mode: gpio_pu
48
42
  in_21:
49
43
  pin: P9_18
50
44
  in_22:
@@ -63,22 +57,16 @@ input_mapping:
63
57
  pin: P8_9
64
58
  in_29:
65
59
  pin: P8_36
66
- gpio_mode: gpio_pu
67
60
  in_30:
68
61
  pin: P8_35
69
- gpio_mode: gpio_pu
70
62
  in_31:
71
63
  pin: P8_34
72
- gpio_mode: gpio_pu
73
64
  in_32:
74
65
  pin: P8_33
75
- gpio_mode: gpio_pu
76
66
  in_33:
77
67
  pin: P8_32
78
- gpio_mode: gpio_pu
79
68
  in_34:
80
69
  pin: P8_31
81
- gpio_mode: gpio_pu
82
70
  in_35:
83
71
  pin: P8_30
84
72
  in_36:
@@ -1,12 +1,10 @@
1
1
  input_mapping:
2
2
  in_01:
3
3
  pin: P8_37
4
- gpio_mode: gpio_pu
5
4
  gpiochip: 1
6
5
  line: 14
7
6
  in_02:
8
7
  pin: P8_38
9
- gpio_mode: gpio_pu
10
8
  gpiochip: 1
11
9
  line: 15
12
10
  in_03:
@@ -38,12 +36,10 @@ input_mapping:
38
36
  line: 9
39
37
  in_09:
40
38
  pin: P8_45
41
- gpio_mode: gpio_pu
42
39
  gpiochip: 1
43
40
  line: 6
44
41
  in_10:
45
42
  pin: P8_46
46
- gpio_mode: gpio_pu
47
43
  gpiochip: 1
48
44
  line: 7
49
45
  in_11:
@@ -80,12 +76,10 @@ input_mapping:
80
76
  line: 17
81
77
  in_19:
82
78
  pin: P9_22
83
- gpio_mode: gpio_pu
84
79
  gpiochip: 3
85
80
  line: 2
86
81
  in_20:
87
82
  pin: P9_21
88
- gpio_mode: gpio_pu
89
83
  gpiochip: 3
90
84
  line: 3
91
85
  in_21:
@@ -122,32 +116,26 @@ input_mapping:
122
116
  line: 5
123
117
  in_29:
124
118
  pin: P8_36
125
- gpio_mode: gpio_pu
126
119
  gpiochip: 1
127
120
  line: 16
128
121
  in_30:
129
122
  pin: P8_35
130
- gpio_mode: gpio_pu
131
123
  gpiochip: 3
132
124
  line: 8
133
125
  in_31:
134
126
  pin: P8_34
135
- gpio_mode: gpio_pu
136
127
  gpiochip: 1
137
128
  line: 17
138
129
  in_32:
139
130
  pin: P8_33
140
- gpio_mode: gpio_pu
141
131
  gpiochip: 3
142
132
  line: 9
143
133
  in_33:
144
134
  pin: P8_32
145
- gpio_mode: gpio_pu
146
135
  gpiochip: 3
147
136
  line: 11
148
137
  in_34:
149
138
  pin: P8_31
150
- gpio_mode: gpio_pu
151
139
  gpiochip: 3
152
140
  line: 10
153
141
  in_35:
@@ -7,6 +7,7 @@ import threading
7
7
  import time
8
8
  from abc import ABC, abstractmethod
9
9
  from collections.abc import Callable
10
+ from contextlib import suppress
10
11
 
11
12
  from boneio.components.output import BasicOutput
12
13
  from boneio.const import (
@@ -25,11 +26,14 @@ from boneio.models.events import CoverEvent
25
26
 
26
27
  _LOGGER = logging.getLogger(__name__)
27
28
 
29
+
28
30
  class BaseCoverABC(ABC):
29
31
  """Base cover class."""
30
32
 
31
33
  @abstractmethod
32
- def __init__(self, id: str,
34
+ def __init__(
35
+ self,
36
+ id: str,
33
37
  open_relay: BasicOutput,
34
38
  close_relay: BasicOutput,
35
39
  state_save: Callable,
@@ -40,11 +44,10 @@ class BaseCoverABC(ABC):
40
44
  **kwargs,
41
45
  ) -> None:
42
46
  pass
43
-
44
47
 
45
48
  @abstractmethod
46
49
  async def stop(self) -> None:
47
- """Stop cover."""
50
+ """Stop cover."""
48
51
  pass
49
52
 
50
53
  @abstractmethod
@@ -77,7 +80,6 @@ class BaseCoverABC(ABC):
77
80
  """Set cover position."""
78
81
  pass
79
82
 
80
-
81
83
  @property
82
84
  @abstractmethod
83
85
  def state(self) -> str:
@@ -103,9 +105,10 @@ class BaseCoverABC(ABC):
103
105
  def kind(self) -> str:
104
106
  pass
105
107
 
106
-
107
108
  @abstractmethod
108
- async def run_cover(self, current_operation: str, target_position: float | None = None, target_tilt: float | None = None) -> None:
109
+ async def run_cover(
110
+ self, current_operation: str, target_position: float | None = None, target_tilt: float | None = None
111
+ ) -> None:
109
112
  """This function is called to run cover after calling open, close, toggle, toggle_open, toggle_close, set_cover_position"""
110
113
  pass
111
114
 
@@ -113,6 +116,7 @@ class BaseCoverABC(ABC):
113
116
  async def send_state(self, state: str, position: float) -> None:
114
117
  pass
115
118
 
119
+
116
120
  class BaseVenetianCoverABC:
117
121
  @property
118
122
  @abstractmethod
@@ -146,7 +150,9 @@ class BaseVenetianCoverABC:
146
150
 
147
151
 
148
152
  class BaseCover(BaseCoverABC, BasicMqtt):
149
- def __init__(self, id: str,
153
+ def __init__(
154
+ self,
155
+ id: str,
150
156
  open_relay: BasicOutput,
151
157
  close_relay: BasicOutput,
152
158
  state_save: Callable,
@@ -174,10 +180,13 @@ class BaseCover(BaseCoverABC, BasicMqtt):
174
180
  self._last_operation = CLOSING
175
181
  _LOGGER.debug(
176
182
  "BaseCover %s initialized: open_time=%dms, close_time=%dms, initial_position=%d%%",
177
- id, self._open_time, self._close_time, position
183
+ id,
184
+ self._open_time,
185
+ self._close_time,
186
+ position,
178
187
  )
179
188
 
180
- self._last_timestamp = time.monotonic()
189
+ self._last_timestamp = time.time()
181
190
 
182
191
  self._last_update_time = 0
183
192
  self._closed = position <= 0
@@ -187,17 +196,8 @@ class BaseCover(BaseCoverABC, BasicMqtt):
187
196
 
188
197
  self._event_bus.add_sigterm_listener(self.on_exit)
189
198
 
190
- try:
191
- self._loop.call_soon_threadsafe(
192
- self._loop.call_later,
193
- 0.5,
194
- self.send_state,
195
- self.state,
196
- self.json_position
197
- )
198
- except RuntimeError:
199
- # Event loop is closed (e.g. during tests)
200
- pass
199
+ with suppress(RuntimeError):
200
+ self._loop.call_soon_threadsafe(self._loop.call_later, 0.5, self.send_state, self.state, self.json_position)
201
201
 
202
202
  async def on_exit(self) -> None:
203
203
  """Stop on exit."""
@@ -210,12 +210,9 @@ class BaseCover(BaseCoverABC, BasicMqtt):
210
210
  self._open_relay.turn_off()
211
211
  self._close_relay.turn_off()
212
212
  # Send relay states to WebSocket (not MQTT - that's handled by output_type check)
213
- try:
213
+ with suppress(RuntimeError):
214
214
  asyncio.create_task(self._open_relay.async_send_state())
215
215
  asyncio.create_task(self._close_relay.async_send_state())
216
- except RuntimeError:
217
- # Event loop is closed (e.g. during tests or shutdown)
218
- pass
219
216
  if self._current_operation in (OPENING, CLOSING):
220
217
  self._last_operation = self._current_operation
221
218
  self._current_operation = IDLE
@@ -228,7 +225,10 @@ class BaseCover(BaseCoverABC, BasicMqtt):
228
225
  estimated_time_s = (100 - self._position) / 100 * self._open_time / 1000
229
226
  _LOGGER.info(
230
227
  "Opening cover %s from position %d%%. Estimated time: %.1fs (open_time=%dms)",
231
- self._id, self._position, estimated_time_s, self._open_time
228
+ self._id,
229
+ self._position,
230
+ estimated_time_s,
231
+ self._open_time,
232
232
  )
233
233
  self._last_operation = OPENING
234
234
  await self.run_cover(current_operation=OPENING)
@@ -240,7 +240,10 @@ class BaseCover(BaseCoverABC, BasicMqtt):
240
240
  estimated_time_s = self._position / 100 * self._close_time / 1000
241
241
  _LOGGER.info(
242
242
  "Closing cover %s from position %d%%. Estimated time: %.1fs (close_time=%dms)",
243
- self._id, self._position, estimated_time_s, self._close_time
243
+ self._id,
244
+ self._position,
245
+ estimated_time_s,
246
+ self._close_time,
244
247
  )
245
248
  self._last_operation = CLOSING
246
249
  await self.run_cover(current_operation=CLOSING)
@@ -258,14 +261,22 @@ class BaseCover(BaseCoverABC, BasicMqtt):
258
261
  estimated_time_s = position_diff / 100 * self._open_time / 1000
259
262
  _LOGGER.info(
260
263
  "Setting cover %s position from %d%% to %d%% (OPENING). Estimated time: %.1fs (open_time=%dms)",
261
- self._id, self._position, position, estimated_time_s, self._open_time
264
+ self._id,
265
+ self._position,
266
+ position,
267
+ estimated_time_s,
268
+ self._open_time,
262
269
  )
263
270
  await self.run_cover(current_operation=OPENING, target_position=position)
264
271
  elif position < self._position:
265
272
  estimated_time_s = position_diff / 100 * self._close_time / 1000
266
273
  _LOGGER.info(
267
274
  "Setting cover %s position from %d%% to %d%% (CLOSING). Estimated time: %.1fs (close_time=%dms)",
268
- self._id, self._position, position, estimated_time_s, self._close_time
275
+ self._id,
276
+ self._position,
277
+ position,
278
+ estimated_time_s,
279
+ self._close_time,
269
280
  )
270
281
  await self.run_cover(current_operation=CLOSING, target_position=position)
271
282
 
@@ -307,7 +318,9 @@ class BaseCover(BaseCoverABC, BasicMqtt):
307
318
  """
308
319
  _LOGGER.debug(
309
320
  "Smart toggle cover %s (position=%d%%, threshold=%d%%)",
310
- self._id, self._position, always_open_till,
321
+ self._id,
322
+ self._position,
323
+ always_open_till,
311
324
  )
312
325
  if self._current_operation != IDLE:
313
326
  await self.stop()
@@ -332,10 +345,10 @@ class BaseCover(BaseCoverABC, BasicMqtt):
332
345
  @property
333
346
  def is_open(self) -> bool:
334
347
  """Whether the cover is currently open (position > 0).
335
-
348
+
336
349
  Used by the action conditions system to evaluate ``is_open`` / ``is_closed``
337
350
  checks for covers.
338
-
351
+
339
352
  Returns:
340
353
  True if the cover is not fully closed.
341
354
  """
@@ -365,15 +378,12 @@ class BaseCover(BaseCoverABC, BasicMqtt):
365
378
  kind=self.kind,
366
379
  timestamp=self._last_timestamp,
367
380
  current_operation=self._current_operation,
368
- **json_position
381
+ **json_position,
369
382
  )
370
- self._event_bus.trigger_event(CoverEvent(
371
- entity_id=self.id,
372
- state=event
373
- ))
383
+ self._event_bus.trigger_event(CoverEvent(entity_id=self.id, state=event))
374
384
  self._message_bus.send_message(topic=f"{self._send_topic}/state", payload=state)
375
385
  self._message_bus.send_message(topic=f"{self._send_topic}/pos", payload=json.dumps(json_position))
376
386
 
377
387
  def send_state_and_save(self, json_position: PositionDict):
378
388
  self.send_state(self.state, json_position)
379
- self._state_save(json_position)
389
+ self._state_save(json_position)