boneIO 0.7.0dev3__py3-none-any.whl → 0.7.0dev6__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.
Potentially problematic release.
This version of boneIO might be problematic. Click here for more details.
- {boneIO-0.7.0.dev3.dist-info → boneIO-0.7.0.dev6.dist-info}/METADATA +1 -1
- {boneIO-0.7.0.dev3.dist-info → boneIO-0.7.0.dev6.dist-info}/RECORD +27 -25
- boneio/const.py +10 -0
- boneio/cover.py +1 -1
- boneio/group/__init__.py +4 -0
- boneio/group/output.py +64 -0
- boneio/helper/async_updater.py +1 -1
- boneio/helper/config.py +3 -0
- boneio/helper/events.py +15 -0
- boneio/helper/gpio.py +8 -0
- boneio/helper/ha_discovery.py +6 -6
- boneio/helper/loader.py +125 -56
- boneio/helper/mqtt.py +1 -1
- boneio/helper/state_manager.py +5 -0
- boneio/input/gpio.py +6 -6
- boneio/manager.py +166 -54
- boneio/mqtt_client.py +1 -1
- boneio/relay/basic.py +22 -8
- boneio/relay/mcp.py +2 -2
- boneio/relay/pca.py +2 -9
- boneio/runner.py +6 -4
- boneio/schema/actions.yaml +1 -1
- boneio/schema/schema.yaml +38 -3
- boneio/version.py +1 -1
- {boneIO-0.7.0.dev3.dist-info → boneIO-0.7.0.dev6.dist-info}/WHEEL +0 -0
- {boneIO-0.7.0.dev3.dist-info → boneIO-0.7.0.dev6.dist-info}/entry_points.txt +0 -0
- {boneIO-0.7.0.dev3.dist-info → boneIO-0.7.0.dev6.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
boneio/__init__.py,sha256=hoLKnu6h1uEsiCHA9Ql2MMDC7VQS0E-s_2cxBS-CTOg,147
|
|
2
2
|
boneio/bonecli.py,sha256=o2DWcsKqw4IJklPmbdq7bwgcISOWPZfYVAUuMltNUP0,3435
|
|
3
|
-
boneio/const.py,sha256=
|
|
4
|
-
boneio/cover.py,sha256=
|
|
3
|
+
boneio/const.py,sha256=Drge50hdQpxW7gYbYIC6DPVHHibFOKH0OAV3lWzhH-Q,3256
|
|
4
|
+
boneio/cover.py,sha256=EfO1DAOGTPQykfgJHzg1WqPs0U8b1AnD2NMI-sLZccM,8444
|
|
5
5
|
boneio/example_config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
6
|
boneio/example_config/adc_v0_4.yaml,sha256=GKNpl2t7ebsH57UhJlJioXNuBflsL6eO4JMnyYwZrFs,168
|
|
7
7
|
boneio/example_config/binary_sensor.yaml,sha256=0-KfPuACU6Q8krtNLQ_Bu8135xLEeCrs8UhGXR7kCxU,238
|
|
@@ -13,18 +13,20 @@ boneio/example_config/output24x16A.yaml,sha256=BTtHToRgz-U_rMMDbmHkM4wQxHakdzInb
|
|
|
13
13
|
boneio/example_config/output24x16A_v0.3.yaml,sha256=XkI4rHn_XdX37xG02-wHieZzSHKiKN5mtnyfRE24NII,1713
|
|
14
14
|
boneio/example_config/output32x5A.yaml,sha256=G2Pb6qL8mXs6MliIM1roAanPag9ozRe3McYYuFsiBc0,2403
|
|
15
15
|
boneio/fonts/danube__.ttf,sha256=KBRPUcGvmroCjrWC8zK4MulUb9lV8R0lXkOY7lNnQWc,19372
|
|
16
|
+
boneio/group/__init__.py,sha256=eUN51J6nU1MdQfcl6JQ2AQwkP6K91mR9caDZyZ18rig,80
|
|
17
|
+
boneio/group/output.py,sha256=byaYz1etz2LWFpRnvLMH0EpzeP5JMF_PH2W2pGDTnEY,2005
|
|
16
18
|
boneio/helper/__init__.py,sha256=zizPsGPbEtcqUsFWOxhs8s4H6PeJvJq8tP0OvCVJ_C4,2039
|
|
17
|
-
boneio/helper/async_updater.py,sha256=
|
|
19
|
+
boneio/helper/async_updater.py,sha256=K1xXpVAFeTOKfcmTGBnBgOvwZHfZQQKOWVEOnEMm0BY,993
|
|
18
20
|
boneio/helper/click_timer.py,sha256=yZ2nfnreSCBfJkkWDE_RhDfV7YHgwfoehMLh3ia2BEI,1184
|
|
19
|
-
boneio/helper/config.py,sha256=
|
|
20
|
-
boneio/helper/events.py,sha256=
|
|
21
|
+
boneio/helper/config.py,sha256=5cDnJ7usJDlUvXv8K2rSWEx30OFcU2k1U1vUEjO69WY,2431
|
|
22
|
+
boneio/helper/events.py,sha256=mK6boHpgMf3mMudnrUOesHL28udX8E2BGNwHFuEN2XA,8059
|
|
21
23
|
boneio/helper/exceptions.py,sha256=vyYSUojwB7OttOPUjbxeHFM7C_o5ZQmRUcZ_vYpxYYI,717
|
|
22
24
|
boneio/helper/filter.py,sha256=UcjifjaC5wHDW2He7wmwCX2IjSSeLVhXyhrXHeT8RmA,885
|
|
23
|
-
boneio/helper/gpio.py,sha256=
|
|
24
|
-
boneio/helper/ha_discovery.py,sha256=
|
|
25
|
-
boneio/helper/loader.py,sha256=
|
|
25
|
+
boneio/helper/gpio.py,sha256=GKSg6Ke9FSnx8P3dAr48JYrJygrez9N8Ej1W5H3WdPc,3557
|
|
26
|
+
boneio/helper/ha_discovery.py,sha256=_2ADUnqo4a2FOaTR4LDJblF2z18sioaOOnVxX5R9aQE,6437
|
|
27
|
+
boneio/helper/loader.py,sha256=a22t1Bu4I_M9Z7k_tVcABgSUBheV9cx7UtPQvfeEjjA,17577
|
|
26
28
|
boneio/helper/logger.py,sha256=zyF_Vk3o2eSHuXypJhNzK99eZgkWDWybuB5KcJgurDs,1801
|
|
27
|
-
boneio/helper/mqtt.py,sha256=
|
|
29
|
+
boneio/helper/mqtt.py,sha256=dXH87TYyDTd1MJz5zHBEJDVmrqFoL38N7uyBeyiieyY,771
|
|
28
30
|
boneio/helper/oled.py,sha256=f0XYbaFstUbJ6ISmFe1vQCnmNVMctQWtnStNdROrblc,351
|
|
29
31
|
boneio/helper/onewire/W1ThermSensor.py,sha256=Pu5Fp29pKbxjJqDbFs05Mjg3Vy-9z_DTVoBpSWM_byA,2430
|
|
30
32
|
boneio/helper/onewire/__init__.py,sha256=4djH-uxiq5XhAiFTOxyqjvWVoJe0c8U8iN0BfmH8nSU,448
|
|
@@ -32,32 +34,32 @@ boneio/helper/onewire/ds2482.py,sha256=c2t_hdAMtFsHw4Vw41QzO_hEDDNMeb3J71mEwEMUB
|
|
|
32
34
|
boneio/helper/onewire/onewire.py,sha256=tHofTu1l0qG7hH2XoSf-lj8gW7wVKe27j57qQWpVMPg,2497
|
|
33
35
|
boneio/helper/pcf8575.py,sha256=qeNYLqV5foDEQCyAz1WRQRi1CYYxtbPIha06Z5TyZVQ,311
|
|
34
36
|
boneio/helper/queue.py,sha256=7fE7d344-BEW8sljN40wmqsbBr4kPLvz4ShBjkT04p8,1066
|
|
35
|
-
boneio/helper/state_manager.py,sha256=
|
|
37
|
+
boneio/helper/state_manager.py,sha256=PiNCL_uHElVH34ztIXBgVgKnpN0Mje2pspCLBiRIsgk,2145
|
|
36
38
|
boneio/helper/stats.py,sha256=XNQDU-ixIobKQ2batzZno2UOMzNGWHSFQ-EXChNBJzM,5853
|
|
37
39
|
boneio/helper/timeperiod.py,sha256=xpg9oe30Z5WiLDQPq3EBKKScejOnN47NhcpeFvDd3bY,5806
|
|
38
40
|
boneio/helper/util.py,sha256=QfSoT3H3WnOQAKO5bFRIBCy62HT5NMa9Ek-FmfTW_rw,508
|
|
39
41
|
boneio/helper/yaml_util.py,sha256=gAX7hCaHUlPgkhGCIQ4zjv0Vj9JmLzQsSyF51ZmSb9g,11304
|
|
40
42
|
boneio/input/__init__.py,sha256=ZM6G2XX621lQUy8Tk6S8zf_jBp_NxsK6OHMMrdsOsDo,178
|
|
41
|
-
boneio/input/gpio.py,sha256=
|
|
43
|
+
boneio/input/gpio.py,sha256=j6tiZmUC934Yc_Lu8FjSNQIdRb0iJLiucJu0UuU_cAQ,2709
|
|
42
44
|
boneio/input/gpio_beta.py,sha256=ZsiY5oeSsqo-JuZ9uglwfsmJ_MySQqxuGU6PbWcO1Hw,3231
|
|
43
|
-
boneio/manager.py,sha256=
|
|
45
|
+
boneio/manager.py,sha256=rITALbKkdzkaNLdza2lw9DvtlrhrS-ydLv3W2KKTNWw,27086
|
|
44
46
|
boneio/modbus.py,sha256=eA_sGnmdcIneXX75ZcXOI223-UkKN1UYmWFqiJBAhJo,4176
|
|
45
|
-
boneio/mqtt_client.py,sha256=
|
|
47
|
+
boneio/mqtt_client.py,sha256=5_ilaYqsCIIdKjsspQxPoNkSpSuCjrwD16HTcfH0Lxk,8551
|
|
46
48
|
boneio/oled.py,sha256=d_ofDQHc7zr3j0qOR0B_L3C8TJhvRH85nnb9Le-88nk,5244
|
|
47
49
|
boneio/relay/__init__.py,sha256=Cz6D37GKHxm8DiuPuxE2EMaey2wdUdJYVet_hfR0lzA,231
|
|
48
|
-
boneio/relay/basic.py,sha256=
|
|
50
|
+
boneio/relay/basic.py,sha256=BeA4v4eq2uyMDnIvZFHBl7EIs5scJ0efJQbvZqwMstc,3276
|
|
49
51
|
boneio/relay/gpio.py,sha256=s64FBf6zlxciF57xJ6nrvy0t5Rie0uiXlwos0HL3RKM,1163
|
|
50
|
-
boneio/relay/mcp.py,sha256=
|
|
51
|
-
boneio/relay/pca.py,sha256=
|
|
52
|
+
boneio/relay/mcp.py,sha256=4NZJLVtR_f-vuwGA1vbTLqzPoEZO2_in-RJSORfwC60,2508
|
|
53
|
+
boneio/relay/pca.py,sha256=YBrClCM_dvPF92gdDmyjfGumhan0UdHWQBDv-J7DrzA,4594
|
|
52
54
|
boneio/relay/pcf.py,sha256=15uw3i3n06AfILcd6fWRgHjibKDkvRbiAntoTrlwHx4,2635
|
|
53
|
-
boneio/runner.py,sha256=
|
|
54
|
-
boneio/schema/actions.yaml,sha256=
|
|
55
|
+
boneio/runner.py,sha256=wHi1R3sI6OSBdjQ5-G44r8WGiTiTqv5n7x5aB-_GIrw,2789
|
|
56
|
+
boneio/schema/actions.yaml,sha256=kaJZ9B6SOl4Wbujtnr5k-g5JcAi2NSC1oGc0wZy8fnQ,1039
|
|
55
57
|
boneio/schema/actions_sensor.yaml,sha256=U_VfdjqdorQZHYD6dZOzhlRKnOGwsnTJ3CDGiqrKxW8,124
|
|
56
58
|
boneio/schema/actions_switch.yaml,sha256=sdqhwz0LrcfaiAN3-RfAR_xApxo5dh9RxXQubuKcsjk,129
|
|
57
59
|
boneio/schema/filters.yaml,sha256=WopX1SmCZsSZXNiGccLoi7uMCsUpdbs0eVfsAjmbay4,286
|
|
58
60
|
boneio/schema/filters_adc.yaml,sha256=3e0ts92MoFKOnfGOOn6WYIHxu0-tnZe9OjAjN9m7hiI,304
|
|
59
61
|
boneio/schema/id.yaml,sha256=vHI_6dxkJwoiGp5ien_pPpyaWA1F06eirTgfWMyWa1E,75
|
|
60
|
-
boneio/schema/schema.yaml,sha256=
|
|
62
|
+
boneio/schema/schema.yaml,sha256=4udNBm8dlUUuZtZat1D-9fUua-gCekPEaZTpqIxPYx4,16585
|
|
61
63
|
boneio/schema/temp_unit.yaml,sha256=m32VGz9RTW92Lz08l9n6RftkcVNZquOGPPr5mc3eZVc,65
|
|
62
64
|
boneio/schema/update_interval.yaml,sha256=L_YLddAZdybcdO-T57Qhlv1GaWIVDwhvH-GadD1oOIo,133
|
|
63
65
|
boneio/sensor/__init__.py,sha256=u-fSBKy1gcXTNclra5KzLYDxpHeo9G0vuNiMexIZSDw,538
|
|
@@ -75,9 +77,9 @@ boneio/sensor/temp/__init__.py,sha256=OViqBb7DwVn_aFIy6V0iqkSUDjsDNLQ5sOS_4frYdw
|
|
|
75
77
|
boneio/sensor/temp/dallas.py,sha256=xrvd1LNBh1fRcjz_yd_9S29Lv26ItVtLCmhZgVQWJos,2485
|
|
76
78
|
boneio/sensor/temp/lm75.py,sha256=-mpOv78429plRPBp9s09Ljz1x2Bdxuagalqz40vlAKE,243
|
|
77
79
|
boneio/sensor/temp/mcp9808.py,sha256=yAh5yJzZLGTqa39xV4fyqsruj7oy3niOZAUV2W6eyCM,271
|
|
78
|
-
boneio/version.py,sha256=
|
|
79
|
-
boneIO-0.7.0.
|
|
80
|
-
boneIO-0.7.0.
|
|
81
|
-
boneIO-0.7.0.
|
|
82
|
-
boneIO-0.7.0.
|
|
83
|
-
boneIO-0.7.0.
|
|
80
|
+
boneio/version.py,sha256=rJDui3QaSbG5XAefsT7-R72wn-eEkq3cia9pkFCPBBU,41
|
|
81
|
+
boneIO-0.7.0.dev6.dist-info/entry_points.txt,sha256=Igl1SMDEWwMg144bwRz28UOCb80hdxomC99QJ3u6qC0,46
|
|
82
|
+
boneIO-0.7.0.dev6.dist-info/WHEEL,sha256=B19PGBCYhWaz2p_UjAoRVh767nYQfk14Sn4TpIZ-nfU,87
|
|
83
|
+
boneIO-0.7.0.dev6.dist-info/METADATA,sha256=kZrIdKcI9WKh2t8Pj8KmoETz47_wUhZ-ywRm-ycOfN4,1749
|
|
84
|
+
boneIO-0.7.0.dev6.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
85
|
+
boneIO-0.7.0.dev6.dist-info/RECORD,,
|
boneio/const.py
CHANGED
|
@@ -112,6 +112,7 @@ MCP_ID = "mcp_id"
|
|
|
112
112
|
PCA_ID = "pca_id"
|
|
113
113
|
PCF_ID = "pcf_id"
|
|
114
114
|
INIT_SLEEP = "init_sleep"
|
|
115
|
+
OUTPUT_GROUP = "output_group"
|
|
115
116
|
|
|
116
117
|
# SENSOR CONST
|
|
117
118
|
TEMPERATURE = "temperature"
|
|
@@ -148,3 +149,12 @@ ExpanderTypes = Literal[MCP23017, PCA9685, PCF8575]
|
|
|
148
149
|
DEVICE_CLASS = "device_class"
|
|
149
150
|
DallasBusTypes = Literal[DS2482, DALLAS]
|
|
150
151
|
FILTERS = "filters"
|
|
152
|
+
|
|
153
|
+
cover_actions = {
|
|
154
|
+
"OPEN": "open",
|
|
155
|
+
"CLOSE": "close",
|
|
156
|
+
"TOGGLE": "toggle",
|
|
157
|
+
"STOP": "stop",
|
|
158
|
+
"TOGGLE_OPEN": "toggle_open",
|
|
159
|
+
"TOGGLE_CLOSE": "toggle_close",
|
|
160
|
+
}
|
boneio/cover.py
CHANGED
boneio/group/__init__.py
ADDED
boneio/group/output.py
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"""Cover module."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
import logging
|
|
4
|
+
import asyncio
|
|
5
|
+
from typing import List
|
|
6
|
+
|
|
7
|
+
from boneio.const import COVER, SWITCH, ON, OFF
|
|
8
|
+
from boneio.relay.basic import BasicRelay
|
|
9
|
+
|
|
10
|
+
_LOGGER = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class OutputGroup(BasicRelay):
|
|
14
|
+
"""Cover class of boneIO"""
|
|
15
|
+
|
|
16
|
+
def __init__(
|
|
17
|
+
self,
|
|
18
|
+
members: List[BasicRelay],
|
|
19
|
+
output_type: str = SWITCH,
|
|
20
|
+
restored_state: bool = True,
|
|
21
|
+
**kwargs,
|
|
22
|
+
) -> None:
|
|
23
|
+
"""Initialize cover class."""
|
|
24
|
+
self._loop = asyncio.get_event_loop()
|
|
25
|
+
super().__init__(
|
|
26
|
+
**kwargs, output_type=output_type, restored_state=restored_state, topic_type="group"
|
|
27
|
+
)
|
|
28
|
+
self._group_members = [x for x in members if x.output_type != COVER]
|
|
29
|
+
self._timer_handle = None
|
|
30
|
+
for member in self._group_members:
|
|
31
|
+
self._event_bus.add_output_listener(member.id, self.event_listener)
|
|
32
|
+
|
|
33
|
+
async def event_listener(self, relay_id=None) -> None:
|
|
34
|
+
"""Listen for events called by children relays."""
|
|
35
|
+
state = OFF
|
|
36
|
+
for x in self._group_members:
|
|
37
|
+
if x.state == ON:
|
|
38
|
+
state = ON
|
|
39
|
+
break
|
|
40
|
+
if state != self._state or not relay_id:
|
|
41
|
+
self._state = state
|
|
42
|
+
self._loop.call_soon_threadsafe(self.send_state)
|
|
43
|
+
|
|
44
|
+
def turn_on(self) -> None:
|
|
45
|
+
"""Call turn on action."""
|
|
46
|
+
for x in self._group_members:
|
|
47
|
+
asyncio.create_task(x.async_turn_on())
|
|
48
|
+
|
|
49
|
+
def turn_off(self) -> None:
|
|
50
|
+
"""Call turn off action."""
|
|
51
|
+
for x in self._group_members:
|
|
52
|
+
asyncio.create_task(x.async_turn_off())
|
|
53
|
+
|
|
54
|
+
def toggle(self) -> None:
|
|
55
|
+
"""Toggle group."""
|
|
56
|
+
_LOGGER.debug("Toggle relay.")
|
|
57
|
+
if self._state == ON:
|
|
58
|
+
self.turn_off()
|
|
59
|
+
else:
|
|
60
|
+
self.turn_on()
|
|
61
|
+
|
|
62
|
+
def send_state(self) -> None:
|
|
63
|
+
"""Send state to Mqtt on action."""
|
|
64
|
+
self._send_message(topic=self._send_topic, payload=self.payload(), retain=True)
|
boneio/helper/async_updater.py
CHANGED
|
@@ -15,7 +15,7 @@ class AsyncUpdater:
|
|
|
15
15
|
self._update_interval = update_interval or TimePeriod(seconds=60)
|
|
16
16
|
self.manager.append_task(coro=self._refresh, name=self.id)
|
|
17
17
|
|
|
18
|
-
async def _refresh(self):
|
|
18
|
+
async def _refresh(self) -> None:
|
|
19
19
|
while True:
|
|
20
20
|
if hasattr(self, "async_update"):
|
|
21
21
|
update_interval = (
|
boneio/helper/config.py
CHANGED
boneio/helper/events.py
CHANGED
|
@@ -81,6 +81,7 @@ class EventBus:
|
|
|
81
81
|
"""Initialize handler"""
|
|
82
82
|
self._loop = loop or asyncio.get_event_loop()
|
|
83
83
|
self._listeners = {}
|
|
84
|
+
self._output_listeners = {}
|
|
84
85
|
self._sigterm_listeners = []
|
|
85
86
|
self._haonline_listeners = []
|
|
86
87
|
self._timer_handle = _async_create_timer(self._loop, self._run_second_event)
|
|
@@ -102,6 +103,7 @@ class EventBus:
|
|
|
102
103
|
"""Function to call on exit. Should invoke all sigterm listeners."""
|
|
103
104
|
_LOGGER.debug("Exiting process started.")
|
|
104
105
|
self._listeners = {}
|
|
106
|
+
self._output_listeners = {}
|
|
105
107
|
for target in self._sigterm_listeners:
|
|
106
108
|
target()
|
|
107
109
|
self._timer_handle()
|
|
@@ -118,6 +120,19 @@ class EventBus:
|
|
|
118
120
|
"""Add sigterm listener."""
|
|
119
121
|
self._sigterm_listeners.append(target)
|
|
120
122
|
|
|
123
|
+
def add_output_listener(self, name, target):
|
|
124
|
+
"""Add output listener."""
|
|
125
|
+
self._output_listeners[name] = ListenerJob(target=target)
|
|
126
|
+
return self._output_listeners[name]
|
|
127
|
+
|
|
128
|
+
def trigger_output_event(self, event):
|
|
129
|
+
asyncio.create_task(self.async_trigger_output_event(event=event))
|
|
130
|
+
|
|
131
|
+
async def async_trigger_output_event(self, event):
|
|
132
|
+
listener = self._output_listeners.get(event)
|
|
133
|
+
if listener:
|
|
134
|
+
await listener.target(event)
|
|
135
|
+
|
|
121
136
|
def add_haonline_listener(self, target):
|
|
122
137
|
"""Add HA Online listener."""
|
|
123
138
|
self._haonline_listeners.append(target)
|
boneio/helper/gpio.py
CHANGED
|
@@ -115,7 +115,15 @@ class GpioBaseClass:
|
|
|
115
115
|
self._press_callback = press_callback
|
|
116
116
|
setup_input(pin=self._pin, pull_mode=gpio_mode)
|
|
117
117
|
|
|
118
|
+
def set_press_callback(self, press_callback: Callable[[ClickTypes, str, bool | None], None]) -> None:
|
|
119
|
+
self._press_callback = press_callback
|
|
120
|
+
|
|
118
121
|
@property
|
|
119
122
|
def is_pressed(self) -> bool:
|
|
120
123
|
"""Is button pressed."""
|
|
121
124
|
return read_input(self._pin)
|
|
125
|
+
|
|
126
|
+
@property
|
|
127
|
+
def pin(self) -> str:
|
|
128
|
+
"""Return configured pin."""
|
|
129
|
+
return self._pin
|
boneio/helper/ha_discovery.py
CHANGED
|
@@ -45,10 +45,10 @@ def ha_availabilty_message(
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
|
|
48
|
-
def ha_light_availabilty_message(id: str, topic: str = "boneIO", **kwargs):
|
|
48
|
+
def ha_light_availabilty_message(id: str, topic: str = "boneIO", device_type: str = RELAY, **kwargs):
|
|
49
49
|
"""Create LIGHT availability topic for HA."""
|
|
50
|
-
msg = ha_availabilty_message(device_type=
|
|
51
|
-
msg["command_topic"] = f"{topic}/cmd/{
|
|
50
|
+
msg = ha_availabilty_message(device_type=device_type, topic=topic, id=id, **kwargs)
|
|
51
|
+
msg["command_topic"] = f"{topic}/cmd/{device_type}/{id}/set"
|
|
52
52
|
msg["payload_off"] = OFF
|
|
53
53
|
msg["payload_on"] = ON
|
|
54
54
|
msg["state_value_template"] = "{{ value_json.state }}"
|
|
@@ -79,10 +79,10 @@ def ha_button_availabilty_message(
|
|
|
79
79
|
return msg
|
|
80
80
|
|
|
81
81
|
|
|
82
|
-
def ha_switch_availabilty_message(id: str, topic: str = "boneIO", **kwargs):
|
|
82
|
+
def ha_switch_availabilty_message(id: str, topic: str = "boneIO", device_type: str = RELAY, **kwargs):
|
|
83
83
|
"""Create SWITCH availability topic for HA."""
|
|
84
|
-
msg = ha_availabilty_message(device_type=
|
|
85
|
-
msg["command_topic"] = f"{topic}/cmd/
|
|
84
|
+
msg = ha_availabilty_message(device_type=device_type, topic=topic, id=id, **kwargs)
|
|
85
|
+
msg["command_topic"] = f"{topic}/cmd/{device_type}/{id}/set"
|
|
86
86
|
msg["payload_off"] = OFF
|
|
87
87
|
msg["payload_on"] = ON
|
|
88
88
|
msg["value_template"] = "{{ value_json.state }}"
|
boneio/helper/loader.py
CHANGED
|
@@ -41,9 +41,10 @@ from boneio.const import (
|
|
|
41
41
|
ExpanderTypes,
|
|
42
42
|
PCF,
|
|
43
43
|
PCA,
|
|
44
|
-
PCF_ID
|
|
44
|
+
PCF_ID,
|
|
45
45
|
)
|
|
46
46
|
from boneio.cover import Cover
|
|
47
|
+
from boneio.group import OutputGroup
|
|
47
48
|
from boneio.helper import (
|
|
48
49
|
GPIOInputException,
|
|
49
50
|
GPIOOutputException,
|
|
@@ -65,7 +66,11 @@ from boneio.helper.ha_discovery import ha_cover_availabilty_message
|
|
|
65
66
|
from boneio.helper.timeperiod import TimePeriod
|
|
66
67
|
from boneio.helper.pcf8575 import PCF8575
|
|
67
68
|
from boneio.input import GpioEventButton, GpioEventButtonBeta
|
|
68
|
-
from boneio.sensor import
|
|
69
|
+
from boneio.sensor import (
|
|
70
|
+
DallasSensorDS2482,
|
|
71
|
+
GpioInputBinarySensor,
|
|
72
|
+
GpioInputBinarySensorBeta,
|
|
73
|
+
)
|
|
69
74
|
from boneio.sensor.temp.dallas import DallasSensorW1
|
|
70
75
|
|
|
71
76
|
# Typing imports that create a circular dependency
|
|
@@ -154,24 +159,19 @@ def create_temp_sensor(
|
|
|
154
159
|
pass
|
|
155
160
|
|
|
156
161
|
|
|
157
|
-
expander_class = {
|
|
158
|
-
MCP: MCP23017,
|
|
159
|
-
PCA: PCA9685,
|
|
160
|
-
PCF: PCF8575
|
|
161
|
-
}
|
|
162
|
+
expander_class = {MCP: MCP23017, PCA: PCA9685, PCF: PCF8575}
|
|
162
163
|
|
|
163
164
|
|
|
164
165
|
def create_expander(
|
|
165
|
-
|
|
166
|
-
expander_config: list,
|
|
167
|
-
exp_type: ExpanderTypes,
|
|
168
|
-
i2cbusio: I2C
|
|
166
|
+
expander_dict: dict, expander_config: list, exp_type: ExpanderTypes, i2cbusio: I2C
|
|
169
167
|
) -> dict:
|
|
170
168
|
grouped_outputs = {}
|
|
171
169
|
for expander in expander_config:
|
|
172
170
|
id = expander[ID] or expander[ADDRESS]
|
|
173
171
|
try:
|
|
174
|
-
expander_dict[id] = expander_class[exp_type](
|
|
172
|
+
expander_dict[id] = expander_class[exp_type](
|
|
173
|
+
i2c=i2cbusio, address=expander[ADDRESS], reset=False
|
|
174
|
+
)
|
|
175
175
|
sleep_time = expander.get(INIT_SLEEP, TimePeriod(seconds=0))
|
|
176
176
|
if sleep_time.total_seconds > 0:
|
|
177
177
|
_LOGGER.debug(
|
|
@@ -179,9 +179,7 @@ def create_expander(
|
|
|
179
179
|
)
|
|
180
180
|
time.sleep(sleep_time.total_seconds)
|
|
181
181
|
else:
|
|
182
|
-
_LOGGER.debug(
|
|
183
|
-
f"{exp_type} {id} is initializing."
|
|
184
|
-
)
|
|
182
|
+
_LOGGER.debug(f"{exp_type} {id} is initializing.")
|
|
185
183
|
grouped_outputs[id] = {}
|
|
186
184
|
except TimeoutError as err:
|
|
187
185
|
_LOGGER.error("Can't connect to %s %s. %s", exp_type, id, err)
|
|
@@ -216,26 +214,54 @@ def create_modbus_sensors(manager: Manager, sensors, **kwargs) -> None:
|
|
|
216
214
|
pass
|
|
217
215
|
|
|
218
216
|
|
|
219
|
-
OutputEntry = namedtuple("OutputEntry", "OutputClass output_kind
|
|
217
|
+
OutputEntry = namedtuple("OutputEntry", "OutputClass output_kind expander_id")
|
|
220
218
|
|
|
221
219
|
|
|
222
220
|
def output_chooser(output_kind: str, config):
|
|
223
221
|
"""Get named tuple based on input."""
|
|
224
222
|
if output_kind == MCP:
|
|
225
|
-
|
|
226
|
-
return OutputEntry(MCPRelay, MCP,
|
|
223
|
+
expander_id = config.pop(MCP_ID, None)
|
|
224
|
+
return OutputEntry(MCPRelay, MCP, expander_id)
|
|
227
225
|
elif output_kind == GPIO:
|
|
228
226
|
return OutputEntry(GpioRelay, GPIO, GPIO)
|
|
229
227
|
elif output_kind == PCA:
|
|
230
|
-
|
|
231
|
-
return OutputEntry(PWMPCA, PCA,
|
|
228
|
+
expander_id = config.pop(PCA_ID, None)
|
|
229
|
+
return OutputEntry(PWMPCA, PCA, expander_id)
|
|
232
230
|
elif output_kind == PCF:
|
|
233
|
-
|
|
234
|
-
return OutputEntry(PCFRelay, PCF,
|
|
231
|
+
expander_id = config.pop(PCF_ID, None)
|
|
232
|
+
return OutputEntry(PCFRelay, PCF, expander_id)
|
|
235
233
|
else:
|
|
236
234
|
raise GPIOOutputException(f"""Output type {output_kind} dont exists""")
|
|
237
235
|
|
|
238
236
|
|
|
237
|
+
def configure_output_group(
|
|
238
|
+
manager: Manager,
|
|
239
|
+
state_manager: StateManager,
|
|
240
|
+
topic_prefix: str,
|
|
241
|
+
relay_id: str,
|
|
242
|
+
config: dict,
|
|
243
|
+
**kwargs
|
|
244
|
+
) -> Any:
|
|
245
|
+
"""Configure kind of relay. Most common MCP."""
|
|
246
|
+
restore_state = config.pop(RESTORE_STATE, False)
|
|
247
|
+
_id = config.pop(ID)
|
|
248
|
+
restored_state = (
|
|
249
|
+
state_manager.get(attr_type=RELAY, attr=relay_id, default_value=False)
|
|
250
|
+
if restore_state
|
|
251
|
+
else False
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
output = OutputGroup(
|
|
255
|
+
send_message=manager.send_message,
|
|
256
|
+
topic_prefix=topic_prefix,
|
|
257
|
+
id=_id,
|
|
258
|
+
restored_state=restored_state,
|
|
259
|
+
callback=lambda: None,
|
|
260
|
+
**config,
|
|
261
|
+
**kwargs)
|
|
262
|
+
return output
|
|
263
|
+
|
|
264
|
+
|
|
239
265
|
def configure_relay(
|
|
240
266
|
manager: Manager,
|
|
241
267
|
state_manager: StateManager,
|
|
@@ -243,6 +269,7 @@ def configure_relay(
|
|
|
243
269
|
relay_id: str,
|
|
244
270
|
relay_callback: Callable,
|
|
245
271
|
config: dict,
|
|
272
|
+
**kwargs
|
|
246
273
|
) -> Any:
|
|
247
274
|
"""Configure kind of relay. Most common MCP."""
|
|
248
275
|
restore_state = config.pop(RESTORE_STATE, False)
|
|
@@ -259,42 +286,42 @@ def configure_relay(
|
|
|
259
286
|
output = output_chooser(output_kind=config.pop(KIND), config=config)
|
|
260
287
|
|
|
261
288
|
if getattr(output, "output_kind") == MCP:
|
|
262
|
-
mcp = manager.mcp.get(getattr(output, "
|
|
289
|
+
mcp = manager.mcp.get(getattr(output, "expander_id"))
|
|
263
290
|
if not mcp:
|
|
264
291
|
_LOGGER.error("No such MCP configured!")
|
|
265
292
|
return None
|
|
266
|
-
|
|
293
|
+
extra_args = {
|
|
267
294
|
"pin": int(config.pop(PIN)),
|
|
268
295
|
"mcp": mcp,
|
|
269
|
-
"mcp_id": getattr(output, "
|
|
296
|
+
"mcp_id": getattr(output, "expander_id"),
|
|
270
297
|
"output_type": output_type,
|
|
271
298
|
}
|
|
272
299
|
elif getattr(output, "output_kind") == PCA:
|
|
273
|
-
pca = manager.pca.get(getattr(output, "
|
|
300
|
+
pca = manager.pca.get(getattr(output, "expander_id"))
|
|
274
301
|
if not pca:
|
|
275
302
|
_LOGGER.error("No such PCA configured!")
|
|
276
303
|
return None
|
|
277
|
-
|
|
304
|
+
extra_args = {
|
|
278
305
|
"pin": int(config.pop(PIN)),
|
|
279
306
|
"pca": pca,
|
|
280
|
-
"pca_id": getattr(output, "
|
|
307
|
+
"pca_id": getattr(output, "expander_id"),
|
|
281
308
|
"output_type": output_type,
|
|
282
309
|
}
|
|
283
310
|
elif getattr(output, "output_kind") == PCF:
|
|
284
|
-
expander = manager.pcf.get(getattr(output, "
|
|
311
|
+
expander = manager.pcf.get(getattr(output, "expander_id"))
|
|
285
312
|
if not expander:
|
|
286
313
|
_LOGGER.error("No such PCF configured!")
|
|
287
314
|
return None
|
|
288
|
-
|
|
315
|
+
extra_args = {
|
|
289
316
|
"pin": int(config.pop(PIN)),
|
|
290
317
|
"expander": expander,
|
|
291
|
-
"expander_id": getattr(output, "
|
|
318
|
+
"expander_id": getattr(output, "expander_id"),
|
|
292
319
|
"output_type": output_type,
|
|
293
320
|
}
|
|
294
321
|
elif getattr(output, "output_kind") == GPIO:
|
|
295
322
|
if GPIO not in manager.grouped_outputs:
|
|
296
323
|
manager.grouped_outputs[GPIO] = {}
|
|
297
|
-
|
|
324
|
+
extra_args = {
|
|
298
325
|
"pin": config.pop(PIN),
|
|
299
326
|
}
|
|
300
327
|
else:
|
|
@@ -310,13 +337,14 @@ def configure_relay(
|
|
|
310
337
|
restored_state=restored_state,
|
|
311
338
|
**config,
|
|
312
339
|
**kwargs,
|
|
340
|
+
**extra_args,
|
|
313
341
|
callback=lambda: relay_callback(
|
|
314
|
-
|
|
342
|
+
expander_id=getattr(output, "expander_id"),
|
|
315
343
|
relay_id=relay_id,
|
|
316
344
|
restore_state=False if output_type == NONE else restore_state,
|
|
317
345
|
),
|
|
318
346
|
)
|
|
319
|
-
manager.grouped_outputs[getattr(output, "
|
|
347
|
+
manager.grouped_outputs[getattr(output, "expander_id")][relay_id] = relay
|
|
320
348
|
return relay
|
|
321
349
|
|
|
322
350
|
|
|
@@ -335,7 +363,9 @@ def input_chooser(input_type: str):
|
|
|
335
363
|
ha_binary_sensor_availabilty_message,
|
|
336
364
|
)
|
|
337
365
|
else:
|
|
338
|
-
return InputEntry(
|
|
366
|
+
return InputEntry(
|
|
367
|
+
GpioEventButton, INPUT, EVENT_ENTITY, ha_event_availabilty_message
|
|
368
|
+
)
|
|
339
369
|
|
|
340
370
|
|
|
341
371
|
def configure_event_sensor(
|
|
@@ -343,22 +373,40 @@ def configure_event_sensor(
|
|
|
343
373
|
pin: str,
|
|
344
374
|
press_callback: Callable,
|
|
345
375
|
send_ha_autodiscovery: Callable,
|
|
346
|
-
|
|
376
|
+
input: GpioEventButton | GpioEventButtonBeta | None = None
|
|
377
|
+
) -> GpioEventButton | GpioEventButtonBeta | None:
|
|
347
378
|
"""Configure input sensor or button."""
|
|
348
379
|
try:
|
|
349
|
-
GpioEventButtonClass =
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
380
|
+
GpioEventButtonClass = (
|
|
381
|
+
GpioEventButton
|
|
382
|
+
if gpio.get("detection_type", "stable") == "stable"
|
|
383
|
+
else GpioEventButtonBeta
|
|
384
|
+
)
|
|
385
|
+
if input:
|
|
386
|
+
if not isinstance(input, GpioEventButtonClass):
|
|
387
|
+
_LOGGER.warn("You preconfigured type of input. It's forbidden. Please restart boneIO.")
|
|
388
|
+
return input
|
|
389
|
+
input.set_press_callback(press_callback=lambda x, i, z: press_callback(
|
|
353
390
|
x=x,
|
|
354
391
|
inpin=i,
|
|
355
392
|
actions=gpio.get(ACTIONS, {}).get(x, []),
|
|
356
393
|
input_type=INPUT,
|
|
357
394
|
empty_message_after=gpio.get("clear_message", False),
|
|
358
|
-
duration=z
|
|
359
|
-
)
|
|
360
|
-
|
|
361
|
-
|
|
395
|
+
duration=z,
|
|
396
|
+
))
|
|
397
|
+
else:
|
|
398
|
+
input = GpioEventButtonClass(
|
|
399
|
+
pin=pin,
|
|
400
|
+
press_callback=lambda x, i, z: press_callback(
|
|
401
|
+
x=x,
|
|
402
|
+
inpin=i,
|
|
403
|
+
actions=gpio.get(ACTIONS, {}).get(x, []),
|
|
404
|
+
input_type=INPUT,
|
|
405
|
+
empty_message_after=gpio.get("clear_message", False),
|
|
406
|
+
duration=z,
|
|
407
|
+
),
|
|
408
|
+
**gpio,
|
|
409
|
+
)
|
|
362
410
|
if gpio.get(SHOW_HA, True):
|
|
363
411
|
send_ha_autodiscovery(
|
|
364
412
|
id=pin,
|
|
@@ -367,31 +415,50 @@ def configure_event_sensor(
|
|
|
367
415
|
device_class=gpio.get(DEVICE_CLASS, None),
|
|
368
416
|
availability_msg_func=ha_event_availabilty_message,
|
|
369
417
|
)
|
|
370
|
-
return
|
|
418
|
+
return input
|
|
371
419
|
except GPIOInputException as err:
|
|
372
420
|
_LOGGER.error("This PIN %s can't be configured. %s", pin, err)
|
|
373
421
|
pass
|
|
374
422
|
|
|
423
|
+
|
|
375
424
|
def configure_binary_sensor(
|
|
376
425
|
gpio: dict,
|
|
377
426
|
pin: str,
|
|
378
427
|
press_callback: Callable,
|
|
379
428
|
send_ha_autodiscovery: Callable,
|
|
380
|
-
|
|
429
|
+
input: GpioInputBinarySensor | GpioInputBinarySensorBeta | None = None
|
|
430
|
+
) -> GpioInputBinarySensor | GpioInputBinarySensorBeta | None:
|
|
381
431
|
"""Configure input sensor or button."""
|
|
382
432
|
try:
|
|
383
|
-
GpioInputBinarySensorClass =
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
433
|
+
GpioInputBinarySensorClass = (
|
|
434
|
+
GpioInputBinarySensor
|
|
435
|
+
if gpio.get("detection_type", "stable") == "stable"
|
|
436
|
+
else GpioInputBinarySensorBeta
|
|
437
|
+
)
|
|
438
|
+
if input:
|
|
439
|
+
if not isinstance(input, GpioInputBinarySensorClass):
|
|
440
|
+
_LOGGER.warn("You preconfigured type of input. It's forbidden. Please restart boneIO.")
|
|
441
|
+
return input
|
|
442
|
+
input.set_press_callback(press_callback=lambda x, i, z: press_callback(
|
|
387
443
|
x=x,
|
|
388
444
|
inpin=i,
|
|
389
445
|
actions=gpio.get(ACTIONS, {}).get(x, []),
|
|
390
|
-
input_type=
|
|
391
|
-
empty_message_after=gpio.get("clear_message", False)
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
446
|
+
input_type=INPUT,
|
|
447
|
+
empty_message_after=gpio.get("clear_message", False),
|
|
448
|
+
duration=z,
|
|
449
|
+
))
|
|
450
|
+
else:
|
|
451
|
+
input = GpioInputBinarySensorClass(
|
|
452
|
+
pin=pin,
|
|
453
|
+
press_callback=lambda x, i: press_callback(
|
|
454
|
+
x=x,
|
|
455
|
+
inpin=i,
|
|
456
|
+
actions=gpio.get(ACTIONS, {}).get(x, []),
|
|
457
|
+
input_type=INPUT_SENSOR,
|
|
458
|
+
empty_message_after=gpio.get("clear_message", False),
|
|
459
|
+
),
|
|
460
|
+
**gpio,
|
|
461
|
+
)
|
|
395
462
|
if gpio.get(SHOW_HA, True):
|
|
396
463
|
send_ha_autodiscovery(
|
|
397
464
|
id=pin,
|
|
@@ -400,11 +467,12 @@ def configure_binary_sensor(
|
|
|
400
467
|
device_class=gpio.get(DEVICE_CLASS, None),
|
|
401
468
|
availability_msg_func=ha_binary_sensor_availabilty_message,
|
|
402
469
|
)
|
|
403
|
-
return
|
|
470
|
+
return input
|
|
404
471
|
except GPIOInputException as err:
|
|
405
472
|
_LOGGER.error("This PIN %s can't be configured. %s", pin, err)
|
|
406
473
|
pass
|
|
407
474
|
|
|
475
|
+
|
|
408
476
|
def configure_cover(
|
|
409
477
|
manager: Manager,
|
|
410
478
|
cover_id: str,
|
|
@@ -440,6 +508,7 @@ def configure_cover(
|
|
|
440
508
|
device_class=config.get(DEVICE_CLASS),
|
|
441
509
|
availability_msg_func=ha_cover_availabilty_message,
|
|
442
510
|
)
|
|
511
|
+
_LOGGER.debug("Configured cover %s", cover_id)
|
|
443
512
|
return cover
|
|
444
513
|
|
|
445
514
|
|