boneIO 0.6.0dev3__py3-none-any.whl → 0.6.0dev5__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.6.0.dev3.dist-info → boneIO-0.6.0.dev5.dist-info}/METADATA +14 -14
- {boneIO-0.6.0.dev3.dist-info → boneIO-0.6.0.dev5.dist-info}/RECORD +28 -27
- boneIO-0.6.0.dev5.dist-info/WHEEL +4 -0
- boneio/bonecli.py +9 -3
- boneio/const.py +2 -1
- boneio/helper/__init__.py +2 -0
- boneio/helper/click_timer.py +37 -0
- boneio/helper/config.py +32 -6
- boneio/helper/events.py +65 -5
- boneio/helper/exceptions.py +5 -0
- boneio/helper/gpio.py +2 -2
- boneio/helper/ha_discovery.py +9 -3
- boneio/helper/loader.py +1 -0
- boneio/helper/mqtt.py +2 -2
- boneio/helper/yaml_util.py +4 -6
- boneio/input/gpio.py +50 -98
- boneio/manager.py +56 -33
- boneio/mqtt_client.py +43 -17
- boneio/relay/basic.py +3 -4
- boneio/runner.py +20 -9
- boneio/schema/actions.yaml +2 -1
- boneio/schema/actions_sensor.yaml +1 -1
- boneio/schema/actions_switch.yaml +1 -1
- boneio/schema/schema.yaml +6 -0
- boneio/sensor/gpio.py +13 -12
- boneio/version.py +1 -1
- boneIO-0.6.0.dev3.dist-info/WHEEL +0 -4
- {boneIO-0.6.0.dev3.dist-info → boneIO-0.6.0.dev5.dist-info}/entry_points.txt +0 -0
- {boneIO-0.6.0.dev3.dist-info → boneIO-0.6.0.dev5.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: boneIO
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.0dev5
|
|
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>
|
|
7
7
|
Requires-Python: >=3.7
|
|
8
8
|
Requires-Dist: Adafruit-BBIO>=1.2.0
|
|
9
|
-
Requires-Dist: Adafruit-Blinka>=8.0
|
|
9
|
+
Requires-Dist: Adafruit-Blinka>=8.19.0
|
|
10
10
|
Requires-Dist: Cerberus>=1.3.4
|
|
11
11
|
Requires-Dist: PyYAML>=6.0
|
|
12
|
-
Requires-Dist: adafruit-circuitpython-ds18x20>=1.3.
|
|
13
|
-
Requires-Dist: adafruit-circuitpython-mcp230xx>=2.5.
|
|
14
|
-
Requires-Dist: adafruit-circuitpython-mcp9808>=3.3.
|
|
15
|
-
Requires-Dist: adafruit-circuitpython-onewire>=2.0.
|
|
16
|
-
Requires-Dist: adafruit-circuitpython-pca9685>=3.4.
|
|
17
|
-
Requires-Dist: adafruit-circuitpython-pct2075>=1.1.
|
|
18
|
-
Requires-Dist: asyncio-mqtt>=0.
|
|
19
|
-
Requires-Dist: colorlog>=6.
|
|
20
|
-
Requires-Dist: gpio>=0.
|
|
21
|
-
Requires-Dist: luma
|
|
22
|
-
Requires-Dist: luma
|
|
23
|
-
Requires-Dist: psutil>=5.9.
|
|
12
|
+
Requires-Dist: adafruit-circuitpython-ds18x20>=1.3.16
|
|
13
|
+
Requires-Dist: adafruit-circuitpython-mcp230xx>=2.5.9
|
|
14
|
+
Requires-Dist: adafruit-circuitpython-mcp9808>=3.3.19
|
|
15
|
+
Requires-Dist: adafruit-circuitpython-onewire>=2.0.4
|
|
16
|
+
Requires-Dist: adafruit-circuitpython-pca9685>=3.4.8
|
|
17
|
+
Requires-Dist: adafruit-circuitpython-pct2075>=1.1.18
|
|
18
|
+
Requires-Dist: asyncio-mqtt>=0.16.1
|
|
19
|
+
Requires-Dist: colorlog>=6.7.0
|
|
20
|
+
Requires-Dist: gpio>=1.0.0
|
|
21
|
+
Requires-Dist: luma-core>=2.4.0
|
|
22
|
+
Requires-Dist: luma-oled>=3.12.0
|
|
23
|
+
Requires-Dist: psutil>=5.9.5
|
|
24
24
|
Requires-Dist: pymodbus>=2.5.3
|
|
25
25
|
Requires-Dist: pyserial-asyncio>=0.6
|
|
26
26
|
Requires-Dist: w1thermsensor[async]>=2.0.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
boneio/__init__.py,sha256=hoLKnu6h1uEsiCHA9Ql2MMDC7VQS0E-s_2cxBS-CTOg,147
|
|
2
|
-
boneio/bonecli.py,sha256=
|
|
3
|
-
boneio/const.py,sha256=
|
|
2
|
+
boneio/bonecli.py,sha256=VhY1BMt6OaZz-752UjhEexdn8fDJkJaDWcGQNhCmgN0,3341
|
|
3
|
+
boneio/const.py,sha256=jowaP49OLdHOK2Bop2KDVPVKRVbqjBPHl_Fgl5aRzIg,2924
|
|
4
4
|
boneio/cover.py,sha256=nr76ft5smAPdBB8Jytk-uFd6RWuqtcZiG6EE129OUjw,8454
|
|
5
5
|
boneio/example_config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
6
|
boneio/example_config/adc.yaml,sha256=KaNfPuZmrhpiKJVUKC6uQXQ0YRCp0DoXVxYtqsbiSGI,168
|
|
@@ -11,17 +11,18 @@ boneio/example_config/led32x4A.yaml,sha256=YkcZ5XH2JF9Oa3pAmrYM5wsE8qQODCHcjYH47
|
|
|
11
11
|
boneio/example_config/output24x16A.yaml,sha256=BTtHToRgz-U_rMMDbmHkM4wQxHakdzInb3zKMkOkj4w,1691
|
|
12
12
|
boneio/example_config/output32x5A.yaml,sha256=G2Pb6qL8mXs6MliIM1roAanPag9ozRe3McYYuFsiBc0,2403
|
|
13
13
|
boneio/fonts/danube__.ttf,sha256=KBRPUcGvmroCjrWC8zK4MulUb9lV8R0lXkOY7lNnQWc,19372
|
|
14
|
-
boneio/helper/__init__.py,sha256=
|
|
14
|
+
boneio/helper/__init__.py,sha256=r-9dubCtDlrs_HFF2OGPQEPmw1XREgb4qQF6I486Li4,2039
|
|
15
15
|
boneio/helper/async_updater.py,sha256=BVh5mXFxgaZqoekjQbQSCTssfyVIdCQ80LCJny-rOo4,985
|
|
16
|
-
boneio/helper/
|
|
17
|
-
boneio/helper/
|
|
18
|
-
boneio/helper/
|
|
16
|
+
boneio/helper/click_timer.py,sha256=blWofzFIwuYcF_yFfCGDtI8nGSMpSdXdl9qMLXlKdXc,1169
|
|
17
|
+
boneio/helper/config.py,sha256=hhM4KUNaAFVXgQ1ZX56Zu7XV0pjp636vrcBuwoTH18g,2233
|
|
18
|
+
boneio/helper/events.py,sha256=EHYJy507RF1LikWQ2s4r990JRvR9rO4z7FkaJqt1Mrk,7494
|
|
19
|
+
boneio/helper/exceptions.py,sha256=vyYSUojwB7OttOPUjbxeHFM7C_o5ZQmRUcZ_vYpxYYI,717
|
|
19
20
|
boneio/helper/filter.py,sha256=UcjifjaC5wHDW2He7wmwCX2IjSSeLVhXyhrXHeT8RmA,885
|
|
20
|
-
boneio/helper/gpio.py,sha256=
|
|
21
|
-
boneio/helper/ha_discovery.py,sha256=
|
|
22
|
-
boneio/helper/loader.py,sha256=
|
|
21
|
+
boneio/helper/gpio.py,sha256=v4QrJfwlhIOqRCcD1SCpwPVcY6zsTlm1tens0eLbazM,2718
|
|
22
|
+
boneio/helper/ha_discovery.py,sha256=s80gwx1Fik2_vtq-6kqabUqPx4KwwZUt4G1Oy6RgGgU,6278
|
|
23
|
+
boneio/helper/loader.py,sha256=dKlk42tI7RkyI_FmX6CneN3FIGnHQ55c20sfn11B_bk,13547
|
|
23
24
|
boneio/helper/logger.py,sha256=zyF_Vk3o2eSHuXypJhNzK99eZgkWDWybuB5KcJgurDs,1801
|
|
24
|
-
boneio/helper/mqtt.py,sha256=
|
|
25
|
+
boneio/helper/mqtt.py,sha256=UVa4KaxvVif6By_sVMdSMiYI_doZjiXF4LS9RFltxJk,765
|
|
25
26
|
boneio/helper/oled.py,sha256=f0XYbaFstUbJ6ISmFe1vQCnmNVMctQWtnStNdROrblc,351
|
|
26
27
|
boneio/helper/onewire/W1ThermSensor.py,sha256=Pu5Fp29pKbxjJqDbFs05Mjg3Vy-9z_DTVoBpSWM_byA,2430
|
|
27
28
|
boneio/helper/onewire/__init__.py,sha256=4djH-uxiq5XhAiFTOxyqjvWVoJe0c8U8iN0BfmH8nSU,448
|
|
@@ -32,31 +33,31 @@ boneio/helper/state_manager.py,sha256=LsMQRrD7WXu5jXFoltYXvzHDeiNDDEx6UWYebFw18g
|
|
|
32
33
|
boneio/helper/stats.py,sha256=eLz3-g6cyaClZ7N1YVEuKVg-P6MAhuKX8D-cm5Nj-k8,5693
|
|
33
34
|
boneio/helper/timeperiod.py,sha256=xpg9oe30Z5WiLDQPq3EBKKScejOnN47NhcpeFvDd3bY,5806
|
|
34
35
|
boneio/helper/util.py,sha256=QfSoT3H3WnOQAKO5bFRIBCy62HT5NMa9Ek-FmfTW_rw,508
|
|
35
|
-
boneio/helper/yaml_util.py,sha256=
|
|
36
|
+
boneio/helper/yaml_util.py,sha256=gAX7hCaHUlPgkhGCIQ4zjv0Vj9JmLzQsSyF51ZmSb9g,11304
|
|
36
37
|
boneio/input/__init__.py,sha256=u9wuehuC_TNizL4tyn7EygZW5LaTFjSnFaZeZr3zZ1U,99
|
|
37
|
-
boneio/input/gpio.py,sha256=
|
|
38
|
-
boneio/manager.py,sha256=
|
|
38
|
+
boneio/input/gpio.py,sha256=7teo2fDyDUarorCn9REF5sGFMIimRrWaKOqildYG8_Y,2597
|
|
39
|
+
boneio/manager.py,sha256=cs2vy-26kvQROWHjHopACY2U1OLufcsu522RjShVXyQ,21023
|
|
39
40
|
boneio/modbus.py,sha256=eA_sGnmdcIneXX75ZcXOI223-UkKN1UYmWFqiJBAhJo,4176
|
|
40
|
-
boneio/mqtt_client.py,sha256=
|
|
41
|
+
boneio/mqtt_client.py,sha256=NYvok8y_g8iRXDopVojzcDGVnDJEFqHBEYhOGy8m7T8,8331
|
|
41
42
|
boneio/oled.py,sha256=d_ofDQHc7zr3j0qOR0B_L3C8TJhvRH85nnb9Le-88nk,5244
|
|
42
43
|
boneio/relay/__init__.py,sha256=iLEUL8kxnEndCQtgDIJfHqUZOfyWfWmuOrqSYAUxb2w,181
|
|
43
|
-
boneio/relay/basic.py,sha256=
|
|
44
|
+
boneio/relay/basic.py,sha256=QEWG8HodBqEqLpQxcQm29hdPIxO7c6ep0uDgfo3pcco,2623
|
|
44
45
|
boneio/relay/gpio.py,sha256=s64FBf6zlxciF57xJ6nrvy0t5Rie0uiXlwos0HL3RKM,1163
|
|
45
46
|
boneio/relay/mcp.py,sha256=DhgqZbFHB6TucL9hJaJiqdVAbkw4Rv5VPHm_khSBIFo,2669
|
|
46
47
|
boneio/relay/pca.py,sha256=tCwXvMJcsxzFj48ZO2tPYyvElZfyIRTFmEMp7ENKvtk,4873
|
|
47
|
-
boneio/runner.py,sha256=
|
|
48
|
-
boneio/schema/actions.yaml,sha256=
|
|
49
|
-
boneio/schema/actions_sensor.yaml,sha256=
|
|
50
|
-
boneio/schema/actions_switch.yaml,sha256=
|
|
48
|
+
boneio/runner.py,sha256=eLRd3NtE8c5fqYu76B4Kz7vs5ftNDSZ_L-KHbipRu90,2569
|
|
49
|
+
boneio/schema/actions.yaml,sha256=WD0LR9SxVPgwU12x10RvFaTeyDiCjdRiicfkrCGLNvc,1030
|
|
50
|
+
boneio/schema/actions_sensor.yaml,sha256=U_VfdjqdorQZHYD6dZOzhlRKnOGwsnTJ3CDGiqrKxW8,124
|
|
51
|
+
boneio/schema/actions_switch.yaml,sha256=sdqhwz0LrcfaiAN3-RfAR_xApxo5dh9RxXQubuKcsjk,129
|
|
51
52
|
boneio/schema/filters.yaml,sha256=WopX1SmCZsSZXNiGccLoi7uMCsUpdbs0eVfsAjmbay4,286
|
|
52
53
|
boneio/schema/filters_adc.yaml,sha256=3e0ts92MoFKOnfGOOn6WYIHxu0-tnZe9OjAjN9m7hiI,304
|
|
53
54
|
boneio/schema/id.yaml,sha256=vHI_6dxkJwoiGp5ien_pPpyaWA1F06eirTgfWMyWa1E,75
|
|
54
|
-
boneio/schema/schema.yaml,sha256=
|
|
55
|
+
boneio/schema/schema.yaml,sha256=GHqcUaCUJypX2JD7tXVKoIZ3XO4rqLaoHW0ppWFWvzU,12988
|
|
55
56
|
boneio/schema/temp_unit.yaml,sha256=m32VGz9RTW92Lz08l9n6RftkcVNZquOGPPr5mc3eZVc,65
|
|
56
57
|
boneio/schema/update_interval.yaml,sha256=L_YLddAZdybcdO-T57Qhlv1GaWIVDwhvH-GadD1oOIo,133
|
|
57
58
|
boneio/sensor/__init__.py,sha256=VjFBEQQv_U0T2ENkzefuBdzmqNvBTEv4M-gQKScc8o0,431
|
|
58
59
|
boneio/sensor/adc.py,sha256=Yf5F8JcZJt0K4ijpPqI8do0BqDfLvfja_LE8_Zu3u7U,1281
|
|
59
|
-
boneio/sensor/gpio.py,sha256=
|
|
60
|
+
boneio/sensor/gpio.py,sha256=oAUYHGLX0_JK6AJMplmDBnLBIAZ2GaDJ7ts8AceljvQ,1303
|
|
60
61
|
boneio/sensor/modbus/__init__.py,sha256=LEOnMqBACNxZmCN2adZtTsq76gPbsNba5JewMiUENBw,8500
|
|
61
62
|
boneio/sensor/modbus/dts1964_3f.json,sha256=WABph_2X4OgMidSM28vw4dLd9ZByRoiUP-RqE0UMpR8,8810
|
|
62
63
|
boneio/sensor/modbus/pt100.json,sha256=bzKNYDc3lMto94Ut8gutVIsHytQiMobwFCkonOiMegs,526
|
|
@@ -68,9 +69,9 @@ boneio/sensor/temp/__init__.py,sha256=h5rGbkC8K6y2GJSNHtm9f8EmoBS3wFlSNIFjcrRj47
|
|
|
68
69
|
boneio/sensor/temp/dallas.py,sha256=xrvd1LNBh1fRcjz_yd_9S29Lv26ItVtLCmhZgVQWJos,2485
|
|
69
70
|
boneio/sensor/temp/lm75.py,sha256=-mpOv78429plRPBp9s09Ljz1x2Bdxuagalqz40vlAKE,243
|
|
70
71
|
boneio/sensor/temp/mcp9808.py,sha256=yAh5yJzZLGTqa39xV4fyqsruj7oy3niOZAUV2W6eyCM,271
|
|
71
|
-
boneio/version.py,sha256=
|
|
72
|
-
boneIO-0.6.0.
|
|
73
|
-
boneIO-0.6.0.
|
|
74
|
-
boneIO-0.6.0.
|
|
75
|
-
boneIO-0.6.0.
|
|
76
|
-
boneIO-0.6.0.
|
|
72
|
+
boneio/version.py,sha256=MRoHBbiT0xKVNIGf8uc_weaaaOMvuoXa9HcssIlg3_0,41
|
|
73
|
+
boneIO-0.6.0.dev5.dist-info/entry_points.txt,sha256=Igl1SMDEWwMg144bwRz28UOCb80hdxomC99QJ3u6qC0,46
|
|
74
|
+
boneIO-0.6.0.dev5.dist-info/WHEEL,sha256=B19PGBCYhWaz2p_UjAoRVh767nYQfk14Sn4TpIZ-nfU,87
|
|
75
|
+
boneIO-0.6.0.dev5.dist-info/METADATA,sha256=b5xgbS9_foPU_jVQq9CPRUDE1XV9Ceq_LlI0e6KBz9U,1698
|
|
76
|
+
boneIO-0.6.0.dev5.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
77
|
+
boneIO-0.6.0.dev5.dist-info/RECORD,,
|
boneio/bonecli.py
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"""Bonecli script."""
|
|
2
|
+
from __future__ import annotations
|
|
2
3
|
import argparse
|
|
3
4
|
import asyncio
|
|
4
5
|
import logging
|
|
5
6
|
import sys
|
|
6
7
|
import os
|
|
8
|
+
from typing import Any
|
|
7
9
|
|
|
8
10
|
os.environ["W1THERMSENSOR_NO_KERNEL_MODULE"] = "1"
|
|
9
11
|
|
|
@@ -12,7 +14,7 @@ from yaml import MarkedYAMLError
|
|
|
12
14
|
|
|
13
15
|
from boneio.const import ACTION
|
|
14
16
|
from boneio.helper import load_config_from_file
|
|
15
|
-
from boneio.helper.exceptions import ConfigurationException
|
|
17
|
+
from boneio.helper.exceptions import ConfigurationException, RestartRequestException
|
|
16
18
|
from boneio.helper.logger import configure_logger
|
|
17
19
|
from boneio.runner import async_run
|
|
18
20
|
from boneio.version import __version__
|
|
@@ -69,7 +71,7 @@ def get_arguments() -> argparse.Namespace:
|
|
|
69
71
|
return arguments
|
|
70
72
|
|
|
71
73
|
|
|
72
|
-
def run(config: str, debug: int, mqttusername: str = "", mqttpassword: str = ""):
|
|
74
|
+
def run(config: str, debug: int, mqttusername: str = "", mqttpassword: str = "") -> int:
|
|
73
75
|
"""Run BoneIO."""
|
|
74
76
|
_LOGGER.info("BoneIO %s starting.", __version__)
|
|
75
77
|
try:
|
|
@@ -78,7 +80,7 @@ def run(config: str, debug: int, mqttusername: str = "", mqttpassword: str = "")
|
|
|
78
80
|
_LOGGER.error("Config not loaded. Exiting.")
|
|
79
81
|
return 1
|
|
80
82
|
configure_logger(log_config=_config.get("logger"), debug=debug)
|
|
81
|
-
|
|
83
|
+
asyncio.run(
|
|
82
84
|
async_run(
|
|
83
85
|
config=_config,
|
|
84
86
|
config_file=config,
|
|
@@ -86,6 +88,10 @@ def run(config: str, debug: int, mqttusername: str = "", mqttpassword: str = "")
|
|
|
86
88
|
mqttpassword=mqttpassword,
|
|
87
89
|
),
|
|
88
90
|
)
|
|
91
|
+
return 0
|
|
92
|
+
except RestartRequestException as err:
|
|
93
|
+
_LOGGER.info(err)
|
|
94
|
+
return 0
|
|
89
95
|
except (ConfigurationException, MarkedYAMLError) as err:
|
|
90
96
|
_LOGGER.error("Failed to load config. %s Exiting.", err)
|
|
91
97
|
return 1
|
boneio/const.py
CHANGED
|
@@ -18,6 +18,7 @@ RELAY = "relay"
|
|
|
18
18
|
LED = "led"
|
|
19
19
|
ON = "ON"
|
|
20
20
|
OFF = "OFF"
|
|
21
|
+
TOGGLE = "TOGGLE"
|
|
21
22
|
STATE = "state"
|
|
22
23
|
BRIGHTNESS = "brightness"
|
|
23
24
|
SET_BRIGHTNESS = "set_brightness"
|
|
@@ -55,7 +56,7 @@ UARTS = {
|
|
|
55
56
|
"uart5": {ID: "/dev/ttyS5", TX: "P8.37", RX: "P8.38"},
|
|
56
57
|
}
|
|
57
58
|
|
|
58
|
-
relay_actions = {ON: "turn_on", OFF: "turn_off",
|
|
59
|
+
relay_actions = {ON: "turn_on", OFF: "turn_off", TOGGLE: "toggle"}
|
|
59
60
|
|
|
60
61
|
# HA CONSTS
|
|
61
62
|
HOMEASSISTANT = "homeassistant"
|
boneio/helper/__init__.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""Helper dir for BoneIO."""
|
|
2
2
|
|
|
3
3
|
from boneio.helper.exceptions import GPIOInputException, GPIOOutputException, I2CError
|
|
4
|
+
from boneio.helper.click_timer import ClickTimer
|
|
4
5
|
from boneio.helper.gpio import (
|
|
5
6
|
GpioBaseClass,
|
|
6
7
|
configure_pin,
|
|
@@ -70,4 +71,5 @@ __all__ = [
|
|
|
70
71
|
"TimePeriod",
|
|
71
72
|
"callback",
|
|
72
73
|
"is_callback",
|
|
74
|
+
"ClickTimer",
|
|
73
75
|
]
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
import asyncio
|
|
3
|
+
from boneio.helper.events import async_call_later_miliseconds
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ClickTimer:
|
|
7
|
+
"""Represent async call later function with variable to check if timing is ON."""
|
|
8
|
+
|
|
9
|
+
def __init__(self, delay: float, action) -> None:
|
|
10
|
+
"""Initialize Click timer."""
|
|
11
|
+
self._loop = asyncio.get_running_loop()
|
|
12
|
+
self._remove_listener = None
|
|
13
|
+
self._delay = delay
|
|
14
|
+
self._action = action
|
|
15
|
+
|
|
16
|
+
def is_waiting(self) -> bool:
|
|
17
|
+
"""If variable is set then timer is ON, if None is Off."""
|
|
18
|
+
return self._remove_listener is not None
|
|
19
|
+
|
|
20
|
+
def action(self, x: float) -> None:
|
|
21
|
+
"""Reset Call later variable and call action."""
|
|
22
|
+
self.reset()
|
|
23
|
+
self._action(x)
|
|
24
|
+
|
|
25
|
+
def reset(self) -> None:
|
|
26
|
+
"""Uninitialize variable remove_listener."""
|
|
27
|
+
if self._remove_listener:
|
|
28
|
+
self._remove_listener()
|
|
29
|
+
self._remove_listener = None
|
|
30
|
+
|
|
31
|
+
def start_timer(self) -> None:
|
|
32
|
+
"""Start timer."""
|
|
33
|
+
self._remove_listener = async_call_later_miliseconds(
|
|
34
|
+
loop=self._loop,
|
|
35
|
+
action=self.action,
|
|
36
|
+
delay=self._delay,
|
|
37
|
+
)
|
boneio/helper/config.py
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Module to provide basic config options.
|
|
3
3
|
"""
|
|
4
|
+
from __future__ import annotations
|
|
4
5
|
from _collections_abc import dict_values
|
|
5
|
-
|
|
6
|
-
from boneio.const import BONEIO, HOMEASSISTANT
|
|
6
|
+
from boneio.const import BONEIO, HOMEASSISTANT, LIGHT, SENSOR, COVER, BUTTON, SWITCH, BINARY_SENSOR
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class ConfigHelper:
|
|
@@ -16,7 +16,16 @@ class ConfigHelper:
|
|
|
16
16
|
self._topic_prefix = topic_prefix
|
|
17
17
|
self._ha_discovery = ha_discovery
|
|
18
18
|
self._ha_discovery_prefix = ha_discovery_prefix
|
|
19
|
-
self.
|
|
19
|
+
self._fetch_old_discovery = None
|
|
20
|
+
self._autodiscovery_messages = {
|
|
21
|
+
SWITCH: {},
|
|
22
|
+
LIGHT: {},
|
|
23
|
+
BINARY_SENSOR: {},
|
|
24
|
+
SENSOR: {},
|
|
25
|
+
COVER: {},
|
|
26
|
+
BUTTON: {}
|
|
27
|
+
}
|
|
28
|
+
self.manager_ready: bool = False
|
|
20
29
|
|
|
21
30
|
@property
|
|
22
31
|
def topic_prefix(self) -> str:
|
|
@@ -38,11 +47,28 @@ class ConfigHelper:
|
|
|
38
47
|
def subscribe_topic(self) -> str:
|
|
39
48
|
return f"{self.cmd_topic_prefix}+/+/#"
|
|
40
49
|
|
|
41
|
-
def add_autodiscovery_msg(self, topic: str, payload: str):
|
|
50
|
+
def add_autodiscovery_msg(self, ha_type: str, topic: str, payload: str):
|
|
42
51
|
"""Add autodiscovery message."""
|
|
43
|
-
self._autodiscovery_messages[topic] = {"topic": topic, "payload": payload}
|
|
52
|
+
self._autodiscovery_messages[ha_type][topic] = {"topic": topic, "payload": payload}
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def ha_types(self) -> list[str]:
|
|
56
|
+
return list(self._autodiscovery_messages.keys())
|
|
57
|
+
|
|
58
|
+
def is_topic_in_autodiscovery(self, topic: str) -> bool:
|
|
59
|
+
topic_parts_raw = topic[len(f"{self._ha_discovery_prefix}/") :].split("/")
|
|
60
|
+
ha_type = topic_parts_raw[0]
|
|
61
|
+
if ha_type in self._autodiscovery_messages:
|
|
62
|
+
if topic in self._autodiscovery_messages[ha_type]:
|
|
63
|
+
return True
|
|
64
|
+
return False
|
|
65
|
+
|
|
66
|
+
|
|
44
67
|
|
|
45
68
|
@property
|
|
46
69
|
def autodiscovery_msgs(self) -> dict_values:
|
|
47
70
|
"""Get autodiscovery messages"""
|
|
48
|
-
|
|
71
|
+
output = {}
|
|
72
|
+
for ha_type in self._autodiscovery_messages:
|
|
73
|
+
output.update(self._autodiscovery_messages[ha_type])
|
|
74
|
+
return output.values()
|
boneio/helper/events.py
CHANGED
|
@@ -21,7 +21,9 @@ def utcnow() -> dt.datetime:
|
|
|
21
21
|
time_tracker_utcnow = utcnow
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
def _async_create_timer(
|
|
24
|
+
def _async_create_timer(
|
|
25
|
+
loop: asyncio.AbstractEventLoop, event_callback
|
|
26
|
+
) -> CALLBACK_TYPE:
|
|
25
27
|
"""Create a timer that will start on BoneIO start."""
|
|
26
28
|
handle = None
|
|
27
29
|
|
|
@@ -149,6 +151,7 @@ def async_track_point_in_time(
|
|
|
149
151
|
"""Add a listener that fires once after a specific point in UTC time."""
|
|
150
152
|
# Ensure point_in_time is UTC
|
|
151
153
|
utc_point_in_time = as_utc(point_in_time)
|
|
154
|
+
expected_fire_timestamp = utc_point_in_time.timestamp()
|
|
152
155
|
|
|
153
156
|
# Since this is called once, we accept a so we can avoid
|
|
154
157
|
# having to figure out how to call the action every time its called.
|
|
@@ -159,14 +162,12 @@ def async_track_point_in_time(
|
|
|
159
162
|
"""Call the action."""
|
|
160
163
|
nonlocal cancel_callback
|
|
161
164
|
|
|
162
|
-
now = time_tracker_utcnow()
|
|
163
|
-
|
|
164
165
|
# Depending on the available clock support (including timer hardware
|
|
165
166
|
# and the OS kernel) it can happen that we fire a little bit too early
|
|
166
167
|
# as measured by utcnow(). That is bad when callbacks have assumptions
|
|
167
168
|
# about the current time. Thus, we rearm the timer for the remaining
|
|
168
169
|
# time.
|
|
169
|
-
delta =
|
|
170
|
+
delta = expected_fire_timestamp - time.time()
|
|
170
171
|
if delta > 0:
|
|
171
172
|
_LOGGER.debug("Called %f seconds too early, rearming", delta)
|
|
172
173
|
|
|
@@ -175,7 +176,52 @@ def async_track_point_in_time(
|
|
|
175
176
|
|
|
176
177
|
loop.call_soon(job, utc_point_in_time)
|
|
177
178
|
|
|
178
|
-
delta =
|
|
179
|
+
delta = expected_fire_timestamp - time.time()
|
|
180
|
+
cancel_callback = loop.call_later(delta, run_action, action)
|
|
181
|
+
|
|
182
|
+
@callback
|
|
183
|
+
def unsub_point_in_time_listener() -> None:
|
|
184
|
+
"""Cancel the call_later."""
|
|
185
|
+
assert cancel_callback is not None
|
|
186
|
+
cancel_callback.cancel()
|
|
187
|
+
|
|
188
|
+
return unsub_point_in_time_listener
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
@callback
|
|
192
|
+
def async_track_point_in_timestamp(
|
|
193
|
+
loop: asyncio.AbstractEventLoop,
|
|
194
|
+
action,
|
|
195
|
+
timestamp: float,
|
|
196
|
+
) -> CALLBACK_TYPE:
|
|
197
|
+
"""Add a listener that fires once after a specific point in UTC time."""
|
|
198
|
+
# Since this is called once, we accept a so we can avoid
|
|
199
|
+
# having to figure out how to call the action every time its called.
|
|
200
|
+
cancel_callback: Optional[asyncio.TimerHandle] = None
|
|
201
|
+
|
|
202
|
+
@callback
|
|
203
|
+
def run_action(job) -> None:
|
|
204
|
+
"""Call the action."""
|
|
205
|
+
nonlocal cancel_callback
|
|
206
|
+
|
|
207
|
+
now = time.time()
|
|
208
|
+
|
|
209
|
+
# Depending on the available clock support (including timer hardware
|
|
210
|
+
# and the OS kernel) it can happen that we fire a little bit too early
|
|
211
|
+
# as measured by utcnow(). That is bad when callbacks have assumptions
|
|
212
|
+
# about the current time. Thus, we rearm the timer for the remaining
|
|
213
|
+
# time.
|
|
214
|
+
delta = timestamp - now
|
|
215
|
+
if delta > 0:
|
|
216
|
+
_LOGGER.debug("Called %f seconds too early, rearming", delta)
|
|
217
|
+
|
|
218
|
+
cancel_callback = loop.call_later(delta, run_action, job)
|
|
219
|
+
return
|
|
220
|
+
|
|
221
|
+
loop.call_soon(job, timestamp)
|
|
222
|
+
|
|
223
|
+
now = time.time()
|
|
224
|
+
delta = timestamp - now
|
|
179
225
|
cancel_callback = loop.call_later(delta, run_action, action)
|
|
180
226
|
|
|
181
227
|
@callback
|
|
@@ -185,3 +231,17 @@ def async_track_point_in_time(
|
|
|
185
231
|
cancel_callback.cancel()
|
|
186
232
|
|
|
187
233
|
return unsub_point_in_time_listener
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
@callback
|
|
237
|
+
def async_call_later_miliseconds(
|
|
238
|
+
loop: asyncio.AbstractEventLoop,
|
|
239
|
+
action,
|
|
240
|
+
delay: float,
|
|
241
|
+
) -> CALLBACK_TYPE:
|
|
242
|
+
"""Add a listener that fires once after a specific point in UTC time."""
|
|
243
|
+
# Ensure point_in_time is UTC
|
|
244
|
+
expected_fire_timestamp = time.time() + (delay / 1000)
|
|
245
|
+
return async_track_point_in_timestamp(
|
|
246
|
+
loop=loop, action=action, timestamp=expected_fire_timestamp
|
|
247
|
+
)
|
boneio/helper/exceptions.py
CHANGED
|
@@ -8,6 +8,7 @@ class BoneIOException(Exception):
|
|
|
8
8
|
class GPIOInputException(BoneIOException):
|
|
9
9
|
"""GPIOInput Exception."""
|
|
10
10
|
|
|
11
|
+
|
|
11
12
|
class GPIOOutputException(BoneIOException):
|
|
12
13
|
"""GPIOInput Exception."""
|
|
13
14
|
|
|
@@ -30,3 +31,7 @@ class CoverRelayException(BoneIOException):
|
|
|
30
31
|
|
|
31
32
|
class ModbusUartException(BoneIOException):
|
|
32
33
|
"""Cover configuration exception."""
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class RestartRequestException(BoneIOException):
|
|
37
|
+
"""Restart exception."""
|
boneio/helper/gpio.py
CHANGED
|
@@ -67,7 +67,7 @@ def write_output(pin: str, value: str) -> None:
|
|
|
67
67
|
GPIO.output(pin, value)
|
|
68
68
|
|
|
69
69
|
|
|
70
|
-
def read_input(pin: str, on_state: Gpio_States = LOW) ->
|
|
70
|
+
def read_input(pin: str, on_state: Gpio_States = LOW) -> bool:
|
|
71
71
|
"""Read a value from a GPIO."""
|
|
72
72
|
return GPIO.input(pin) is on_state
|
|
73
73
|
|
|
@@ -97,6 +97,6 @@ class GpioBaseClass:
|
|
|
97
97
|
setup_input(pin=self._pin, pull_mode=gpio_mode)
|
|
98
98
|
|
|
99
99
|
@property
|
|
100
|
-
def is_pressed(self):
|
|
100
|
+
def is_pressed(self) -> bool:
|
|
101
101
|
"""Is button pressed."""
|
|
102
102
|
return read_input(self._pin)
|
boneio/helper/ha_discovery.py
CHANGED
|
@@ -51,6 +51,7 @@ def ha_light_availabilty_message(id: str, topic: str = "boneIO", **kwargs):
|
|
|
51
51
|
msg["state_value_template"] = "{{ value_json.state }}"
|
|
52
52
|
return msg
|
|
53
53
|
|
|
54
|
+
|
|
54
55
|
def ha_led_availabilty_message(id: str, topic: str = "boneIO", **kwargs):
|
|
55
56
|
"""Create LED availability topic for HA."""
|
|
56
57
|
msg = ha_availabilty_message(device_type=RELAY, topic=topic, id=id, **kwargs)
|
|
@@ -64,11 +65,14 @@ def ha_led_availabilty_message(id: str, topic: str = "boneIO", **kwargs):
|
|
|
64
65
|
msg["brightness_value_template"] = "{{ value_json.brightness }}"
|
|
65
66
|
return msg
|
|
66
67
|
|
|
67
|
-
|
|
68
|
+
|
|
69
|
+
def ha_button_availabilty_message(
|
|
70
|
+
id: str, topic: str = "boneIO", payload_press: str = "reload", **kwargs
|
|
71
|
+
):
|
|
68
72
|
"""Create BUTTON availability topic for HA."""
|
|
69
73
|
msg = ha_availabilty_message(device_type="button", topic=topic, id=id, **kwargs)
|
|
70
74
|
msg["command_topic"] = f"{topic}/cmd/button/{id}/set"
|
|
71
|
-
msg["payload_press"] =
|
|
75
|
+
msg["payload_press"] = payload_press
|
|
72
76
|
return msg
|
|
73
77
|
|
|
74
78
|
|
|
@@ -102,9 +106,11 @@ def ha_sensor_availabilty_message(unit_of_measurement: str = None, **kwargs):
|
|
|
102
106
|
return msg
|
|
103
107
|
|
|
104
108
|
|
|
105
|
-
def ha_binary_sensor_availabilty_message(id: str, name: str, topic: str = "boneIO"):
|
|
109
|
+
def ha_binary_sensor_availabilty_message(id: str, name: str, device_class: str, topic: str = "boneIO"):
|
|
106
110
|
"""Create availability topic for HA."""
|
|
111
|
+
kwargs = {"device_class": device_class} if device_class else {}
|
|
107
112
|
return {
|
|
113
|
+
**kwargs,
|
|
108
114
|
"availability": [{"topic": f"{topic}/{STATE}"}],
|
|
109
115
|
"device": {
|
|
110
116
|
"identifiers": [topic],
|
boneio/helper/loader.py
CHANGED
boneio/helper/mqtt.py
CHANGED
|
@@ -21,11 +21,11 @@ class BasicMqtt:
|
|
|
21
21
|
self._send_topic = f"{topic_prefix}/{topic_type}/{self.id}"
|
|
22
22
|
|
|
23
23
|
@property
|
|
24
|
-
def id(self) ->
|
|
24
|
+
def id(self) -> str:
|
|
25
25
|
"""Id of the module."""
|
|
26
26
|
return self._id
|
|
27
27
|
|
|
28
28
|
@property
|
|
29
|
-
def name(self):
|
|
29
|
+
def name(self) -> str:
|
|
30
30
|
"""Return name of the sensor."""
|
|
31
31
|
return self._name
|
boneio/helper/yaml_util.py
CHANGED
|
@@ -8,7 +8,7 @@ from typing import Any, Tuple
|
|
|
8
8
|
from cerberus import TypeDefinition, Validator
|
|
9
9
|
from yaml import MarkedYAMLError, SafeLoader, YAMLError, load
|
|
10
10
|
|
|
11
|
-
from boneio.const import COVER, ID, OUTPUT
|
|
11
|
+
from boneio.const import COVER, ID, OUTPUT, TOGGLE
|
|
12
12
|
from boneio.helper.exceptions import ConfigurationException
|
|
13
13
|
from boneio.helper.timeperiod import TimePeriod
|
|
14
14
|
|
|
@@ -103,9 +103,7 @@ BoneIOLoader.add_constructor(
|
|
|
103
103
|
BoneIOLoader.add_constructor(
|
|
104
104
|
"!include_dir_merge_named", BoneIOLoader.construct_include_dir_merge_named
|
|
105
105
|
)
|
|
106
|
-
BoneIOLoader.add_constructor(
|
|
107
|
-
"!include_files", BoneIOLoader.construct_include_files
|
|
108
|
-
)
|
|
106
|
+
BoneIOLoader.add_constructor("!include_files", BoneIOLoader.construct_include_files)
|
|
109
107
|
|
|
110
108
|
|
|
111
109
|
def filter_yaml_files(files):
|
|
@@ -246,7 +244,7 @@ class CustomValidator(Validator):
|
|
|
246
244
|
return str(value).upper()
|
|
247
245
|
|
|
248
246
|
def _normalize_coerce_actions_output(self, value):
|
|
249
|
-
return str(value).
|
|
247
|
+
return str(value).upper()
|
|
250
248
|
|
|
251
249
|
def _normalize_coerce_str(self, value):
|
|
252
250
|
return str(value)
|
|
@@ -324,4 +322,4 @@ class CustomValidator(Validator):
|
|
|
324
322
|
|
|
325
323
|
parent = get_parent()
|
|
326
324
|
if parent["action"] == COVER:
|
|
327
|
-
return
|
|
325
|
+
return TOGGLE
|