boneIO 0.8.0.dev13__tar.gz → 0.8.0.dev15__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.dev13 → boneIO-0.8.0.dev15}/PKG-INFO +1 -1
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/cover.py +25 -6
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/modbus/client.py +57 -17
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/modbus/liquid-sensor.json +2 -2
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/modbus/modbuscli.py +5 -1
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/modbus/orno-or-we-517.json +1 -1
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/modbus/sensor.py +18 -6
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/modbus/utils.py +1 -1
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/mqtt_client.py +51 -22
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/sensor/temp/__init__.py +3 -2
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/sensor/temp/dallas.py +6 -1
- boneIO-0.8.0.dev15/boneio/version.py +2 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/pyproject.toml +1 -1
- boneIO-0.8.0.dev13/boneio/version.py +0 -2
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/LICENSE +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/README.md +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/__init__.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/bonecli.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/const.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/example_config/__init__.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/example_config/adc.yaml +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/example_config/binary_sensor.yaml +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/example_config/binary_sensor_v_0_7.yaml +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/example_config/config.yaml +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/example_config/cover.yaml +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/example_config/event.yaml +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/example_config/event_all.yaml +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/example_config/event_v_0_7.yaml +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/example_config/led32x4A.yaml +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/example_config/output24x16A.yaml +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/example_config/output24x16A_v0.3.yaml +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/example_config/output32x10A.yaml +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/example_config/output32x5A.yaml +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/fonts/danube__.ttf +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/group/__init__.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/group/output.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/helper/__init__.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/helper/async_updater.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/helper/click_timer.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/helper/config.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/helper/events.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/helper/exceptions.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/helper/filter.py +1 -1
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/helper/gpio.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/helper/gpiod.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/helper/ha_discovery.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/helper/loader.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/helper/logger.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/helper/mqtt.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/helper/oled.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/helper/onewire/W1ThermSensor.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/helper/onewire/__init__.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/helper/onewire/ds2482.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/helper/onewire/onewire.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/helper/pcf8575.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/helper/queue.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/helper/sensor/ina_219_smbus.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/helper/state_manager.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/helper/stats.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/helper/timeperiod.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/helper/util.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/helper/yaml_util.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/input/__init__.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/input/gpio.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/input/gpio_new.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/manager.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/modbus/__init__.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/modbus/cwt.json +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/modbus/dts1964_3f.json +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/modbus/pt100.json +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/modbus/r4dcb08.json +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/modbus/sdm120.json +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/modbus/sdm630.json +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/modbus/sht20.json +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/modbus/single_sensor.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/modbus/socomec_e03.json +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/modbus/socomec_e23.json +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/modbus/sofar.json +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/oled.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/relay/__init__.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/relay/basic.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/relay/gpio.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/relay/mcp.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/relay/pca.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/relay/pcf.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/runner.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/schema/actions.yaml +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/schema/actions_sensor.yaml +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/schema/actions_switch.yaml +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/schema/filters.yaml +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/schema/filters_adc.yaml +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/schema/id.yaml +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/schema/schema.yaml +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/schema/temp_unit.yaml +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/schema/update_interval.yaml +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/sensor/__init__.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/sensor/adc.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/sensor/gpio.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/sensor/gpio_new.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/sensor/ina219.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/sensor/temp/lm75.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/boneio/sensor/temp/mcp9808.py +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/tests/32_5_config.yaml +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/tests/bandit.yaml +0 -0
- {boneIO-0.8.0.dev13 → boneIO-0.8.0.dev15}/tests/relay_32_5.py +0 -0
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
"""Cover module."""
|
|
2
|
+
|
|
2
3
|
from __future__ import annotations
|
|
3
4
|
import asyncio
|
|
4
5
|
import logging
|
|
5
6
|
from typing import Callable
|
|
6
7
|
|
|
7
|
-
from boneio.const import
|
|
8
|
+
from boneio.const import (
|
|
9
|
+
CLOSE,
|
|
10
|
+
CLOSED,
|
|
11
|
+
CLOSING,
|
|
12
|
+
COVER,
|
|
13
|
+
IDLE,
|
|
14
|
+
OPEN,
|
|
15
|
+
OPENING,
|
|
16
|
+
STOP,
|
|
17
|
+
)
|
|
8
18
|
from boneio.helper.events import EventBus
|
|
9
19
|
from boneio.helper.mqtt import BasicMqtt
|
|
10
20
|
from boneio.helper.timeperiod import TimePeriod
|
|
@@ -121,7 +131,9 @@ class Cover(BasicMqtt):
|
|
|
121
131
|
|
|
122
132
|
def send_state(self) -> None:
|
|
123
133
|
"""Send state of cover to mqtt."""
|
|
124
|
-
self._send_message(
|
|
134
|
+
self._send_message(
|
|
135
|
+
topic=f"{self._send_topic}/state", payload=self.cover_state
|
|
136
|
+
)
|
|
125
137
|
pos = round(self._position, 0)
|
|
126
138
|
self._send_message(topic=f"{self._send_topic}/pos", payload=str(pos))
|
|
127
139
|
self._state_save(position=pos)
|
|
@@ -161,7 +173,9 @@ class Cover(BasicMqtt):
|
|
|
161
173
|
if self._set_position:
|
|
162
174
|
# Set position is only working for every 10%, so round to nearest 10.
|
|
163
175
|
# Except for start moving time
|
|
164
|
-
if (
|
|
176
|
+
if (
|
|
177
|
+
self._requested_closing and rounded_pos < 95
|
|
178
|
+
) or rounded_pos > 5:
|
|
165
179
|
rounded_pos = round(self._position, -1)
|
|
166
180
|
else:
|
|
167
181
|
if rounded_pos > 100:
|
|
@@ -170,7 +184,8 @@ class Cover(BasicMqtt):
|
|
|
170
184
|
rounded_pos = 0
|
|
171
185
|
self._send_message(topic=f"{self._send_topic}/pos", payload=rounded_pos)
|
|
172
186
|
if rounded_pos == self._set_position or (
|
|
173
|
-
self._set_position is None
|
|
187
|
+
self._set_position is None
|
|
188
|
+
and (rounded_pos >= 100 or rounded_pos <= 0)
|
|
174
189
|
):
|
|
175
190
|
self._position = rounded_pos
|
|
176
191
|
self._closed = self.current_cover_position <= 0
|
|
@@ -222,9 +237,13 @@ class Cover(BasicMqtt):
|
|
|
222
237
|
self._requested_closing = set_position < self._position
|
|
223
238
|
current_operation = CLOSING if self._requested_closing else OPENING
|
|
224
239
|
_LOGGER.debug(
|
|
225
|
-
"Requested set position %s. Operation %s",
|
|
240
|
+
"Requested set position %s. Operation %s",
|
|
241
|
+
set_position,
|
|
242
|
+
current_operation,
|
|
243
|
+
)
|
|
244
|
+
self._send_message(
|
|
245
|
+
topic=f"{self._send_topic}/state", payload=current_operation
|
|
226
246
|
)
|
|
227
|
-
self._send_message(topic=f"{self._send_topic}/state", payload=current_operation)
|
|
228
247
|
await self.run_cover(
|
|
229
248
|
current_operation=current_operation,
|
|
230
249
|
)
|
|
@@ -20,17 +20,61 @@ from boneio.helper.exceptions import ModbusUartException
|
|
|
20
20
|
_LOGGER = logging.getLogger(__name__)
|
|
21
21
|
|
|
22
22
|
VALUE_TYPES = {
|
|
23
|
-
"U_WORD": {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
"
|
|
23
|
+
"U_WORD": {
|
|
24
|
+
"f": "decode_16bit_uint",
|
|
25
|
+
"byteorder": Endian.Big,
|
|
26
|
+
"count": 1,
|
|
27
|
+
},
|
|
28
|
+
"S_WORD": {
|
|
29
|
+
"f": "decode_16bit_int",
|
|
30
|
+
"byteorder": Endian.Big,
|
|
31
|
+
"count": 1,
|
|
32
|
+
},
|
|
33
|
+
"U_DWORD": {
|
|
34
|
+
"f": "decode_32bit_uint",
|
|
35
|
+
"byteorder": Endian.Big,
|
|
36
|
+
"count": 2,
|
|
37
|
+
},
|
|
38
|
+
"S_DWORD": {
|
|
39
|
+
"f": "decode_32bit_int",
|
|
40
|
+
"byteorder": Endian.Big,
|
|
41
|
+
"count": 2,
|
|
42
|
+
},
|
|
43
|
+
"U_DWORD_R": {
|
|
44
|
+
"f": "decode_32bit_uint",
|
|
45
|
+
"byteorder": Endian.Little,
|
|
46
|
+
"count": 2,
|
|
47
|
+
},
|
|
48
|
+
"S_DWORD_R": {
|
|
49
|
+
"f": "decode_32bit_int",
|
|
50
|
+
"byteorder": Endian.Little,
|
|
51
|
+
"count": 2,
|
|
52
|
+
},
|
|
53
|
+
"U_QWORD": {
|
|
54
|
+
"f": "decode_64bit_uint",
|
|
55
|
+
"byteorder": Endian.Big,
|
|
56
|
+
"count": 4,
|
|
57
|
+
},
|
|
58
|
+
"S_QWORD": {
|
|
59
|
+
"f": "decode_64bit_int",
|
|
60
|
+
"byteorder": Endian.Big,
|
|
61
|
+
"count": 4,
|
|
62
|
+
},
|
|
63
|
+
"U_QWORD_R": {
|
|
64
|
+
"f": "decode_64bit_uint",
|
|
65
|
+
"byteorder": Endian.Little,
|
|
66
|
+
"count": 4,
|
|
67
|
+
},
|
|
68
|
+
"FP32": {
|
|
69
|
+
"f": "decode_32bit_float",
|
|
70
|
+
"byteorder": Endian.Big,
|
|
71
|
+
"count": 2,
|
|
72
|
+
},
|
|
73
|
+
"FP32_R": {
|
|
74
|
+
"f": "decode_32bit_float",
|
|
75
|
+
"byteorder": Endian.Little,
|
|
76
|
+
"count": 2,
|
|
77
|
+
},
|
|
34
78
|
}
|
|
35
79
|
|
|
36
80
|
|
|
@@ -167,9 +211,5 @@ class Modbus:
|
|
|
167
211
|
decoder = BinaryPayloadDecoder.fromRegisters(
|
|
168
212
|
registers=payload, byteorder=_payload_type["byteorder"]
|
|
169
213
|
)
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
return value
|
|
173
|
-
except Exception as e:
|
|
174
|
-
_LOGGER.error(e)
|
|
175
|
-
return None
|
|
214
|
+
value = getattr(decoder, _payload_type["f"])()
|
|
215
|
+
return value
|
|
@@ -18,13 +18,13 @@
|
|
|
18
18
|
},
|
|
19
19
|
"registers_base": [
|
|
20
20
|
{
|
|
21
|
-
"base":
|
|
21
|
+
"base": 7,
|
|
22
22
|
"length": 2,
|
|
23
23
|
"register_type": "holding",
|
|
24
24
|
"registers": [
|
|
25
25
|
{
|
|
26
26
|
"name": "Immersion depth",
|
|
27
|
-
"address":
|
|
27
|
+
"address": 7,
|
|
28
28
|
"unit_of_measurement": "mm",
|
|
29
29
|
"state_class": "measurement",
|
|
30
30
|
"device_class": "humidity",
|
|
@@ -63,7 +63,11 @@ class ModbusHelper:
|
|
|
63
63
|
_LOGGER.error("No returned value.")
|
|
64
64
|
return False
|
|
65
65
|
payload = value.registers[0:count]
|
|
66
|
-
|
|
66
|
+
try:
|
|
67
|
+
decoded_value = self._modbus.decode_value(payload, value_type)
|
|
68
|
+
except Exception as e:
|
|
69
|
+
_LOGGER.error("Decoding error during checking connection %s", e)
|
|
70
|
+
decoded_value = None
|
|
67
71
|
for filter in self._check_record.get("filters", []):
|
|
68
72
|
for key, value in filter.items():
|
|
69
73
|
if key in allowed_operations:
|
|
@@ -23,7 +23,7 @@ from boneio.const import (
|
|
|
23
23
|
from boneio.helper import BasicMqtt, AsyncUpdater
|
|
24
24
|
from boneio.helper.config import ConfigHelper
|
|
25
25
|
from boneio.helper.events import EventBus
|
|
26
|
-
from .client import Modbus
|
|
26
|
+
from .client import Modbus, VALUE_TYPES
|
|
27
27
|
from .single_sensor import SingleSensor
|
|
28
28
|
from boneio.helper.util import open_json
|
|
29
29
|
|
|
@@ -194,12 +194,24 @@ class ModbusSensor(BasicMqtt, AsyncUpdater, Filter):
|
|
|
194
194
|
)
|
|
195
195
|
else:
|
|
196
196
|
start_index = sensor.address - sensor.base_address
|
|
197
|
+
count = VALUE_TYPES[sensor.value_type]["count"]
|
|
197
198
|
payload = values.registers[
|
|
198
|
-
start_index : start_index +
|
|
199
|
-
]
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
199
|
+
start_index : start_index + count
|
|
200
|
+
]
|
|
201
|
+
try:
|
|
202
|
+
decoded_value = self._modbus.decode_value(
|
|
203
|
+
payload, sensor.value_type
|
|
204
|
+
)
|
|
205
|
+
except Exception as e:
|
|
206
|
+
_LOGGER.error(
|
|
207
|
+
"Decoding error for %s at address %s, base: %s, length: %s, error %s",
|
|
208
|
+
sensor.name,
|
|
209
|
+
sensor.address,
|
|
210
|
+
sensor.base_address,
|
|
211
|
+
data[LENGTH],
|
|
212
|
+
e,
|
|
213
|
+
)
|
|
214
|
+
decoded_value = None
|
|
203
215
|
sensor.set_value(value=decoded_value)
|
|
204
216
|
output[sensor.decoded_name] = sensor.state
|
|
205
217
|
self._send_message(
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Provide an MQTT client for providing BoneIO MQTT broker.
|
|
3
3
|
Code based on cgarwood/python-openzwave-mqtt.
|
|
4
4
|
"""
|
|
5
|
+
|
|
5
6
|
from __future__ import annotations
|
|
6
7
|
import asyncio
|
|
7
8
|
import json
|
|
@@ -48,8 +49,18 @@ class MQTTClient:
|
|
|
48
49
|
self.reconnect_interval = 1
|
|
49
50
|
self._connection_established = False
|
|
50
51
|
self.publish_queue: UniqueQueue = UniqueQueue()
|
|
51
|
-
self._discovery_topics =
|
|
52
|
-
|
|
52
|
+
self._discovery_topics = (
|
|
53
|
+
[
|
|
54
|
+
f"{self._config_helper.ha_discovery_prefix}/{ha_type}/{self._config_helper.topic_prefix}/#"
|
|
55
|
+
for ha_type in self._config_helper.ha_types
|
|
56
|
+
]
|
|
57
|
+
if self._config_helper.ha_discovery
|
|
58
|
+
else []
|
|
59
|
+
)
|
|
60
|
+
self._topics = [
|
|
61
|
+
self._config_helper.subscribe_topic,
|
|
62
|
+
"homeassistant/status",
|
|
63
|
+
]
|
|
53
64
|
|
|
54
65
|
def create_client(self) -> None:
|
|
55
66
|
"""Create the asyncio client."""
|
|
@@ -110,7 +121,9 @@ class MQTTClient:
|
|
|
110
121
|
params["properties"] = properties
|
|
111
122
|
|
|
112
123
|
# e.g. subscribe([("my/topic", SubscribeOptions(qos=0), ("another/topic", SubscribeOptions(qos=2)])
|
|
113
|
-
await self.asyncio_client.subscribe(
|
|
124
|
+
await self.asyncio_client.subscribe(
|
|
125
|
+
topic=args, **params, timeout=timeout
|
|
126
|
+
)
|
|
114
127
|
|
|
115
128
|
async def unsubscribe(
|
|
116
129
|
self,
|
|
@@ -129,7 +142,10 @@ class MQTTClient:
|
|
|
129
142
|
await self.asyncio_client.unsubscribe(topic=topics, **params)
|
|
130
143
|
|
|
131
144
|
def send_message(
|
|
132
|
-
self,
|
|
145
|
+
self,
|
|
146
|
+
topic: str,
|
|
147
|
+
payload: Union[str, int, dict, None],
|
|
148
|
+
retain: bool = False,
|
|
133
149
|
) -> None:
|
|
134
150
|
"""Send a message from the manager options."""
|
|
135
151
|
to_publish = (
|
|
@@ -154,7 +170,9 @@ class MQTTClient:
|
|
|
154
170
|
try:
|
|
155
171
|
await self._subscribe_manager(manager)
|
|
156
172
|
except MqttError as err:
|
|
157
|
-
self.reconnect_interval = min(
|
|
173
|
+
self.reconnect_interval = min(
|
|
174
|
+
self.reconnect_interval * 2, 600
|
|
175
|
+
)
|
|
158
176
|
_LOGGER.error(
|
|
159
177
|
"MQTT error: %s. Reconnecting in %s seconds",
|
|
160
178
|
err,
|
|
@@ -168,15 +186,13 @@ class MQTTClient:
|
|
|
168
186
|
pass
|
|
169
187
|
|
|
170
188
|
async def stop_client(self) -> None:
|
|
171
|
-
await self.unsubscribe(
|
|
172
|
-
topics=self._topics
|
|
173
|
-
)
|
|
189
|
+
await self.unsubscribe(topics=self._topics)
|
|
174
190
|
raise RestartRequestException("Restart requested.")
|
|
175
|
-
|
|
191
|
+
|
|
176
192
|
def state(self) -> bool:
|
|
177
193
|
"""State of MQTT Client."""
|
|
178
194
|
return self._connection_established
|
|
179
|
-
|
|
195
|
+
|
|
180
196
|
async def _subscribe_manager(self, manager: Manager) -> None:
|
|
181
197
|
"""Connect and subscribe to manager topics + host stats."""
|
|
182
198
|
async with AsyncExitStack() as stack:
|
|
@@ -200,21 +216,21 @@ class MQTTClient:
|
|
|
200
216
|
)
|
|
201
217
|
if not self._connection_established:
|
|
202
218
|
self._connection_established = True
|
|
203
|
-
reconnect_task = asyncio.create_task(
|
|
219
|
+
reconnect_task = asyncio.create_task(
|
|
220
|
+
manager.reconnect_callback()
|
|
221
|
+
)
|
|
204
222
|
tasks.add(reconnect_task)
|
|
205
223
|
tasks.add(messages_task)
|
|
206
224
|
|
|
207
|
-
await self.subscribe(
|
|
208
|
-
|
|
209
|
-
)
|
|
210
|
-
await self.subscribe(
|
|
211
|
-
topics=self._discovery_topics
|
|
212
|
-
)
|
|
225
|
+
await self.subscribe(topics=self._topics)
|
|
226
|
+
await self.subscribe(topics=self._discovery_topics)
|
|
213
227
|
|
|
214
228
|
# Wait for everything to complete (or fail due to, e.g., network errors).
|
|
215
229
|
await asyncio.gather(*tasks)
|
|
216
230
|
|
|
217
|
-
async def handle_messages(
|
|
231
|
+
async def handle_messages(
|
|
232
|
+
self, messages: Any, callback: Callable[[str, str], Awaitable[None]]
|
|
233
|
+
):
|
|
218
234
|
"""Handle messages with callback or remove obsolete HA discovery messages."""
|
|
219
235
|
async for message in messages:
|
|
220
236
|
payload = message.payload.decode()
|
|
@@ -223,10 +239,23 @@ class MQTTClient:
|
|
|
223
239
|
if message.topic.matches(discovery_topic):
|
|
224
240
|
callback_start = False
|
|
225
241
|
topic = str(message.topic)
|
|
226
|
-
if
|
|
227
|
-
|
|
228
|
-
self.
|
|
242
|
+
if (
|
|
243
|
+
message.payload
|
|
244
|
+
and not self._config_helper.is_topic_in_autodiscovery(
|
|
245
|
+
topic
|
|
246
|
+
)
|
|
247
|
+
):
|
|
248
|
+
_LOGGER.info(
|
|
249
|
+
"Removing unused discovery entity %s", topic
|
|
250
|
+
)
|
|
251
|
+
self.send_message(
|
|
252
|
+
topic=topic, payload=None, retain=True
|
|
253
|
+
)
|
|
229
254
|
break
|
|
230
255
|
if callback_start:
|
|
231
|
-
_LOGGER.debug(
|
|
256
|
+
_LOGGER.debug(
|
|
257
|
+
"Received message topic: %s, payload: %s",
|
|
258
|
+
message.topic,
|
|
259
|
+
payload,
|
|
260
|
+
)
|
|
232
261
|
await callback(str(message.topic), payload)
|
|
@@ -32,7 +32,8 @@ class TempSensor(BasicMqtt, AsyncUpdater, Filter):
|
|
|
32
32
|
self._loop = asyncio.get_event_loop()
|
|
33
33
|
self._filters = filters
|
|
34
34
|
try:
|
|
35
|
-
|
|
35
|
+
if self.SensorClass:
|
|
36
|
+
self._pct = self.SensorClass(i2c_bus=i2c, address=address)
|
|
36
37
|
self._state: float | None = None
|
|
37
38
|
except ValueError as err:
|
|
38
39
|
raise I2CError(err)
|
|
@@ -41,7 +42,7 @@ class TempSensor(BasicMqtt, AsyncUpdater, Filter):
|
|
|
41
42
|
@property
|
|
42
43
|
def state(self) -> float:
|
|
43
44
|
"""Give rounded value of temperature."""
|
|
44
|
-
return self._state
|
|
45
|
+
return self._state or -1
|
|
45
46
|
|
|
46
47
|
def update(self, time: datetime) -> None:
|
|
47
48
|
"""Fetch temperature periodically and send to MQTT."""
|
|
@@ -10,7 +10,11 @@ from w1thermsensor import SensorNotReadyError, NoSensorFoundError
|
|
|
10
10
|
from boneio.const import SENSOR, STATE, TEMPERATURE
|
|
11
11
|
from boneio.helper import AsyncUpdater, BasicMqtt
|
|
12
12
|
from boneio.helper.exceptions import OneWireError
|
|
13
|
-
from boneio.helper.onewire import
|
|
13
|
+
from boneio.helper.onewire import (
|
|
14
|
+
AsyncBoneIOW1ThermSensor,
|
|
15
|
+
OneWireAddress,
|
|
16
|
+
OneWireBus,
|
|
17
|
+
)
|
|
14
18
|
|
|
15
19
|
from . import TempSensor
|
|
16
20
|
|
|
@@ -54,6 +58,7 @@ class DallasSensorW1(TempSensor, AsyncUpdater):
|
|
|
54
58
|
self._loop = asyncio.get_event_loop()
|
|
55
59
|
BasicMqtt.__init__(self, id=id, topic_type=SENSOR, **kwargs)
|
|
56
60
|
self._filters = filters
|
|
61
|
+
self._state = None
|
|
57
62
|
try:
|
|
58
63
|
self._pct = AsyncBoneIOW1ThermSensor(sensor_id=address)
|
|
59
64
|
except ValueError as err:
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|