boneIO 0.7.0dev2__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.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: boneIO
3
- Version: 0.7.0dev2
3
+ Version: 0.7.0dev6
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,7 +1,7 @@
1
1
  boneio/__init__.py,sha256=hoLKnu6h1uEsiCHA9Ql2MMDC7VQS0E-s_2cxBS-CTOg,147
2
- boneio/bonecli.py,sha256=VhY1BMt6OaZz-752UjhEexdn8fDJkJaDWcGQNhCmgN0,3341
3
- boneio/const.py,sha256=NwdWZaL2Jjk7eizYhjXcaPGB5PjEeg9TJGhKBbj2bkg,3049
4
- boneio/cover.py,sha256=nr76ft5smAPdBB8Jytk-uFd6RWuqtcZiG6EE129OUjw,8454
2
+ boneio/bonecli.py,sha256=o2DWcsKqw4IJklPmbdq7bwgcISOWPZfYVAUuMltNUP0,3435
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,50 +13,53 @@ 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=BVh5mXFxgaZqoekjQbQSCTssfyVIdCQ80LCJny-rOo4,985
18
- boneio/helper/click_timer.py,sha256=dVYdX3VNpAEKHCIqWs3u0PCJLSPIGr0K2kMffc_kGdc,1138
19
- boneio/helper/config.py,sha256=HUl7iF7os1-YNfl1neJf2aDwiS2VE43biGefU5EhW3s,2321
20
- boneio/helper/events.py,sha256=i-5FLyVwcAO3m3TpctxtbTcb7SCyQv8lX04mLHHhYk8,7592
19
+ boneio/helper/async_updater.py,sha256=K1xXpVAFeTOKfcmTGBnBgOvwZHfZQQKOWVEOnEMm0BY,993
20
+ boneio/helper/click_timer.py,sha256=yZ2nfnreSCBfJkkWDE_RhDfV7YHgwfoehMLh3ia2BEI,1184
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=sxvkYtKVt5alGoXFBRzG8ONEo112fsKsX-zK2C-_YKg,3249
24
- boneio/helper/ha_discovery.py,sha256=ErAub0LK9y2fUieqUsHpixQATO1NQ_ZABGELVYDAZtE,6359
25
- boneio/helper/loader.py,sha256=6t9q3ns0EamuI0hn7_pCydAIWhOab5LoJ1AxPSHetZE,14687
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=UVa4KaxvVif6By_sVMdSMiYI_doZjiXF4LS9RFltxJk,765
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
31
33
  boneio/helper/onewire/ds2482.py,sha256=c2t_hdAMtFsHw4Vw41QzO_hEDDNMeb3J71mEwEMUBhM,5169
32
34
  boneio/helper/onewire/onewire.py,sha256=tHofTu1l0qG7hH2XoSf-lj8gW7wVKe27j57qQWpVMPg,2497
35
+ boneio/helper/pcf8575.py,sha256=qeNYLqV5foDEQCyAz1WRQRi1CYYxtbPIha06Z5TyZVQ,311
33
36
  boneio/helper/queue.py,sha256=7fE7d344-BEW8sljN40wmqsbBr4kPLvz4ShBjkT04p8,1066
34
- boneio/helper/state_manager.py,sha256=LsMQRrD7WXu5jXFoltYXvzHDeiNDDEx6UWYebFw18gc,1994
37
+ boneio/helper/state_manager.py,sha256=PiNCL_uHElVH34ztIXBgVgKnpN0Mje2pspCLBiRIsgk,2145
35
38
  boneio/helper/stats.py,sha256=XNQDU-ixIobKQ2batzZno2UOMzNGWHSFQ-EXChNBJzM,5853
36
39
  boneio/helper/timeperiod.py,sha256=xpg9oe30Z5WiLDQPq3EBKKScejOnN47NhcpeFvDd3bY,5806
37
40
  boneio/helper/util.py,sha256=QfSoT3H3WnOQAKO5bFRIBCy62HT5NMa9Ek-FmfTW_rw,508
38
41
  boneio/helper/yaml_util.py,sha256=gAX7hCaHUlPgkhGCIQ4zjv0Vj9JmLzQsSyF51ZmSb9g,11304
39
42
  boneio/input/__init__.py,sha256=ZM6G2XX621lQUy8Tk6S8zf_jBp_NxsK6OHMMrdsOsDo,178
40
- boneio/input/gpio.py,sha256=4YPzwtyWuEWdDQWte5YU-X_vaId2wFy_XWv7WkjzFoQ,2611
41
- boneio/input/gpio_beta.py,sha256=mBMIpVUEyH-CJpb2TtHDiiYaVFYdzjExcDGeOxx9PYQ,3133
42
- boneio/manager.py,sha256=YwTm-5Loi9deUFokXFNW-FDQDtnrZUlpW9xreyW6Vlw,22339
43
+ boneio/input/gpio.py,sha256=j6tiZmUC934Yc_Lu8FjSNQIdRb0iJLiucJu0UuU_cAQ,2709
44
+ boneio/input/gpio_beta.py,sha256=ZsiY5oeSsqo-JuZ9uglwfsmJ_MySQqxuGU6PbWcO1Hw,3231
45
+ boneio/manager.py,sha256=rITALbKkdzkaNLdza2lw9DvtlrhrS-ydLv3W2KKTNWw,27086
43
46
  boneio/modbus.py,sha256=eA_sGnmdcIneXX75ZcXOI223-UkKN1UYmWFqiJBAhJo,4176
44
- boneio/mqtt_client.py,sha256=OakqsF5q6JSOMR___EldxuG_Xg9YVDPYAV6CSwyJAjs,8645
47
+ boneio/mqtt_client.py,sha256=5_ilaYqsCIIdKjsspQxPoNkSpSuCjrwD16HTcfH0Lxk,8551
45
48
  boneio/oled.py,sha256=d_ofDQHc7zr3j0qOR0B_L3C8TJhvRH85nnb9Le-88nk,5244
46
- boneio/relay/__init__.py,sha256=iLEUL8kxnEndCQtgDIJfHqUZOfyWfWmuOrqSYAUxb2w,181
47
- boneio/relay/basic.py,sha256=uMQWSgcCVH-ieGKirW_Faj1rVEivt0kmCE9XCDCu47s,2798
49
+ boneio/relay/__init__.py,sha256=Cz6D37GKHxm8DiuPuxE2EMaey2wdUdJYVet_hfR0lzA,231
50
+ boneio/relay/basic.py,sha256=BeA4v4eq2uyMDnIvZFHBl7EIs5scJ0efJQbvZqwMstc,3276
48
51
  boneio/relay/gpio.py,sha256=s64FBf6zlxciF57xJ6nrvy0t5Rie0uiXlwos0HL3RKM,1163
49
- boneio/relay/mcp.py,sha256=y23yvOsyBEs9d8A6QOgtmJpjd4cDx6DyW-cBz8Y-488,2506
50
- boneio/relay/pca.py,sha256=vYQbDoBQ6iRK0HN3M8gW402PEwM5utON1hmdw5E0cIE,4871
51
- boneio/relay/pcf.py,sha256=N_4d2u7nMUL-s5LwxsHGOKtGXneKFm-lCpezpKvrJvs,2504
52
- boneio/runner.py,sha256=VL0q7P4VeDhoQIqooE8gg8Q7wOYCGIcHSZk7g9SDZHU,2876
53
- boneio/schema/actions.yaml,sha256=WD0LR9SxVPgwU12x10RvFaTeyDiCjdRiicfkrCGLNvc,1030
52
+ boneio/relay/mcp.py,sha256=4NZJLVtR_f-vuwGA1vbTLqzPoEZO2_in-RJSORfwC60,2508
53
+ boneio/relay/pca.py,sha256=YBrClCM_dvPF92gdDmyjfGumhan0UdHWQBDv-J7DrzA,4594
54
+ boneio/relay/pcf.py,sha256=15uw3i3n06AfILcd6fWRgHjibKDkvRbiAntoTrlwHx4,2635
55
+ boneio/runner.py,sha256=wHi1R3sI6OSBdjQ5-G44r8WGiTiTqv5n7x5aB-_GIrw,2789
56
+ boneio/schema/actions.yaml,sha256=kaJZ9B6SOl4Wbujtnr5k-g5JcAi2NSC1oGc0wZy8fnQ,1039
54
57
  boneio/schema/actions_sensor.yaml,sha256=U_VfdjqdorQZHYD6dZOzhlRKnOGwsnTJ3CDGiqrKxW8,124
55
58
  boneio/schema/actions_switch.yaml,sha256=sdqhwz0LrcfaiAN3-RfAR_xApxo5dh9RxXQubuKcsjk,129
56
59
  boneio/schema/filters.yaml,sha256=WopX1SmCZsSZXNiGccLoi7uMCsUpdbs0eVfsAjmbay4,286
57
60
  boneio/schema/filters_adc.yaml,sha256=3e0ts92MoFKOnfGOOn6WYIHxu0-tnZe9OjAjN9m7hiI,304
58
61
  boneio/schema/id.yaml,sha256=vHI_6dxkJwoiGp5ien_pPpyaWA1F06eirTgfWMyWa1E,75
59
- boneio/schema/schema.yaml,sha256=NxG-4i3Sak27sOWk_nf8Bmbwgt5Ldye4ZYnRIvR_79g,15072
62
+ boneio/schema/schema.yaml,sha256=4udNBm8dlUUuZtZat1D-9fUua-gCekPEaZTpqIxPYx4,16585
60
63
  boneio/schema/temp_unit.yaml,sha256=m32VGz9RTW92Lz08l9n6RftkcVNZquOGPPr5mc3eZVc,65
61
64
  boneio/schema/update_interval.yaml,sha256=L_YLddAZdybcdO-T57Qhlv1GaWIVDwhvH-GadD1oOIo,133
62
65
  boneio/sensor/__init__.py,sha256=u-fSBKy1gcXTNclra5KzLYDxpHeo9G0vuNiMexIZSDw,538
@@ -74,9 +77,9 @@ boneio/sensor/temp/__init__.py,sha256=OViqBb7DwVn_aFIy6V0iqkSUDjsDNLQ5sOS_4frYdw
74
77
  boneio/sensor/temp/dallas.py,sha256=xrvd1LNBh1fRcjz_yd_9S29Lv26ItVtLCmhZgVQWJos,2485
75
78
  boneio/sensor/temp/lm75.py,sha256=-mpOv78429plRPBp9s09Ljz1x2Bdxuagalqz40vlAKE,243
76
79
  boneio/sensor/temp/mcp9808.py,sha256=yAh5yJzZLGTqa39xV4fyqsruj7oy3niOZAUV2W6eyCM,271
77
- boneio/version.py,sha256=17EUCA3ZgMyhHFifjToUvLPBUn7Sc12qa42ebBpttH8,41
78
- boneIO-0.7.0.dev2.dist-info/entry_points.txt,sha256=Igl1SMDEWwMg144bwRz28UOCb80hdxomC99QJ3u6qC0,46
79
- boneIO-0.7.0.dev2.dist-info/WHEEL,sha256=B19PGBCYhWaz2p_UjAoRVh767nYQfk14Sn4TpIZ-nfU,87
80
- boneIO-0.7.0.dev2.dist-info/METADATA,sha256=F57mc0Y6T-8X1avMDVEnxuG80U7zMx5oLq7vtc-kOTA,1749
81
- boneIO-0.7.0.dev2.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
82
- boneIO-0.7.0.dev2.dist-info/RECORD,,
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/bonecli.py CHANGED
@@ -15,6 +15,7 @@ from yaml import MarkedYAMLError
15
15
  from boneio.const import ACTION
16
16
  from boneio.helper import load_config_from_file
17
17
  from boneio.helper.exceptions import ConfigurationException, RestartRequestException
18
+ from boneio.helper.events import GracefulExit
18
19
  from boneio.helper.logger import configure_logger
19
20
  from boneio.runner import async_run
20
21
  from boneio.version import __version__
@@ -89,8 +90,9 @@ def run(config: str, debug: int, mqttusername: str = "", mqttpassword: str = "")
89
90
  ),
90
91
  )
91
92
  return 0
92
- except RestartRequestException as err:
93
- _LOGGER.info(err)
93
+ except (RestartRequestException, GracefulExit) as err:
94
+ if err is not None:
95
+ _LOGGER.info(err)
94
96
  return 0
95
97
  except (ConfigurationException, MarkedYAMLError) as err:
96
98
  _LOGGER.error("Failed to load config. %s Exiting.", err)
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
@@ -109,7 +109,7 @@ class Cover(BasicMqtt):
109
109
  self._stop_cover(on_exit=True)
110
110
 
111
111
  @property
112
- def cover_state(self) -> CLOSED | OPEN:
112
+ def cover_state(self) -> str:
113
113
  """Current state of cover."""
114
114
  return CLOSED if self._closed else OPEN
115
115
 
@@ -0,0 +1,4 @@
1
+ """Group classes."""
2
+ from .output import OutputGroup
3
+
4
+ __all__ = ["OutputGroup"]
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)
@@ -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 = (
@@ -24,9 +24,10 @@ class ClickTimer:
24
24
  self._remove_listener = None
25
25
 
26
26
  async def _start_async_timer(self) -> None:
27
+ start = time.time()
27
28
  await asyncio.sleep(self._delay)
28
29
  self._remove_listener = None
29
- self._action(time.time())
30
+ self._action(round(time.time() - start, 2))
30
31
 
31
32
  def start_timer(self) -> None:
32
33
  """Start timer."""
boneio/helper/config.py CHANGED
@@ -64,6 +64,9 @@ class ConfigHelper:
64
64
  if topic in self._autodiscovery_messages[ha_type]:
65
65
  return True
66
66
  return False
67
+
68
+ def clear_autodiscovery_type(self, ha_type: str):
69
+ self._autodiscovery_messages[ha_type] = {}
67
70
 
68
71
 
69
72
 
boneio/helper/events.py CHANGED
@@ -77,19 +77,18 @@ class ListenerJob:
77
77
  class EventBus:
78
78
  """Simple event bus which ticks every second."""
79
79
 
80
- def __init__(self, last_will_mqtt = Callable) -> None:
80
+ def __init__(self, loop: asyncio.AbstractEventLoop) -> None:
81
81
  """Initialize handler"""
82
- self._loop = asyncio.get_event_loop()
83
- self._last_will = last_will_mqtt
84
-
82
+ self._loop = loop or asyncio.get_event_loop()
85
83
  self._listeners = {}
84
+ self._output_listeners = {}
86
85
  self._sigterm_listeners = []
87
86
  self._haonline_listeners = []
88
87
  self._timer_handle = _async_create_timer(self._loop, self._run_second_event)
89
88
  for signame in {"SIGINT", "SIGTERM"}:
90
89
  self._loop.add_signal_handler(
91
90
  getattr(signal, signame),
92
- lambda: asyncio.create_task(self.ask_exit()),
91
+ self.ask_exit,
93
92
  )
94
93
 
95
94
  def _run_second_event(self, time):
@@ -100,15 +99,15 @@ class EventBus:
100
99
  self._loop.call_soon(listener.target, time)
101
100
  )
102
101
 
103
- async def ask_exit(self):
102
+ def ask_exit(self):
104
103
  """Function to call on exit. Should invoke all sigterm listeners."""
105
104
  _LOGGER.debug("Exiting process started.")
106
105
  self._listeners = {}
106
+ self._output_listeners = {}
107
107
  for target in self._sigterm_listeners:
108
108
  target()
109
109
  self._timer_handle()
110
110
 
111
- await self._last_will()
112
111
  _LOGGER.info("Shutdown gracefully.")
113
112
  raise GracefulExit(code=0)
114
113
 
@@ -121,6 +120,19 @@ class EventBus:
121
120
  """Add sigterm listener."""
122
121
  self._sigterm_listeners.append(target)
123
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
+
124
136
  def add_haonline_listener(self, target):
125
137
  """Add HA Online listener."""
126
138
  self._haonline_listeners.append(target)
boneio/helper/gpio.py CHANGED
@@ -1,3 +1,4 @@
1
+ from __future__ import annotations
1
2
  import asyncio
2
3
  import logging
3
4
 
@@ -104,7 +105,7 @@ class GpioBaseClass:
104
105
  """Base class for initialize GPIO"""
105
106
 
106
107
  def __init__(
107
- self, pin: str, press_callback: Callable[[ClickTypes, str], None], **kwargs
108
+ self, pin: str, press_callback: Callable[[ClickTypes, str, bool | None], None], **kwargs
108
109
  ) -> None:
109
110
  """Setup GPIO Input Button"""
110
111
  self._pin = pin
@@ -114,7 +115,15 @@ class GpioBaseClass:
114
115
  self._press_callback = press_callback
115
116
  setup_input(pin=self._pin, pull_mode=gpio_mode)
116
117
 
118
+ def set_press_callback(self, press_callback: Callable[[ClickTypes, str, bool | None], None]) -> None:
119
+ self._press_callback = press_callback
120
+
117
121
  @property
118
122
  def is_pressed(self) -> bool:
119
123
  """Is button pressed."""
120
124
  return read_input(self._pin)
125
+
126
+ @property
127
+ def pin(self) -> str:
128
+ """Return configured pin."""
129
+ return self._pin
@@ -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=RELAY, topic=topic, id=id, **kwargs)
51
- msg["command_topic"] = f"{topic}/cmd/{RELAY}/{id}/set"
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=RELAY, topic=topic, id=id, **kwargs)
85
- msg["command_topic"] = f"{topic}/cmd/relay/{id}/set"
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 }}"