boneIO 0.8.0.dev5__tar.gz → 0.8.0.dev7__tar.gz

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 (98) hide show
  1. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/PKG-INFO +1 -1
  2. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/group/output.py +40 -11
  3. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/helper/events.py +13 -9
  4. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/helper/loader.py +2 -1
  5. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/helper/stats.py +68 -22
  6. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/input/gpio.py +13 -3
  7. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/manager.py +1 -1
  8. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/modbus/client.py +24 -24
  9. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/modbus/modbuscli.py +2 -2
  10. boneIO-0.8.0.dev7/boneio/modbus/orno-or-we-517.json +36 -0
  11. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/modbus/sensor.py +5 -2
  12. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/schema/schema.yaml +6 -0
  13. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/sensor/ina219.py +18 -11
  14. boneIO-0.8.0.dev7/boneio/version.py +2 -0
  15. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/pyproject.toml +1 -1
  16. boneIO-0.8.0.dev5/boneio/modbus/orno-or-we-517.json +0 -20
  17. boneIO-0.8.0.dev5/boneio/version.py +0 -2
  18. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/LICENSE +0 -0
  19. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/README.md +0 -0
  20. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/__init__.py +0 -0
  21. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/bonecli.py +0 -0
  22. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/const.py +0 -0
  23. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/cover.py +0 -0
  24. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/example_config/__init__.py +0 -0
  25. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/example_config/adc.yaml +0 -0
  26. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/example_config/binary_sensor.yaml +0 -0
  27. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/example_config/config.yaml +0 -0
  28. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/example_config/cover.yaml +0 -0
  29. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/example_config/event.yaml +0 -0
  30. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/example_config/event_all.yaml +0 -0
  31. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/example_config/led32x4A.yaml +0 -0
  32. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/example_config/output24x16A.yaml +0 -0
  33. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/example_config/output24x16A_v0.3.yaml +0 -0
  34. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/example_config/output32x5A.yaml +0 -0
  35. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/fonts/danube__.ttf +0 -0
  36. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/group/__init__.py +0 -0
  37. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/helper/__init__.py +0 -0
  38. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/helper/async_updater.py +0 -0
  39. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/helper/click_timer.py +0 -0
  40. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/helper/config.py +0 -0
  41. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/helper/exceptions.py +0 -0
  42. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/helper/filter.py +0 -0
  43. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/helper/gpio.py +0 -0
  44. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/helper/ha_discovery.py +0 -0
  45. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/helper/logger.py +0 -0
  46. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/helper/mqtt.py +0 -0
  47. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/helper/oled.py +0 -0
  48. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/helper/onewire/W1ThermSensor.py +0 -0
  49. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/helper/onewire/__init__.py +0 -0
  50. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/helper/onewire/ds2482.py +0 -0
  51. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/helper/onewire/onewire.py +0 -0
  52. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/helper/pcf8575.py +0 -0
  53. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/helper/queue.py +0 -0
  54. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/helper/sensor/ina_219_smbus.py +0 -0
  55. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/helper/state_manager.py +0 -0
  56. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/helper/timeperiod.py +0 -0
  57. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/helper/util.py +0 -0
  58. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/helper/yaml_util.py +0 -0
  59. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/input/__init__.py +0 -0
  60. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/input/gpio_new.py +0 -0
  61. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/modbus/__init__.py +0 -0
  62. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/modbus/cwt.json +0 -0
  63. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/modbus/dts1964_3f.json +0 -0
  64. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/modbus/pt100.json +0 -0
  65. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/modbus/r4dcb08.json +0 -0
  66. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/modbus/sdm120.json +0 -0
  67. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/modbus/sdm630.json +0 -0
  68. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/modbus/socomec_e23.json +0 -0
  69. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/modbus/sofar.json +0 -0
  70. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/modbus/utils.py +0 -0
  71. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/mqtt_client.py +0 -0
  72. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/oled.py +0 -0
  73. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/relay/__init__.py +0 -0
  74. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/relay/basic.py +0 -0
  75. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/relay/gpio.py +0 -0
  76. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/relay/mcp.py +0 -0
  77. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/relay/pca.py +0 -0
  78. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/relay/pcf.py +0 -0
  79. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/runner.py +0 -0
  80. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/schema/actions.yaml +0 -0
  81. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/schema/actions_sensor.yaml +0 -0
  82. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/schema/actions_switch.yaml +0 -0
  83. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/schema/filters.yaml +0 -0
  84. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/schema/filters_adc.yaml +0 -0
  85. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/schema/id.yaml +0 -0
  86. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/schema/temp_unit.yaml +0 -0
  87. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/schema/update_interval.yaml +0 -0
  88. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/sensor/__init__.py +0 -0
  89. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/sensor/adc.py +0 -0
  90. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/sensor/gpio.py +0 -0
  91. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/sensor/gpio_new.py +0 -0
  92. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/sensor/temp/__init__.py +0 -0
  93. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/sensor/temp/dallas.py +0 -0
  94. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/sensor/temp/lm75.py +0 -0
  95. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/boneio/sensor/temp/mcp9808.py +0 -0
  96. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/tests/32_5_config.yaml +0 -0
  97. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/tests/bandit.yaml +0 -0
  98. {boneIO-0.8.0.dev5 → boneIO-0.8.0.dev7}/tests/relay_32_5.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: boneIO
3
- Version: 0.8.0.dev5
3
+ Version: 0.8.0.dev7
4
4
  Summary: Python App for BoneIO
5
5
  License: GNU General Public License v3.0
6
6
  Author-email: Paweł Szafer <pszafer@gmail.com>
@@ -1,4 +1,5 @@
1
1
  """Group output module."""
2
+
2
3
  from __future__ import annotations
3
4
  import asyncio
4
5
  from typing import List
@@ -13,26 +14,46 @@ class OutputGroup(BasicRelay):
13
14
  self,
14
15
  members: List[BasicRelay],
15
16
  output_type: str = SWITCH,
16
- restored_state: bool = True,
17
+ restored_state: bool = False,
18
+ all_on_behaviour: bool = False,
17
19
  **kwargs,
18
20
  ) -> None:
19
21
  """Initialize cover class."""
20
22
  self._loop = asyncio.get_event_loop()
21
23
  super().__init__(
22
- **kwargs, output_type=output_type, restored_state=restored_state, topic_type="group"
24
+ **kwargs,
25
+ output_type=output_type,
26
+ restored_state=False,
27
+ topic_type="group",
23
28
  )
29
+ self._all_on_behaviour = all_on_behaviour
24
30
  self._group_members = [x for x in members if x.output_type != COVER]
25
31
  self._timer_handle = None
32
+ self.check_state()
33
+
26
34
  for member in self._group_members:
27
- self._event_bus.add_output_listener(member.id, self.event_listener)
35
+ self._event_bus.add_output_listener(
36
+ output_id=member.id,
37
+ group_id=self.id,
38
+ target=self.event_listener,
39
+ )
28
40
 
29
- async def event_listener(self, relay_id=None) -> None:
30
- """Listen for events called by children relays."""
31
- state = OFF
41
+ def check_state(self) -> None:
32
42
  for x in self._group_members:
33
43
  if x.state == ON:
34
- state = ON
35
- break
44
+ self._state = ON
45
+ return
46
+
47
+ async def event_listener(self, relay_id=None) -> None:
48
+ """Listen for events called by children relays."""
49
+ if self._all_on_behaviour:
50
+ state = (
51
+ ON if all(x.state == ON for x in self._group_members) else OFF
52
+ )
53
+ else:
54
+ state = (
55
+ ON if any(x.state == ON for x in self._group_members) else OFF
56
+ )
36
57
  if state != self._state or not relay_id:
37
58
  self._state = state
38
59
  self._loop.call_soon_threadsafe(self.send_state)
@@ -40,13 +61,19 @@ class OutputGroup(BasicRelay):
40
61
  async def async_turn_on(self) -> None:
41
62
  """Call turn on action."""
42
63
  await asyncio.gather(
43
- *[self._loop.run_in_executor(self.executor, x.turn_on) for x in self._group_members]
64
+ *[
65
+ self._loop.run_in_executor(self.executor, x.turn_on)
66
+ for x in self._group_members
67
+ ]
44
68
  )
45
69
 
46
70
  async def async_turn_off(self) -> None:
47
71
  """Call turn off action."""
48
72
  await asyncio.gather(
49
- *[self._loop.run_in_executor(self.executor, x.turn_off) for x in self._group_members]
73
+ *[
74
+ self._loop.run_in_executor(self.executor, x.turn_off)
75
+ for x in self._group_members
76
+ ]
50
77
  )
51
78
 
52
79
  @property
@@ -56,4 +83,6 @@ class OutputGroup(BasicRelay):
56
83
 
57
84
  def send_state(self) -> None:
58
85
  """Send state to Mqtt on action."""
59
- self._send_message(topic=self._send_topic, payload=self.payload(), retain=True)
86
+ self._send_message(
87
+ topic=self._send_topic, payload=self.payload(), retain=True
88
+ )
@@ -4,7 +4,7 @@ import logging
4
4
  import signal
5
5
  import time
6
6
  from datetime import datetime
7
- from typing import Any, Coroutine, List, Optional, Callable, Optional
7
+ from typing import Any, Coroutine, List, Optional, Callable
8
8
 
9
9
 
10
10
  from boneio.helper.util import callback
@@ -85,7 +85,9 @@ class EventBus:
85
85
  self._output_listeners = {}
86
86
  self._sigterm_listeners = []
87
87
  self._haonline_listeners = []
88
- self._timer_handle = _async_create_timer(self._loop, self._run_second_event)
88
+ self._timer_handle = _async_create_timer(
89
+ self._loop, self._run_second_event
90
+ )
89
91
  for signame in {"SIGINT", "SIGTERM"}:
90
92
  self._loop.add_signal_handler(
91
93
  getattr(signal, signame),
@@ -121,17 +123,19 @@ class EventBus:
121
123
  """Add sigterm listener."""
122
124
  self._sigterm_listeners.append(target)
123
125
 
124
- def add_output_listener(self, name, target):
126
+ def add_output_listener(self, output_id, group_id, target):
125
127
  """Add output listener."""
126
- self._output_listeners[name] = ListenerJob(target=target)
127
- return self._output_listeners[name]
128
-
128
+ if output_id not in self._output_listeners:
129
+ self._output_listeners[output_id] = {}
130
+ self._output_listeners[output_id][group_id] = ListenerJob(target=target)
131
+ return self._output_listeners[output_id]
132
+
129
133
  def trigger_output_event(self, event):
130
134
  asyncio.create_task(self.async_trigger_output_event(event=event))
131
-
135
+
132
136
  async def async_trigger_output_event(self, event):
133
- listener = self._output_listeners.get(event)
134
- if listener:
137
+ listeners = self._output_listeners.get(event, {})
138
+ for listener in listeners.values():
135
139
  await listener.target(event)
136
140
 
137
141
  def add_haonline_listener(self, target):
@@ -15,7 +15,6 @@ from boneio.const import (
15
15
  DEVICE_CLASS,
16
16
  FILTERS,
17
17
  GPIO,
18
- PCA,
19
18
  ID,
20
19
  INIT_SLEEP,
21
20
  INPUT,
@@ -135,6 +134,8 @@ def create_temp_sensor(
135
134
  else:
136
135
  return
137
136
  name = config.get(ID)
137
+ if not name:
138
+ return
138
139
  id = name.replace(" ", "")
139
140
  try:
140
141
  temp_sensor = TempSensor(
@@ -63,7 +63,7 @@ def get_network_info():
63
63
  for addr in addrs:
64
64
  if addr.family == socket.AF_INET:
65
65
  out["ip"] = addr.address
66
- out["mask"] = addr.netmask
66
+ out["mask"] = addr.netmask if addr.netmask is not None else ""
67
67
  elif addr.family == psutil.AF_LINK:
68
68
  out["mac"] = addr.address
69
69
  return out
@@ -139,7 +139,9 @@ class HostSensor(AsyncUpdater):
139
139
 
140
140
  async def async_update(self, time: datetime) -> None:
141
141
  self._state = self._update_function()
142
- self._loop.call_soon_threadsafe(partial(self._manager_callback, self._type))
142
+ self._loop.call_soon_threadsafe(
143
+ partial(self._manager_callback, self._type)
144
+ )
143
145
 
144
146
  @property
145
147
  def state(self) -> dict:
@@ -155,7 +157,7 @@ class HostData:
155
157
  self,
156
158
  output: dict,
157
159
  callback: Callable,
158
- temp_sensor: Callable[[LM75Sensor, MCP9808Sensor], None],
160
+ temp_sensor: Callable[[LM75Sensor, MCP9808Sensor], None] | None,
159
161
  ina219: INA219Class | None,
160
162
  manager: Manager,
161
163
  enabled_screens: List[str],
@@ -164,27 +166,68 @@ class HostData:
164
166
  self._hostname = socket.gethostname()
165
167
  self._temp_sensor = temp_sensor
166
168
  host_stats = {
167
- NETWORK: {"f": get_network_info, "update_interval": TimePeriod(seconds=60)},
169
+ NETWORK: {
170
+ "f": get_network_info,
171
+ "update_interval": TimePeriod(seconds=60),
172
+ },
168
173
  CPU: {"f": get_cpu_info, "update_interval": TimePeriod(seconds=5)},
169
- DISK: {"f": get_disk_info, "update_interval": TimePeriod(seconds=60)},
170
- MEMORY: {"f": get_memory_info, "update_interval": TimePeriod(seconds=10)},
171
- SWAP: {"f": get_swap_info, "update_interval": TimePeriod(seconds=60)},
174
+ DISK: {
175
+ "f": get_disk_info,
176
+ "update_interval": TimePeriod(seconds=60),
177
+ },
178
+ MEMORY: {
179
+ "f": get_memory_info,
180
+ "update_interval": TimePeriod(seconds=10),
181
+ },
182
+ SWAP: {
183
+ "f": get_swap_info,
184
+ "update_interval": TimePeriod(seconds=60),
185
+ },
172
186
  UPTIME: {
173
- "f": lambda: {
174
- "uptime": {"data": get_uptime(), "fontSize": "small", "row": 2, "col": 3},
175
- "MQTT": {"data": "CONN" if manager.mqtt_state else "DOWN", "fontSize": "small", "row": 3, "col": 60},
176
- "T": {
177
- "data": f"{self._temp_sensor.state} C",
187
+ "f": lambda: (
188
+ {
189
+ "uptime": {
190
+ "data": get_uptime(),
191
+ "fontSize": "small",
192
+ "row": 2,
193
+ "col": 3,
194
+ },
195
+ "MQTT": {
196
+ "data": "CONN" if manager.mqtt_state else "DOWN",
197
+ "fontSize": "small",
198
+ "row": 3,
199
+ "col": 60,
200
+ },
201
+ "T": {
202
+ "data": f"{self._temp_sensor.state} C",
203
+ "fontSize": "small",
204
+ "row": 3,
205
+ "col": 3,
206
+ },
207
+ }
208
+ if self._temp_sensor
209
+ else {
210
+ "uptime": {
211
+ "data": get_uptime(),
212
+ "fontSize": "small",
213
+ "row": 2,
214
+ "col": 3,
215
+ }
216
+ }
217
+ ),
218
+ "static": {
219
+ HOST: {
220
+ "data": self._hostname,
178
221
  "fontSize": "small",
179
- "row": 3,
180
- "col": 3
222
+ "row": 0,
223
+ "col": 3,
224
+ },
225
+ "ver": {
226
+ "data": __version__,
227
+ "fontSize": "small",
228
+ "row": 1,
229
+ "col": 3,
181
230
  },
182
- }
183
- if self._temp_sensor
184
- else {"uptime": {"data": get_uptime(), "fontSize": "small", "row": 2, "col": 3}},
185
- "static": {
186
- HOST: {"data": self._hostname, "fontSize": "small", "row": 0, "col": 3},
187
- "ver": {"data": __version__, "fontSize": "small", "row": 1, "col": 3},
188
231
  },
189
232
  "update_interval": TimePeriod(seconds=30),
190
233
  },
@@ -192,9 +235,12 @@ class HostData:
192
235
  if ina219 is not None:
193
236
  host_stats[INA219] = {
194
237
  "f": lambda: {
195
- *{sensor.device_class: sensor.state for sensor in ina219.sensors}
238
+ *{
239
+ sensor.device_class: sensor.state
240
+ for sensor in ina219.sensors.values()
241
+ }
196
242
  },
197
- "update_interval": TimePeriod(seconds=60)
243
+ "update_interval": TimePeriod(seconds=60),
198
244
  }
199
245
  self._data = {}
200
246
  for k, _v in host_stats.items():
@@ -1,4 +1,5 @@
1
1
  """GpioEventButton to receive signals."""
2
+
2
3
  from __future__ import annotations
3
4
  import logging
4
5
  import asyncio
@@ -39,6 +40,12 @@ class GpioEventButton(GpioBaseClass):
39
40
  self._is_waiting_for_second_click = False
40
41
  if not self._state and not self._timer_long.is_waiting():
41
42
  self.press_callback(click_type=SINGLE, duration=None)
43
+ else:
44
+ _LOGGER.error(
45
+ "Thats why it's not working %s %s",
46
+ self._state,
47
+ self._timer_long.is_waiting(),
48
+ )
42
49
 
43
50
  async def _run(self) -> None:
44
51
  while True:
@@ -49,7 +56,7 @@ class GpioEventButton(GpioBaseClass):
49
56
  if state == self._state:
50
57
  return
51
58
  self._state = state
52
- if state: #is pressed?
59
+ if state: # is pressed?
53
60
  self._timer_long.start_timer()
54
61
  if self._timer_double.is_waiting():
55
62
  self._timer_double.reset()
@@ -59,8 +66,11 @@ class GpioEventButton(GpioBaseClass):
59
66
  self._timer_double.start_timer()
60
67
  self._is_waiting_for_second_click = True
61
68
 
62
- else: #is released?
63
- if not self._is_waiting_for_second_click and not self._double_click_ran:
69
+ else: # is released?
70
+ if (
71
+ not self._is_waiting_for_second_click
72
+ and not self._double_click_ran
73
+ ):
64
74
  if self._timer_long.is_waiting():
65
75
  self.press_callback(click_type=SINGLE, duration=None)
66
76
  self._timer_long.reset()
@@ -299,7 +299,7 @@ class Manager:
299
299
  if x in self._output:
300
300
  output = self._output[x]
301
301
  if output.output_type == COVER:
302
- _LOGGER.warn("You can't add cover output to group.")
302
+ _LOGGER.warning("You can't add cover output to group.")
303
303
  else:
304
304
  outputs.append(output)
305
305
  return outputs
@@ -101,51 +101,51 @@ class Modbus:
101
101
  _LOGGER.error(exception_error)
102
102
  return False
103
103
 
104
- async def read_single_register(
104
+ async def read_and_decode(
105
105
  self,
106
106
  unit: int | str,
107
107
  address: int,
108
+ payload_type: str,
108
109
  count: int = 2,
109
110
  method: str = "input",
110
111
  ) -> float | None:
111
- """Call sync. pymodbus."""
112
- async with self._lock:
113
- if not self._pymodbus_connect():
114
- _LOGGER.error("Can't connect to Modbus address %s.", address)
115
- return None
116
- kwargs = {"unit": unit, "count": count} if unit else {}
117
- try:
118
- result: ReadInputRegistersResponse = self._read_methods[method](
119
- address, **kwargs
120
- )
121
- except (ModbusException, struct.error) as exception_error:
122
- _LOGGER.error(exception_error)
123
- return None
124
- if not hasattr(result, REGISTERS):
125
- _LOGGER.error(str(result))
126
- return None
127
- return BinaryPayloadDecoder.fromRegisters(
128
- result.registers, byteorder=Endian.Big, wordorder=Endian.Big
129
- ).decode_32bit_float()
112
+ """Call read_registers and decode."""
113
+ result = await self.read_registers(
114
+ unit=unit, address=address, count=count, method=method
115
+ )
116
+ if not result or result.isError():
117
+ return None
118
+ decoded_value = self.decode_value(
119
+ payload=result.registers, value_type=payload_type
120
+ )
121
+ return decoded_value
130
122
 
131
- async def read_multiple_registers(
123
+ async def read_registers(
132
124
  self,
133
125
  unit: int | str, # device address
134
126
  address: int, # modbus register address
135
127
  count: int = 2, # number of registers to read
136
128
  method: str = "input", # type of register: input, holding
137
129
  ) -> ModbusResponse:
138
- """Call sync. pymodbus."""
130
+ """Call async pymodbus."""
139
131
  async with self._lock:
140
132
  if not self._pymodbus_connect():
141
133
  _LOGGER.error("Can't connect to Modbus.")
142
134
  return None
143
135
  kwargs = {"unit": unit, "count": count} if unit else {}
144
136
  try:
145
- result: ReadInputRegistersResponse = self._read_methods[method](
137
+ read_method = self._read_methods[method]
138
+ _LOGGER.debug(
139
+ "Reading %s registers from %s with method %s from device %s.",
140
+ count,
141
+ address,
142
+ method,
143
+ unit,
144
+ )
145
+ result: ReadInputRegistersResponse = read_method(
146
146
  address, **kwargs
147
147
  )
148
- except ModbusException as exception_error:
148
+ except (ModbusException, struct.error) as exception_error:
149
149
  _LOGGER.error(exception_error)
150
150
  return None
151
151
  if not hasattr(result, REGISTERS):
@@ -53,7 +53,7 @@ class ModbusHelper:
53
53
  f"Checking connection {self._device_address}, address {address}."
54
54
  )
55
55
  count = 1 if value_type == "S_WORD" or value_type == "U_WORD" else 2
56
- value = await self._modbus.read_multiple_registers(
56
+ value = await self._modbus.read_registers(
57
57
  unit=self._device_address,
58
58
  address=address,
59
59
  count=count,
@@ -180,7 +180,7 @@ async def async_run_modbus_get(
180
180
  parity=parity,
181
181
  )
182
182
  count = 1 if value_type == "S_WORD" or value_type == "U_WORD" else 2
183
- value = await _modbus.read_multiple_registers(
183
+ value = await _modbus.read_registers(
184
184
  unit=device_address,
185
185
  address=register_address,
186
186
  count=count,
@@ -0,0 +1,36 @@
1
+ {
2
+ "model": "orno-or-we-517",
3
+ "registers_base": [
4
+ {
5
+ "base": 14,
6
+ "length": 6,
7
+ "register_type": "holding",
8
+ "registers": [
9
+ {
10
+ "name": "Voltage_L1",
11
+ "address": 14,
12
+ "unit_of_measurement": "V",
13
+ "state_class": "measurement",
14
+ "device_class": "voltage",
15
+ "value_type": "FP32"
16
+ },
17
+ {
18
+ "name": "Voltage_L2",
19
+ "address": 16,
20
+ "unit_of_measurement": "V",
21
+ "state_class": "measurement",
22
+ "device_class": "voltage",
23
+ "value_type": "FP32"
24
+ },
25
+ {
26
+ "name": "Voltage_L3",
27
+ "address": 18,
28
+ "unit_of_measurement": "V",
29
+ "state_class": "measurement",
30
+ "device_class": "voltage",
31
+ "value_type": "FP32"
32
+ }
33
+ ]
34
+ }
35
+ ]
36
+ }
@@ -122,10 +122,13 @@ class ModbusSensor(BasicMqtt, AsyncUpdater):
122
122
  register_method = first_register_base.get("register_type", "input")
123
123
  # Let's try fetch register 2 times in case something wrong with initial packet.
124
124
  for _ in [0, 1]:
125
- register = await self._modbus.read_single_register(
125
+ register = await self._modbus.read_and_decode(
126
126
  unit=self._address,
127
127
  address=first_register_base[REGISTERS][0][ADDRESS],
128
128
  method=register_method,
129
+ payload_type=first_register_base[REGISTERS][0].get(
130
+ "value_type", "FP32"
131
+ ),
129
132
  )
130
133
  if register is not None:
131
134
  self._discovery_sent = (
@@ -144,7 +147,7 @@ class ModbusSensor(BasicMqtt, AsyncUpdater):
144
147
  update_interval = self._update_interval.total_in_seconds
145
148
  await self.check_availability()
146
149
  for data in self._db[REGISTERS_BASE]:
147
- values = await self._modbus.read_multiple_registers(
150
+ values = await self._modbus.read_registers(
148
151
  unit=self._address,
149
152
  address=data[BASE],
150
153
  count=data[LENGTH],
@@ -432,6 +432,12 @@ output_group:
432
432
  required: True
433
433
  meta:
434
434
  label: List of outputs.
435
+ all_on_behaviour:
436
+ type: boolean
437
+ required: True
438
+ default: False
439
+ meta:
440
+ label: Behaviour if set true toggle when all outputs are on, otherwise if any is on then group is on.
435
441
  output_type:
436
442
  type: string
437
443
  required: True
@@ -1,4 +1,5 @@
1
1
  """INA219 Black sensor."""
2
+
2
3
  from __future__ import annotations
3
4
  from datetime import datetime
4
5
  import logging
@@ -10,24 +11,24 @@ from boneio.helper.sensor.ina_219_smbus import INA219_I2C
10
11
 
11
12
  _LOGGER = logging.getLogger(__name__)
12
13
 
13
- unit_converter = {
14
- "current": "A",
15
- "power": "W",
16
- "voltage": "V"
17
- }
14
+ unit_converter = {"current": "A", "power": "W", "voltage": "V"}
18
15
 
19
16
 
20
17
  class INA219Sensor(BasicMqtt, Filter):
21
18
  """Represent singel value from INA219 as sensor."""
22
19
 
23
- def __init__(self, device_class: str, filters: list, state: float | None, **kwargs) -> None:
20
+ def __init__(
21
+ self, device_class: str, filters: list, state: float | None, **kwargs
22
+ ) -> None:
24
23
  super().__init__(topic_type=SENSOR, **kwargs)
25
24
  self._unit_of_measurement = unit_converter[device_class]
26
25
  self._device_class = device_class
27
26
  self._filters = filters
28
27
  self._raw_state = state
29
28
  self._state = (
30
- self._apply_filters(value=self._raw_state) if self._raw_state else None
29
+ self._apply_filters(value=self._raw_state)
30
+ if self._raw_state
31
+ else None
31
32
  )
32
33
 
33
34
  @property
@@ -41,18 +42,22 @@ class INA219Sensor(BasicMqtt, Filter):
41
42
  @property
42
43
  def state(self) -> float | None:
43
44
  return self._state
44
-
45
+
45
46
  @property
46
47
  def device_class(self) -> str:
47
48
  return self._device_class
48
-
49
+
49
50
  @property
50
51
  def unit_of_measurement(self) -> str:
51
52
  return self._unit_of_measurement
52
53
 
53
54
  def update(self, time: datetime) -> None:
54
55
  """Fetch temperature periodically and send to MQTT."""
55
- _state = self._apply_filters(value=self._raw_state) if self._raw_state else None
56
+ _state = (
57
+ self._apply_filters(value=self._raw_state)
58
+ if self._raw_state
59
+ else None
60
+ )
56
61
  if not _state:
57
62
  return
58
63
  self._state = _state
@@ -65,7 +70,9 @@ class INA219Sensor(BasicMqtt, Filter):
65
70
  class INA219(AsyncUpdater, Filter):
66
71
  """Represent INA219 sensors."""
67
72
 
68
- def __init__(self, address: int, id: str, sensors: list[dict] = [], **kwargs) -> None:
73
+ def __init__(
74
+ self, address: int, id: str, sensors: list[dict] = [], **kwargs
75
+ ) -> None:
69
76
  """Setup GPIO ADC Sensor"""
70
77
  self._loop = asyncio.get_event_loop()
71
78
  self._ina_219 = INA219_I2C(address=address)
@@ -0,0 +1,2 @@
1
+ # flake8: noqa
2
+ __version__ = "0.8.0dev7"
@@ -30,7 +30,7 @@ dependencies = [
30
30
  "Adafruit-BBIO>=1.2.0",
31
31
  ]
32
32
  requires-python = ">=3.7"
33
- version = "0.8.0.dev5"
33
+ version = "0.8.0.dev7"
34
34
 
35
35
  [project.license]
36
36
  text = "GNU General Public License v3.0"
@@ -1,20 +0,0 @@
1
- {
2
- "model": "orno-or-we-517",
3
- "registers_base": [
4
- {
5
- "base": 14,
6
- "length": 4,
7
- "register_type": "holding",
8
- "registers": [
9
- {
10
- "name": "Napiecie_L1",
11
- "address": 14,
12
- "unit_of_measurement": "V",
13
- "state_class": "measurement",
14
- "device_class": "voltage",
15
- "return_type": "float32"
16
- }
17
- ]
18
- }
19
- ]
20
- }
@@ -1,2 +0,0 @@
1
- # flake8: noqa
2
- __version__ = "0.8.0dev5"
File without changes
File without changes
File without changes
File without changes
File without changes