boneIO 0.8.0.dev6__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.
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/PKG-INFO +1 -1
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/group/output.py +40 -11
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/helper/events.py +13 -9
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/helper/loader.py +2 -1
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/helper/stats.py +68 -22
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/input/gpio.py +13 -3
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/manager.py +1 -1
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/modbus/client.py +3 -3
- boneIO-0.8.0.dev7/boneio/modbus/orno-or-we-517.json +36 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/schema/schema.yaml +6 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/sensor/ina219.py +18 -11
- boneIO-0.8.0.dev7/boneio/version.py +2 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/pyproject.toml +1 -1
- boneIO-0.8.0.dev6/boneio/modbus/orno-or-we-517.json +0 -20
- boneIO-0.8.0.dev6/boneio/version.py +0 -2
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/LICENSE +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/README.md +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/__init__.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/bonecli.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/const.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/cover.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/example_config/__init__.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/example_config/adc.yaml +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/example_config/binary_sensor.yaml +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/example_config/config.yaml +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/example_config/cover.yaml +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/example_config/event.yaml +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/example_config/event_all.yaml +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/example_config/led32x4A.yaml +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/example_config/output24x16A.yaml +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/example_config/output24x16A_v0.3.yaml +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/example_config/output32x5A.yaml +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/fonts/danube__.ttf +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/group/__init__.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/helper/__init__.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/helper/async_updater.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/helper/click_timer.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/helper/config.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/helper/exceptions.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/helper/filter.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/helper/gpio.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/helper/ha_discovery.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/helper/logger.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/helper/mqtt.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/helper/oled.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/helper/onewire/W1ThermSensor.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/helper/onewire/__init__.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/helper/onewire/ds2482.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/helper/onewire/onewire.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/helper/pcf8575.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/helper/queue.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/helper/sensor/ina_219_smbus.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/helper/state_manager.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/helper/timeperiod.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/helper/util.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/helper/yaml_util.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/input/__init__.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/input/gpio_new.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/modbus/__init__.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/modbus/cwt.json +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/modbus/dts1964_3f.json +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/modbus/modbuscli.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/modbus/pt100.json +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/modbus/r4dcb08.json +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/modbus/sdm120.json +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/modbus/sdm630.json +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/modbus/sensor.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/modbus/socomec_e23.json +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/modbus/sofar.json +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/modbus/utils.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/mqtt_client.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/oled.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/relay/__init__.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/relay/basic.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/relay/gpio.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/relay/mcp.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/relay/pca.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/relay/pcf.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/runner.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/schema/actions.yaml +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/schema/actions_sensor.yaml +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/schema/actions_switch.yaml +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/schema/filters.yaml +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/schema/filters_adc.yaml +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/schema/id.yaml +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/schema/temp_unit.yaml +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/schema/update_interval.yaml +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/sensor/__init__.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/sensor/adc.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/sensor/gpio.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/sensor/gpio_new.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/sensor/temp/__init__.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/sensor/temp/dallas.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/sensor/temp/lm75.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/boneio/sensor/temp/mcp9808.py +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/tests/32_5_config.yaml +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/tests/bandit.yaml +0 -0
- {boneIO-0.8.0.dev6 → boneIO-0.8.0.dev7}/tests/relay_32_5.py +0 -0
|
@@ -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 =
|
|
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,
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
35
|
-
|
|
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
|
-
*[
|
|
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
|
-
*[
|
|
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(
|
|
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
|
|
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(
|
|
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,
|
|
126
|
+
def add_output_listener(self, output_id, group_id, target):
|
|
125
127
|
"""Add output listener."""
|
|
126
|
-
self._output_listeners
|
|
127
|
-
|
|
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
|
-
|
|
134
|
-
|
|
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(
|
|
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: {
|
|
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: {
|
|
170
|
-
|
|
171
|
-
|
|
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
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
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":
|
|
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
|
-
*{
|
|
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:
|
|
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:
|
|
63
|
-
if
|
|
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.
|
|
302
|
+
_LOGGER.warning("You can't add cover output to group.")
|
|
303
303
|
else:
|
|
304
304
|
outputs.append(output)
|
|
305
305
|
return outputs
|
|
@@ -109,7 +109,7 @@ class Modbus:
|
|
|
109
109
|
count: int = 2,
|
|
110
110
|
method: str = "input",
|
|
111
111
|
) -> float | None:
|
|
112
|
-
"""Call
|
|
112
|
+
"""Call read_registers and decode."""
|
|
113
113
|
result = await self.read_registers(
|
|
114
114
|
unit=unit, address=address, count=count, method=method
|
|
115
115
|
)
|
|
@@ -127,7 +127,7 @@ class Modbus:
|
|
|
127
127
|
count: int = 2, # number of registers to read
|
|
128
128
|
method: str = "input", # type of register: input, holding
|
|
129
129
|
) -> ModbusResponse:
|
|
130
|
-
"""Call
|
|
130
|
+
"""Call async pymodbus."""
|
|
131
131
|
async with self._lock:
|
|
132
132
|
if not self._pymodbus_connect():
|
|
133
133
|
_LOGGER.error("Can't connect to Modbus.")
|
|
@@ -136,7 +136,7 @@ class Modbus:
|
|
|
136
136
|
try:
|
|
137
137
|
read_method = self._read_methods[method]
|
|
138
138
|
_LOGGER.debug(
|
|
139
|
-
"
|
|
139
|
+
"Reading %s registers from %s with method %s from device %s.",
|
|
140
140
|
count,
|
|
141
141
|
address,
|
|
142
142
|
method,
|
|
@@ -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
|
+
}
|
|
@@ -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__(
|
|
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)
|
|
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 =
|
|
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__(
|
|
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)
|
|
@@ -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
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|