boneIO 0.5.0dev1__tar.gz → 0.5.0dev2__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.
Potentially problematic release.
This version of boneIO might be problematic. Click here for more details.
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/PKG-INFO +1 -1
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/const.py +1 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/cover.py +15 -14
- boneIO-0.5.0.dev2/boneio/helper/filter.py +26 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/loader.py +7 -4
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/stats.py +6 -2
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/manager.py +10 -11
- boneIO-0.5.0.dev2/boneio/schema/filters.yaml +11 -0
- boneIO-0.5.0.dev2/boneio/schema/filters_adc.yaml +12 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/schema/schema.yaml +14 -50
- boneIO-0.5.0.dev2/boneio/schema/update_interval.yaml +10 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/sensor/adc.py +9 -3
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/sensor/temp/__init__.py +15 -3
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/sensor/temp/dallas.py +9 -1
- boneIO-0.5.0.dev2/boneio/version.py +2 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/pyproject.toml +1 -1
- boneIO-0.5.0.dev1/boneio/version.py +0 -2
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/LICENSE +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/README.md +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/__init__.py +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/bonecli.py +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/example_config/__init__.py +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/example_config/adc.yaml +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/example_config/config.yaml +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/example_config/cover.yaml +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/example_config/input.yaml +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/example_config/output24x16A.yaml +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/example_config/output32x5A.yaml +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/fonts/danube__.ttf +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/__init__.py +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/async_updater.py +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/config.py +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/events.py +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/exceptions.py +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/gpio.py +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/ha_discovery.py +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/logger.py +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/mqtt.py +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/oled.py +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/onewire/W1ThermSensor.py +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/onewire/__init__.py +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/onewire/ds2482.py +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/onewire/onewire.py +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/queue.py +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/state_manager.py +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/timeperiod.py +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/util.py +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/yaml_util.py +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/input/__init__.py +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/input/gpio.py +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/modbus.py +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/mqtt_client.py +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/oled.py +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/relay/__init__.py +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/relay/basic.py +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/relay/gpio.py +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/relay/mcp.py +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/runner.py +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/schema/actions.yaml +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/schema/actions_sensor.yaml +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/schema/actions_switch.yaml +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/sensor/__init__.py +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/sensor/gpio.py +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/sensor/modbus/__init__.py +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/sensor/modbus/sdm120.json +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/sensor/modbus/sdm630.json +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/sensor/modbus/sofar.json +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/sensor/temp/lm75.py +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/sensor/temp/mcp9808.py +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/tests/32_5_config.yaml +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/tests/bandit.yaml +0 -0
- {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/tests/relay_32_5.py +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""Cover module."""
|
|
2
|
+
from __future__ import annotations
|
|
2
3
|
import asyncio
|
|
3
4
|
import logging
|
|
4
5
|
from typing import Callable
|
|
@@ -108,24 +109,24 @@ class Cover(BasicMqtt):
|
|
|
108
109
|
self._stop_cover(on_exit=True)
|
|
109
110
|
|
|
110
111
|
@property
|
|
111
|
-
def cover_state(self):
|
|
112
|
+
def cover_state(self) -> CLOSED | OPEN:
|
|
112
113
|
"""Current state of cover."""
|
|
113
114
|
return CLOSED if self._closed else OPEN
|
|
114
115
|
|
|
115
|
-
def stop(self):
|
|
116
|
+
def stop(self) -> None:
|
|
116
117
|
"""Public Stop cover graceful."""
|
|
117
118
|
_LOGGER.info("Stopping cover %s.", self._id)
|
|
118
119
|
if self._current_operation != IDLE:
|
|
119
120
|
self._stop_cover(on_exit=False)
|
|
120
121
|
|
|
121
|
-
def send_state(self):
|
|
122
|
+
def send_state(self) -> None:
|
|
122
123
|
"""Send state of cover to mqtt."""
|
|
123
124
|
self._send_message(topic=f"{self._send_topic}/state", payload=self.cover_state)
|
|
124
125
|
pos = round(self._position, 0)
|
|
125
126
|
self._send_message(topic=f"{self._send_topic}/pos", payload=str(pos))
|
|
126
127
|
self._state_save(position=pos)
|
|
127
128
|
|
|
128
|
-
def _stop_cover(self, on_exit=False):
|
|
129
|
+
def _stop_cover(self, on_exit=False) -> None:
|
|
129
130
|
"""Stop cover."""
|
|
130
131
|
self._open.relay.turn_off()
|
|
131
132
|
self._close.relay.turn_off()
|
|
@@ -138,11 +139,11 @@ class Cover(BasicMqtt):
|
|
|
138
139
|
self._current_operation = IDLE
|
|
139
140
|
|
|
140
141
|
@property
|
|
141
|
-
def current_cover_position(self):
|
|
142
|
+
def current_cover_position(self) -> int:
|
|
142
143
|
"""Return the current position of the cover."""
|
|
143
144
|
return round(self._position, 0)
|
|
144
145
|
|
|
145
|
-
def listen_cover(self, *args):
|
|
146
|
+
def listen_cover(self, *args) -> None:
|
|
146
147
|
"""Listen for change in cover."""
|
|
147
148
|
if self._current_operation == IDLE:
|
|
148
149
|
return
|
|
@@ -178,7 +179,7 @@ class Cover(BasicMqtt):
|
|
|
178
179
|
|
|
179
180
|
self._closed = self.current_cover_position <= 0
|
|
180
181
|
|
|
181
|
-
async def close_cover(self):
|
|
182
|
+
async def close_cover(self) -> None:
|
|
182
183
|
"""Close cover."""
|
|
183
184
|
if self._position == 0:
|
|
184
185
|
return
|
|
@@ -193,7 +194,7 @@ class Cover(BasicMqtt):
|
|
|
193
194
|
current_operation=CLOSING,
|
|
194
195
|
)
|
|
195
196
|
|
|
196
|
-
async def open_cover(self):
|
|
197
|
+
async def open_cover(self) -> None:
|
|
197
198
|
"""Open cover."""
|
|
198
199
|
if self._position == 100:
|
|
199
200
|
return
|
|
@@ -208,7 +209,7 @@ class Cover(BasicMqtt):
|
|
|
208
209
|
current_operation=OPENING,
|
|
209
210
|
)
|
|
210
211
|
|
|
211
|
-
async def set_cover_position(self, position: int):
|
|
212
|
+
async def set_cover_position(self, position: int) -> None:
|
|
212
213
|
"""Move cover to a specific position."""
|
|
213
214
|
set_position = round(position, -1)
|
|
214
215
|
if self._position == position or set_position == self._set_position:
|
|
@@ -228,29 +229,29 @@ class Cover(BasicMqtt):
|
|
|
228
229
|
current_operation=current_operation,
|
|
229
230
|
)
|
|
230
231
|
|
|
231
|
-
def open(self):
|
|
232
|
+
def open(self) -> None:
|
|
232
233
|
_LOGGER.debug("Opening cover %s.", self._id)
|
|
233
234
|
asyncio.create_task(self.open_cover())
|
|
234
235
|
|
|
235
|
-
def close(self):
|
|
236
|
+
def close(self) -> None:
|
|
236
237
|
_LOGGER.debug("Closing cover %s.", self._id)
|
|
237
238
|
asyncio.create_task(self.close_cover())
|
|
238
239
|
|
|
239
|
-
def toggle(self):
|
|
240
|
+
def toggle(self) -> None:
|
|
240
241
|
_LOGGER.debug("Toggle cover %s from input.", self._id)
|
|
241
242
|
if self.cover_state == CLOSED:
|
|
242
243
|
self.close()
|
|
243
244
|
else:
|
|
244
245
|
self.open()
|
|
245
246
|
|
|
246
|
-
def toggle_open(self):
|
|
247
|
+
def toggle_open(self) -> None:
|
|
247
248
|
_LOGGER.debug("Toggle open cover %s from input.", self._id)
|
|
248
249
|
if self._current_operation != IDLE:
|
|
249
250
|
self.stop()
|
|
250
251
|
else:
|
|
251
252
|
self.open()
|
|
252
253
|
|
|
253
|
-
def toggle_close(self):
|
|
254
|
+
def toggle_close(self) -> None:
|
|
254
255
|
_LOGGER.debug("Toggle close cover %s from input.", self._id)
|
|
255
256
|
if self._current_operation != IDLE:
|
|
256
257
|
self.stop()
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""Filter class to adjust sensor values."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
FILTERS = {
|
|
6
|
+
"offset": lambda x, y: x + y,
|
|
7
|
+
"round": lambda x, y: round(x, y),
|
|
8
|
+
"multiply": lambda x, y: x * y,
|
|
9
|
+
"filter_out": lambda x, y: None if x == y else x,
|
|
10
|
+
"filter_out_greater": lambda x, y: None if x > y else x,
|
|
11
|
+
"filter_out_lower": lambda x, y: None if x < y else x,
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Filter:
|
|
16
|
+
_filters = []
|
|
17
|
+
|
|
18
|
+
def _apply_filters(self, value: float) -> float | None:
|
|
19
|
+
for filter in self._filters:
|
|
20
|
+
for k, v in filter.items():
|
|
21
|
+
if k not in FILTERS:
|
|
22
|
+
break
|
|
23
|
+
value = FILTERS[k](value, v)
|
|
24
|
+
if value is None:
|
|
25
|
+
return None
|
|
26
|
+
return value
|
|
@@ -13,6 +13,7 @@ from boneio.const import (
|
|
|
13
13
|
BINARY_SENSOR,
|
|
14
14
|
COVER,
|
|
15
15
|
DEVICE_CLASS,
|
|
16
|
+
FILTERS,
|
|
16
17
|
GPIO,
|
|
17
18
|
ID,
|
|
18
19
|
INIT_SLEEP,
|
|
@@ -107,7 +108,7 @@ def create_temp_sensor(
|
|
|
107
108
|
topic_prefix: str,
|
|
108
109
|
sensor_type: str,
|
|
109
110
|
i2cbusio: I2C,
|
|
110
|
-
|
|
111
|
+
config: dict = {},
|
|
111
112
|
):
|
|
112
113
|
"""Create LM sensor in manager."""
|
|
113
114
|
if sensor_type == LM75:
|
|
@@ -116,17 +117,18 @@ def create_temp_sensor(
|
|
|
116
117
|
from boneio.sensor import MCP9808Sensor as TempSensor
|
|
117
118
|
else:
|
|
118
119
|
return
|
|
119
|
-
name =
|
|
120
|
+
name = config.get(ID)
|
|
120
121
|
id = name.replace(" ", "")
|
|
121
122
|
try:
|
|
122
123
|
temp_sensor = TempSensor(
|
|
123
124
|
id=id,
|
|
124
125
|
name=name,
|
|
125
126
|
i2c=i2cbusio,
|
|
126
|
-
address=
|
|
127
|
+
address=config[ADDRESS],
|
|
127
128
|
send_message=manager.send_message,
|
|
128
129
|
topic_prefix=topic_prefix,
|
|
129
|
-
update_interval=
|
|
130
|
+
update_interval=config.get(UPDATE_INTERVAL, TimePeriod(seconds=60)),
|
|
131
|
+
filters=config.get(FILTERS, []),
|
|
130
132
|
)
|
|
131
133
|
manager.send_ha_autodiscovery(
|
|
132
134
|
id=id,
|
|
@@ -393,6 +395,7 @@ def create_dallas_sensor(
|
|
|
393
395
|
name=name,
|
|
394
396
|
update_interval=config.get(UPDATE_INTERVAL, TimePeriod(seconds=60)),
|
|
395
397
|
send_message=manager.send_message,
|
|
398
|
+
filters=config.get(FILTERS, []),
|
|
396
399
|
**kwargs,
|
|
397
400
|
)
|
|
398
401
|
if config.get(SHOW_HA, True):
|
|
@@ -117,10 +117,13 @@ def get_uptime():
|
|
|
117
117
|
class HostSensor(AsyncUpdater):
|
|
118
118
|
"""Host sensor."""
|
|
119
119
|
|
|
120
|
-
def __init__(
|
|
120
|
+
def __init__(
|
|
121
|
+
self, update_function: Callable, static_data: dict, id: str, **kwargs
|
|
122
|
+
) -> None:
|
|
121
123
|
self._update_function = update_function
|
|
122
124
|
self._static_data = static_data
|
|
123
125
|
self._state = None
|
|
126
|
+
self.id = id
|
|
124
127
|
super().__init__(**kwargs)
|
|
125
128
|
|
|
126
129
|
async def async_update(self, time: datetime) -> None:
|
|
@@ -160,10 +163,11 @@ class HostData:
|
|
|
160
163
|
},
|
|
161
164
|
}
|
|
162
165
|
for k, _v in host_stats.items():
|
|
163
|
-
self.
|
|
166
|
+
self.data[k] = HostSensor(
|
|
164
167
|
update_function=_v["f"],
|
|
165
168
|
static_data=_v.get("static"),
|
|
166
169
|
manager=manager,
|
|
170
|
+
id=f"{k}_hoststats",
|
|
167
171
|
update_interval=_v["update_interval"],
|
|
168
172
|
)
|
|
169
173
|
self._temp_sensor = temp_sensor
|
|
@@ -218,7 +218,7 @@ class Manager:
|
|
|
218
218
|
)
|
|
219
219
|
except (GPIOInputException, I2CError) as err:
|
|
220
220
|
_LOGGER.error("Can't configure OLED display. %s", err)
|
|
221
|
-
|
|
221
|
+
self.prepare_ha_buttons()
|
|
222
222
|
|
|
223
223
|
_LOGGER.info("BoneIO manager is ready.")
|
|
224
224
|
|
|
@@ -320,7 +320,7 @@ class Manager:
|
|
|
320
320
|
manager=self,
|
|
321
321
|
topic_prefix=self._config_helper.topic_prefix,
|
|
322
322
|
sensor_type=sensor_type,
|
|
323
|
-
|
|
323
|
+
config=temp_def,
|
|
324
324
|
i2cbusio=self._i2cbusio,
|
|
325
325
|
)
|
|
326
326
|
if temp_sensor:
|
|
@@ -371,11 +371,11 @@ class Manager:
|
|
|
371
371
|
"""Retrieve asyncio tasks to run."""
|
|
372
372
|
return self._tasks
|
|
373
373
|
|
|
374
|
-
def
|
|
375
|
-
"""Prepare buttons for reload."""
|
|
374
|
+
def prepare_ha_buttons(self) -> None:
|
|
375
|
+
"""Prepare HA buttons for reload."""
|
|
376
376
|
self.send_ha_autodiscovery(
|
|
377
377
|
id="Logger",
|
|
378
|
-
name="Logger",
|
|
378
|
+
name="Logger reload",
|
|
379
379
|
ha_type=BUTTON,
|
|
380
380
|
availability_msg_func=ha_button_availabilty_message,
|
|
381
381
|
)
|
|
@@ -438,7 +438,7 @@ class Manager:
|
|
|
438
438
|
self._config_helper.add_autodiscovery_msg(topic=topic, payload=payload)
|
|
439
439
|
self.send_message(topic=topic, payload=payload, retain=True)
|
|
440
440
|
|
|
441
|
-
def resend_autodiscovery(self):
|
|
441
|
+
def resend_autodiscovery(self) -> None:
|
|
442
442
|
for msg in self._config_helper.autodiscovery_msgs:
|
|
443
443
|
self.send_message(**msg, retain=True)
|
|
444
444
|
|
|
@@ -500,11 +500,10 @@ class Manager:
|
|
|
500
500
|
_LOGGER.warn(
|
|
501
501
|
"Positon cannot be set. Not number between 0-100. %s", message
|
|
502
502
|
)
|
|
503
|
-
elif msg_type == BUTTON:
|
|
504
|
-
if device_id == "logger" and
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
self._logger_reload()
|
|
503
|
+
elif msg_type == BUTTON and command == "set":
|
|
504
|
+
if device_id == "logger" and message == "reload":
|
|
505
|
+
_LOGGER.info("Reloading logger configuration.")
|
|
506
|
+
self._logger_reload()
|
|
508
507
|
|
|
509
508
|
@property
|
|
510
509
|
def output(self) -> dict:
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
type: list
|
|
2
|
+
required: False
|
|
3
|
+
schema:
|
|
4
|
+
type: dict
|
|
5
|
+
keysrules:
|
|
6
|
+
type: string
|
|
7
|
+
allowed: ["offset", "round", "multiply", "filter_out", "filter_out_greater", "filter_out_lower"]
|
|
8
|
+
default:
|
|
9
|
+
- round: 2
|
|
10
|
+
meta:
|
|
11
|
+
label: List of filters to apply. Allowed filters visible in allowed section.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
type: list
|
|
2
|
+
required: False
|
|
3
|
+
schema:
|
|
4
|
+
type: dict
|
|
5
|
+
keysrules:
|
|
6
|
+
type: string
|
|
7
|
+
allowed: ["offset", "round", "multiply", "filter_out", "filter_out_greater", "filter_out_lower"]
|
|
8
|
+
default:
|
|
9
|
+
- multiply: 1.8
|
|
10
|
+
- round: 2
|
|
11
|
+
meta:
|
|
12
|
+
label: List of filters to apply. Allowed filters visible in allowed section.
|
|
@@ -147,17 +147,8 @@ lm75:
|
|
|
147
147
|
default: 0x48
|
|
148
148
|
meta:
|
|
149
149
|
label: Address of I2C
|
|
150
|
-
update_interval:
|
|
151
|
-
|
|
152
|
-
- string
|
|
153
|
-
- timeperiod
|
|
154
|
-
coerce:
|
|
155
|
-
- str
|
|
156
|
-
- positive_time_period
|
|
157
|
-
required: True
|
|
158
|
-
default: 60s
|
|
159
|
-
meta:
|
|
160
|
-
label: Update interval.
|
|
150
|
+
update_interval: !include update_interval.yaml
|
|
151
|
+
filters: !include filters.yaml
|
|
161
152
|
|
|
162
153
|
|
|
163
154
|
mcp9808:
|
|
@@ -175,17 +166,8 @@ mcp9808:
|
|
|
175
166
|
default: 0x18
|
|
176
167
|
meta:
|
|
177
168
|
label: Address of I2C device
|
|
178
|
-
update_interval:
|
|
179
|
-
|
|
180
|
-
- string
|
|
181
|
-
- timeperiod
|
|
182
|
-
coerce:
|
|
183
|
-
- str
|
|
184
|
-
- positive_time_period
|
|
185
|
-
required: True
|
|
186
|
-
default: 60s
|
|
187
|
-
meta:
|
|
188
|
-
label: Update interval.
|
|
169
|
+
update_interval: !include update_interval.yaml
|
|
170
|
+
filters: !include filters.yaml
|
|
189
171
|
|
|
190
172
|
mcp23017:
|
|
191
173
|
type: list
|
|
@@ -360,17 +342,7 @@ adc:
|
|
|
360
342
|
allowed: ["P9_33", "P9_35", "P9_36", "P9_37", "P9_38", "P9_39", "P9_40"]
|
|
361
343
|
meta:
|
|
362
344
|
label: PIN to use.
|
|
363
|
-
update_interval:
|
|
364
|
-
required: True
|
|
365
|
-
type:
|
|
366
|
-
- string
|
|
367
|
-
- timeperiod
|
|
368
|
-
coerce:
|
|
369
|
-
- str
|
|
370
|
-
- positive_time_period
|
|
371
|
-
default: 60s
|
|
372
|
-
meta:
|
|
373
|
-
label: Update interval.
|
|
345
|
+
update_interval: !include update_interval.yaml
|
|
374
346
|
show_in_ha:
|
|
375
347
|
type: boolean
|
|
376
348
|
required: True
|
|
@@ -483,17 +455,18 @@ sensor:
|
|
|
483
455
|
required: False
|
|
484
456
|
meta:
|
|
485
457
|
label: Id to use in HA if needed. Default to address.
|
|
458
|
+
platform:
|
|
459
|
+
type: string
|
|
460
|
+
required: True
|
|
461
|
+
default: dallas
|
|
462
|
+
allowed: ["dallas"]
|
|
463
|
+
meta:
|
|
464
|
+
label: Platform of sensor to use. Currently only Dallas platform is supported.
|
|
486
465
|
address:
|
|
487
466
|
type: integer
|
|
488
467
|
required: True
|
|
489
468
|
meta:
|
|
490
469
|
label: Address of Dallas device
|
|
491
|
-
via_ds2482:
|
|
492
|
-
type: boolean
|
|
493
|
-
required: True
|
|
494
|
-
default: False
|
|
495
|
-
meta:
|
|
496
|
-
label: Choose if sensor is connected via DS2482 bus.
|
|
497
470
|
bus_id:
|
|
498
471
|
type: string
|
|
499
472
|
required: False
|
|
@@ -505,14 +478,5 @@ sensor:
|
|
|
505
478
|
default: True
|
|
506
479
|
meta:
|
|
507
480
|
label: If you want you can disable discovering this input in HA.
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
- string
|
|
511
|
-
- timeperiod
|
|
512
|
-
coerce:
|
|
513
|
-
- str
|
|
514
|
-
- positive_time_period
|
|
515
|
-
required: True
|
|
516
|
-
default: 60 s
|
|
517
|
-
meta:
|
|
518
|
-
label: Update interval.
|
|
481
|
+
filters: !include filters.yaml
|
|
482
|
+
update_interval: !include update_interval.yaml
|
|
@@ -4,6 +4,7 @@ import logging
|
|
|
4
4
|
|
|
5
5
|
from boneio.const import SENSOR
|
|
6
6
|
from boneio.helper import BasicMqtt, AsyncUpdater
|
|
7
|
+
from boneio.helper.filter import Filter
|
|
7
8
|
|
|
8
9
|
try:
|
|
9
10
|
import Adafruit_BBIO.ADC as ADC
|
|
@@ -22,23 +23,28 @@ def initialize_adc():
|
|
|
22
23
|
ADC.setup()
|
|
23
24
|
|
|
24
25
|
|
|
25
|
-
class GpioADCSensor(BasicMqtt, AsyncUpdater):
|
|
26
|
+
class GpioADCSensor(BasicMqtt, AsyncUpdater, Filter):
|
|
26
27
|
"""Represent Gpio ADC sensor."""
|
|
27
28
|
|
|
28
29
|
def __init__(self, pin: str, **kwargs) -> None:
|
|
29
30
|
"""Setup GPIO ADC Sensor"""
|
|
30
31
|
super().__init__(topic_type=SENSOR, **kwargs)
|
|
31
32
|
self._pin = pin
|
|
33
|
+
self._state = None
|
|
32
34
|
AsyncUpdater.__init__(self, **kwargs)
|
|
33
35
|
_LOGGER.debug("Configured sensor pin %s", self._pin)
|
|
34
36
|
|
|
35
37
|
@property
|
|
36
|
-
def state(self):
|
|
38
|
+
def state(self) -> float:
|
|
37
39
|
"""Give rounded value of temperature."""
|
|
38
|
-
return
|
|
40
|
+
return self._state
|
|
39
41
|
|
|
40
42
|
def update(self, time: datetime) -> None:
|
|
41
43
|
"""Fetch temperature periodically and send to MQTT."""
|
|
44
|
+
_state = self._apply_filters(value=ADC.read(self._pin))
|
|
45
|
+
if not _state:
|
|
46
|
+
return
|
|
47
|
+
self._state = _state
|
|
42
48
|
self._send_message(
|
|
43
49
|
topic=self._send_topic,
|
|
44
50
|
payload=self.state,
|
|
@@ -6,18 +6,27 @@ from datetime import datetime
|
|
|
6
6
|
from boneio.const import SENSOR, STATE, TEMPERATURE
|
|
7
7
|
from boneio.helper import BasicMqtt, AsyncUpdater
|
|
8
8
|
from boneio.helper.exceptions import I2CError
|
|
9
|
+
from boneio.helper.filter import Filter
|
|
9
10
|
|
|
10
11
|
|
|
11
|
-
class TempSensor(BasicMqtt, AsyncUpdater):
|
|
12
|
+
class TempSensor(BasicMqtt, AsyncUpdater, Filter):
|
|
12
13
|
"""Represent Temp sensor in BoneIO."""
|
|
13
14
|
|
|
14
15
|
SensorClass = None
|
|
15
16
|
DefaultName = TEMPERATURE
|
|
16
17
|
|
|
17
|
-
def __init__(
|
|
18
|
+
def __init__(
|
|
19
|
+
self,
|
|
20
|
+
i2c,
|
|
21
|
+
address: str,
|
|
22
|
+
id: str = DefaultName,
|
|
23
|
+
filters: list = ["round(x, 2)"],
|
|
24
|
+
**kwargs
|
|
25
|
+
):
|
|
18
26
|
"""Initialize Temp class."""
|
|
19
27
|
super().__init__(id=id, topic_type=SENSOR, **kwargs)
|
|
20
28
|
self._loop = asyncio.get_event_loop()
|
|
29
|
+
self._filters = filters
|
|
21
30
|
try:
|
|
22
31
|
self._pct = self.SensorClass(i2c_bus=i2c, address=address)
|
|
23
32
|
self._state: float | None = None
|
|
@@ -32,7 +41,10 @@ class TempSensor(BasicMqtt, AsyncUpdater):
|
|
|
32
41
|
|
|
33
42
|
def update(self, time: datetime) -> None:
|
|
34
43
|
"""Fetch temperature periodically and send to MQTT."""
|
|
35
|
-
|
|
44
|
+
_temp = self._apply_filters(value=self._pct.temperature)
|
|
45
|
+
if not _temp:
|
|
46
|
+
return
|
|
47
|
+
self._state = _temp
|
|
36
48
|
self._send_message(
|
|
37
49
|
topic=self._send_topic,
|
|
38
50
|
payload={STATE: self._state},
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import asyncio
|
|
4
4
|
import logging
|
|
5
5
|
from datetime import datetime
|
|
6
|
+
from ast import literal_eval
|
|
6
7
|
|
|
7
8
|
from adafruit_ds18x20 import DS18X20
|
|
8
9
|
from w1thermsensor import SensorNotReadyError
|
|
@@ -47,11 +48,13 @@ class DallasSensorW1(TempSensor, AsyncUpdater):
|
|
|
47
48
|
self,
|
|
48
49
|
address: OneWireAddress,
|
|
49
50
|
id: str = DefaultName,
|
|
51
|
+
filters: list = ["round(x, 2)"],
|
|
50
52
|
**kwargs,
|
|
51
53
|
):
|
|
52
54
|
"""Initialize Temp class."""
|
|
53
55
|
self._loop = asyncio.get_event_loop()
|
|
54
56
|
BasicMqtt.__init__(self, id=id, topic_type=SENSOR, **kwargs)
|
|
57
|
+
self._filters = filters
|
|
55
58
|
try:
|
|
56
59
|
self._pct = AsyncBoneIOW1ThermSensor(sensor_id=address)
|
|
57
60
|
except ValueError as err:
|
|
@@ -60,7 +63,12 @@ class DallasSensorW1(TempSensor, AsyncUpdater):
|
|
|
60
63
|
|
|
61
64
|
async def async_update(self, time: datetime) -> None:
|
|
62
65
|
try:
|
|
63
|
-
|
|
66
|
+
_temp = await self._pct.get_temperature()
|
|
67
|
+
_LOGGER.debug("Fetched temperature %s. Applying filters.", _temp)
|
|
68
|
+
_temp = self._apply_filters(value=_temp)
|
|
69
|
+
if not _temp:
|
|
70
|
+
return
|
|
71
|
+
self._state = _temp
|
|
64
72
|
self._send_message(
|
|
65
73
|
topic=self._send_topic,
|
|
66
74
|
payload={STATE: self._state},
|
|
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
|