boneIO 0.5.0.dev1__tar.gz → 0.5.0.dev2__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.
Files changed (72) hide show
  1. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/PKG-INFO +1 -1
  2. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/const.py +1 -0
  3. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/cover.py +15 -14
  4. boneIO-0.5.0.dev2/boneio/helper/filter.py +26 -0
  5. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/loader.py +7 -4
  6. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/stats.py +6 -2
  7. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/manager.py +10 -11
  8. boneIO-0.5.0.dev2/boneio/schema/filters.yaml +11 -0
  9. boneIO-0.5.0.dev2/boneio/schema/filters_adc.yaml +12 -0
  10. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/schema/schema.yaml +14 -50
  11. boneIO-0.5.0.dev2/boneio/schema/update_interval.yaml +10 -0
  12. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/sensor/adc.py +9 -3
  13. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/sensor/temp/__init__.py +15 -3
  14. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/sensor/temp/dallas.py +9 -1
  15. boneIO-0.5.0.dev2/boneio/version.py +2 -0
  16. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/pyproject.toml +1 -1
  17. boneIO-0.5.0.dev1/boneio/version.py +0 -2
  18. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/LICENSE +0 -0
  19. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/README.md +0 -0
  20. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/__init__.py +0 -0
  21. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/bonecli.py +0 -0
  22. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/example_config/__init__.py +0 -0
  23. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/example_config/adc.yaml +0 -0
  24. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/example_config/config.yaml +0 -0
  25. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/example_config/cover.yaml +0 -0
  26. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/example_config/input.yaml +0 -0
  27. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/example_config/output24x16A.yaml +0 -0
  28. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/example_config/output32x5A.yaml +0 -0
  29. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/fonts/danube__.ttf +0 -0
  30. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/__init__.py +0 -0
  31. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/async_updater.py +0 -0
  32. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/config.py +0 -0
  33. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/events.py +0 -0
  34. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/exceptions.py +0 -0
  35. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/gpio.py +0 -0
  36. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/ha_discovery.py +0 -0
  37. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/logger.py +0 -0
  38. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/mqtt.py +0 -0
  39. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/oled.py +0 -0
  40. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/onewire/W1ThermSensor.py +0 -0
  41. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/onewire/__init__.py +0 -0
  42. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/onewire/ds2482.py +0 -0
  43. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/onewire/onewire.py +0 -0
  44. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/queue.py +0 -0
  45. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/state_manager.py +0 -0
  46. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/timeperiod.py +0 -0
  47. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/util.py +0 -0
  48. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/helper/yaml_util.py +0 -0
  49. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/input/__init__.py +0 -0
  50. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/input/gpio.py +0 -0
  51. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/modbus.py +0 -0
  52. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/mqtt_client.py +0 -0
  53. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/oled.py +0 -0
  54. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/relay/__init__.py +0 -0
  55. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/relay/basic.py +0 -0
  56. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/relay/gpio.py +0 -0
  57. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/relay/mcp.py +0 -0
  58. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/runner.py +0 -0
  59. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/schema/actions.yaml +0 -0
  60. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/schema/actions_sensor.yaml +0 -0
  61. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/schema/actions_switch.yaml +0 -0
  62. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/sensor/__init__.py +0 -0
  63. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/sensor/gpio.py +0 -0
  64. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/sensor/modbus/__init__.py +0 -0
  65. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/sensor/modbus/sdm120.json +0 -0
  66. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/sensor/modbus/sdm630.json +0 -0
  67. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/sensor/modbus/sofar.json +0 -0
  68. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/sensor/temp/lm75.py +0 -0
  69. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/boneio/sensor/temp/mcp9808.py +0 -0
  70. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/tests/32_5_config.yaml +0 -0
  71. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/tests/bandit.yaml +0 -0
  72. {boneIO-0.5.0.dev1 → boneIO-0.5.0.dev2}/tests/relay_32_5.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: boneIO
3
- Version: 0.5.0dev1
3
+ Version: 0.5.0dev2
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>
@@ -136,3 +136,4 @@ Gpio_Edges = Literal[BOTH, FALLING]
136
136
  InputTypes = Literal[INPUT, INPUT_SENSOR]
137
137
  DEVICE_CLASS = "device_class"
138
138
  DallasBusTypes = Literal[DS2482, DALLAS]
139
+ FILTERS = "filters"
@@ -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
- temp_def: dict = {},
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 = temp_def.get(ID)
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=temp_def[ADDRESS],
127
+ address=config[ADDRESS],
127
128
  send_message=manager.send_message,
128
129
  topic_prefix=topic_prefix,
129
- update_interval=temp_def.get(UPDATE_INTERVAL, TimePeriod(seconds=60)),
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__(self, update_function: Callable, static_data: dict, **kwargs) -> None:
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._data[k] = HostSensor(
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
- self.prepare_button()
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
- temp_def=temp_def,
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 prepare_button(self) -> None:
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 command == "set":
505
- if message == "reload":
506
- _LOGGER.info("Reloading logger configuration.")
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
- type:
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
- type:
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
- update_interval:
509
- type:
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
@@ -0,0 +1,10 @@
1
+ type:
2
+ - string
3
+ - timeperiod
4
+ coerce:
5
+ - str
6
+ - positive_time_period
7
+ required: True
8
+ default: 60s
9
+ meta:
10
+ label: Update interval.
@@ -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 round(ADC.read(self._pin) * 1.8, 2)
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__(self, i2c, address: str, id: str = DefaultName, **kwargs):
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
- self._state = round(self._pct.temperature, 2)
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
- self._state = round(await self._pct.get_temperature(), 2)
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},
@@ -0,0 +1,2 @@
1
+ # flake8: noqa
2
+ __version__ = "0.5.0dev2"
@@ -27,7 +27,7 @@ dependencies = [
27
27
  "w1thermsensor[async]>=2.0.0",
28
28
  ]
29
29
  requires-python = ">=3.7"
30
- version = "0.5.0dev1"
30
+ version = "0.5.0dev2"
31
31
 
32
32
  [project.license]
33
33
  text = "GNU General Public License v3.0"
@@ -1,2 +0,0 @@
1
- # flake8: noqa
2
- __version__ = "0.5.0dev1"
File without changes
File without changes
File without changes