boneIO 0.3.0.dev5__tar.gz → 0.3.0.dev7__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.3.0.dev5/boneio.egg-info → boneio-0.3.0.dev7}/PKG-INFO +2 -2
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/const.py +4 -7
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/cover.py +1 -2
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/example_config/config.yaml +2 -2
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/example_config/cover.yaml +2 -2
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/helper/__init__.py +2 -15
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/helper/config.py +11 -0
- boneio-0.3.0.dev7/boneio/helper/ds2482/__init__.py +10 -0
- boneio-0.3.0.dev7/boneio/helper/ds2482/ds2482.py +163 -0
- boneio-0.3.0.dev7/boneio/helper/ds2482/onewire.py +44 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/helper/events.py +4 -4
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/helper/exceptions.py +4 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/helper/gpio.py +1 -1
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/helper/loader.py +48 -0
- boneio-0.3.0.dev7/boneio/helper/util.py +15 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/input/gpio.py +8 -7
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/manager.py +37 -4
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/relay/mcp.py +1 -1
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/runner.py +4 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/schema/schema.yaml +81 -1
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/sensor/__init__.py +4 -1
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/sensor/modbus/__init__.py +13 -13
- boneio-0.3.0.dev7/boneio/sensor/temp/__init__.py +76 -0
- boneio-0.3.0.dev7/boneio/sensor/temp/dallas.py +43 -0
- boneio-0.3.0.dev7/boneio/sensor/temp/lm75.py +11 -0
- boneio-0.3.0.dev7/boneio/sensor/temp/mcp9808.py +12 -0
- boneio-0.3.0.dev7/boneio/version.py +2 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7/boneio.egg-info}/PKG-INFO +2 -2
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio.egg-info/SOURCES.txt +8 -1
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio.egg-info/requires.txt +1 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/requirements.txt +1 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/setup.py +1 -0
- boneio-0.3.0.dev5/boneio/sensor/temp/__init__.py +0 -52
- boneio-0.3.0.dev5/boneio/version.py +0 -2
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/LICENSE +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/MANIFEST.in +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/README.md +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/__init__.py +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/bonecli.py +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/example_config/__init__.py +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/example_config/adc.yaml +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/example_config/input.yaml +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/example_config/output24x16A.yaml +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/example_config/output32x5A.yaml +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/fonts/danube__.ttf +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/helper/ha_discovery.py +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/helper/logger.py +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/helper/mqtt.py +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/helper/oled.py +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/helper/queue.py +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/helper/state_manager.py +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/helper/stats.py +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/helper/timeperiod.py +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/helper/yaml_util.py +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/input/__init__.py +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/modbus.py +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/mqtt_client.py +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/oled.py +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/relay/__init__.py +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/relay/basic.py +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/relay/gpio.py +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/schema/actions.yaml +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/schema/actions_sensor.yaml +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/schema/actions_switch.yaml +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/sensor/adc.py +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/sensor/gpio.py +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/sensor/modbus/sdm120.json +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/sensor/modbus/sdm630.json +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio/sensor/modbus/sofar.json +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio.egg-info/dependency_links.txt +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio.egg-info/entry_points.txt +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/boneio.egg-info/top_level.txt +0 -0
- {boneio-0.3.0.dev5 → boneio-0.3.0.dev7}/setup.cfg +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: boneio
|
|
3
|
-
Version: 0.3.0.
|
|
3
|
+
Version: 0.3.0.dev7
|
|
4
4
|
Summary: Python App for BoneIO
|
|
5
5
|
Home-page: https://github.com/boneIO-eu/app_bbb
|
|
6
|
-
Download-URL: https://github.com/boneIO-eu/app_bbb/archive/0.3.0.
|
|
6
|
+
Download-URL: https://github.com/boneIO-eu/app_bbb/archive/0.3.0.dev7.zip
|
|
7
7
|
License: GNU General Public License v3.0
|
|
8
8
|
Platform: UNKNOWN
|
|
9
9
|
Classifier: Programming Language :: Python
|
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
from datetime import timedelta
|
|
3
3
|
|
|
4
4
|
try:
|
|
5
|
-
from Adafruit_BBIO.GPIO import HIGH, LOW, BOTH, FALLING
|
|
5
|
+
from Adafruit_BBIO.GPIO import HIGH, LOW, BOTH, FALLING, RISING
|
|
6
6
|
except ModuleNotFoundError:
|
|
7
7
|
HIGH = "high"
|
|
8
8
|
LOW = "low"
|
|
9
9
|
BOTH = "both"
|
|
10
10
|
FALLING = "falling"
|
|
11
|
+
RISING = "rising"
|
|
11
12
|
pass
|
|
12
13
|
from typing_extensions import Literal
|
|
13
14
|
|
|
@@ -50,12 +51,6 @@ UARTS = {
|
|
|
50
51
|
"uart4": {ID: "/dev/ttyS4", TX: "P9.13", RX: "P9.11"},
|
|
51
52
|
}
|
|
52
53
|
|
|
53
|
-
# TIMINGS FOR BUTTONS
|
|
54
|
-
DEBOUNCE_DURATION = timedelta(seconds=0.2)
|
|
55
|
-
LONG_PRESS_DURATION = timedelta(seconds=0.7)
|
|
56
|
-
DELAY_DURATION = 0.1
|
|
57
|
-
SECOND_DELAY_DURATION = 0.3
|
|
58
|
-
|
|
59
54
|
# HA CONSTS
|
|
60
55
|
HOMEASSISTANT = "homeassistant"
|
|
61
56
|
HA_DISCOVERY = "ha_discovery"
|
|
@@ -113,6 +108,8 @@ BINARY_SENSOR = "binary_sensor"
|
|
|
113
108
|
LM75 = "lm75"
|
|
114
109
|
MCP_TEMP_9808 = "mcp9808"
|
|
115
110
|
INPUT_SENSOR = "inputsensor"
|
|
111
|
+
DS2482 = "ds2482"
|
|
112
|
+
DALLAS = "dallas"
|
|
116
113
|
|
|
117
114
|
BASE = "base"
|
|
118
115
|
LENGTH = "length"
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
"""Cover module."""
|
|
2
2
|
import asyncio
|
|
3
3
|
import logging
|
|
4
|
-
from typing import
|
|
4
|
+
from typing import Callable
|
|
5
5
|
from boneio.const import CLOSE, COVER, IDLE, OPEN, OPENING, CLOSING, CLOSED, STOP
|
|
6
6
|
from boneio.helper.events import EventBus
|
|
7
|
-
from boneio.helper.exceptions import CoverRelayException
|
|
8
7
|
from boneio.helper.mqtt import BasicMqtt
|
|
9
8
|
from boneio.helper.timeperiod import TimePeriod
|
|
10
9
|
from boneio.relay import MCPRelay
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"""Helper dir for BoneIO."""
|
|
2
|
-
from typing import Callable, TypeVar, Any
|
|
3
2
|
|
|
4
3
|
from boneio.helper.gpio import (
|
|
5
4
|
edge_detect,
|
|
@@ -35,20 +34,6 @@ from boneio.helper.exceptions import GPIOInputException, I2CError
|
|
|
35
34
|
from boneio.helper.queue import UniqueQueue
|
|
36
35
|
from boneio.helper.timeperiod import TimePeriod
|
|
37
36
|
|
|
38
|
-
CALLABLE_T = TypeVar("CALLABLE_T", bound=Callable[..., Any])
|
|
39
|
-
CALLBACK_TYPE = Callable[[], None]
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
def callback(func: CALLABLE_T) -> CALLABLE_T:
|
|
43
|
-
"""Annotation to mark method as safe to call from within the event loop."""
|
|
44
|
-
setattr(func, "_boneio_callback", True)
|
|
45
|
-
return func
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
def is_callback(func: Callable[..., Any]) -> bool:
|
|
49
|
-
"""Check if function is safe to be called in the event loop."""
|
|
50
|
-
return getattr(func, "_boneio_callback", False) is True
|
|
51
|
-
|
|
52
37
|
|
|
53
38
|
__all__ = [
|
|
54
39
|
"CustomValidator",
|
|
@@ -80,4 +65,6 @@ __all__ = [
|
|
|
80
65
|
"load_config_from_string",
|
|
81
66
|
"load_config_from_file",
|
|
82
67
|
"TimePeriod",
|
|
68
|
+
"callback",
|
|
69
|
+
"is_callback",
|
|
83
70
|
]
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Module to provide basic config options.
|
|
3
3
|
"""
|
|
4
4
|
from boneio.const import BONEIO, HOMEASSISTANT
|
|
5
|
+
from _collections_abc import dict_values
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
class ConfigHelper:
|
|
@@ -14,6 +15,7 @@ class ConfigHelper:
|
|
|
14
15
|
self._topic_prefix = topic_prefix
|
|
15
16
|
self._ha_discovery = ha_discovery
|
|
16
17
|
self._ha_discovery_prefix = ha_discovery_prefix
|
|
18
|
+
self._autodiscovery_messages = {}
|
|
17
19
|
|
|
18
20
|
@property
|
|
19
21
|
def topic_prefix(self) -> str:
|
|
@@ -34,3 +36,12 @@ class ConfigHelper:
|
|
|
34
36
|
@property
|
|
35
37
|
def subscribe_topic(self) -> str:
|
|
36
38
|
return f"{self.cmd_topic_prefix}+/+/#"
|
|
39
|
+
|
|
40
|
+
def add_autodiscovery_msg(self, topic: str, payload: str):
|
|
41
|
+
"""Add autodiscovery message."""
|
|
42
|
+
self._autodiscovery_messages[topic] = {"topic": topic, "payload": payload}
|
|
43
|
+
|
|
44
|
+
@property
|
|
45
|
+
def autodiscovery_msgs(self) -> dict_values:
|
|
46
|
+
"""Get autodiscovery messages"""
|
|
47
|
+
return self._autodiscovery_messages.values()
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""Helper dir for DS2482."""
|
|
2
|
+
from boneio.helper.ds2482.ds2482 import DS2482, DS2482_ADDRESS
|
|
3
|
+
from boneio.helper.ds2482.onewire import OneWire, OneWireBus
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def ds_address(rom: bytes) -> int:
|
|
7
|
+
return int.from_bytes(rom, "little")
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
__all__ = ["DS2482", "OneWire", "OneWireBus", "ds_address", "DS2482_ADDRESS"]
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"""DS2482 base class.
|
|
2
|
+
Module by https://github.com/fgervais/ds2482
|
|
3
|
+
"""
|
|
4
|
+
import time
|
|
5
|
+
|
|
6
|
+
import adafruit_bus_device.i2c_device as i2c_device
|
|
7
|
+
|
|
8
|
+
# Default i2c address (AD0 = GND, AD1 = GND)
|
|
9
|
+
DS2482_ADDRESS = 0x18
|
|
10
|
+
|
|
11
|
+
# DS2482 device commands
|
|
12
|
+
COMMAND_DEVICE_RESET = 0xF0
|
|
13
|
+
COMMAND_SET_POINTER = 0xE1
|
|
14
|
+
COMMAND_WRITE_CONFIG = 0xD2
|
|
15
|
+
COMMAND_1W_RESET = 0xB4
|
|
16
|
+
COMMAND_1W_SINGLE_BIT = 0x87
|
|
17
|
+
COMMAND_1W_WRITE_BYTE = 0xA5
|
|
18
|
+
COMMAND_1W_READ_BYTE = 0x96
|
|
19
|
+
COMMAND_1W_TRIPLET = 0x78
|
|
20
|
+
|
|
21
|
+
# DS2482 read pointer codes
|
|
22
|
+
POINTER_STATUS = 0xF0
|
|
23
|
+
POINTER_DATA = 0xE1
|
|
24
|
+
POINTER_CONFIG = 0xC3
|
|
25
|
+
|
|
26
|
+
# DS2482 configuration register
|
|
27
|
+
CONFIG_ACTIVE_PULLUP = 0x01
|
|
28
|
+
CONFIG_STRONG_PULLUP = 0x04
|
|
29
|
+
CONFIG_1W_OVERDRIVE = 0x08
|
|
30
|
+
|
|
31
|
+
CONFIG_MASK = 0x0F
|
|
32
|
+
|
|
33
|
+
# DS2482 status register
|
|
34
|
+
STATUS_1W_BUSY = 0x01
|
|
35
|
+
STATUS_PRESENCE_PULSE = 0x02
|
|
36
|
+
STATUT_SHORT_DETECTED = 0x04
|
|
37
|
+
STATUS_LOGIC_LEVEL = 0x08
|
|
38
|
+
STATUS_DEVICE_RESET = 0x10
|
|
39
|
+
STATUS_SINGLE_BIT = 0x20
|
|
40
|
+
STATUS_TRIPLET_BIT = 0x40
|
|
41
|
+
STATUS_BRANCH_TAKEN = 0x80
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class DS2482:
|
|
45
|
+
def __init__(self, i2c, address=DS2482_ADDRESS, active_pullup=False):
|
|
46
|
+
self._i2c = i2c_device.I2CDevice(i2c, address)
|
|
47
|
+
self.device_reset()
|
|
48
|
+
if active_pullup:
|
|
49
|
+
self.device_config = CONFIG_ACTIVE_PULLUP
|
|
50
|
+
|
|
51
|
+
# 1-Wire bus busy with STRONG_PULLUP
|
|
52
|
+
self._bus_busy = time.monotonic()
|
|
53
|
+
|
|
54
|
+
def device_reset(self):
|
|
55
|
+
"""Terminate any 1-wire communication and reset the DS2482"""
|
|
56
|
+
with self._i2c as i2c:
|
|
57
|
+
i2c.write(bytes([COMMAND_DEVICE_RESET]))
|
|
58
|
+
|
|
59
|
+
@property
|
|
60
|
+
def device_status(self):
|
|
61
|
+
with self._i2c as i2c:
|
|
62
|
+
buf = bytearray([COMMAND_SET_POINTER, POINTER_STATUS])
|
|
63
|
+
i2c.write_then_readinto(buf, buf, in_end=1)
|
|
64
|
+
return buf[0]
|
|
65
|
+
|
|
66
|
+
@property
|
|
67
|
+
def device_config(self):
|
|
68
|
+
with self._i2c as i2c:
|
|
69
|
+
buf = bytearray([COMMAND_SET_POINTER, POINTER_CONFIG])
|
|
70
|
+
i2c.write_then_readinto(buf, buf, in_end=1)
|
|
71
|
+
return buf[0] & 0x0F
|
|
72
|
+
|
|
73
|
+
@device_config.setter
|
|
74
|
+
def device_config(self, config):
|
|
75
|
+
with self._i2c as i2c:
|
|
76
|
+
i2c.write(
|
|
77
|
+
bytes([COMMAND_WRITE_CONFIG, (config & 0x0F) | ((~config << 4) & 0xF0)])
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
def reset(self):
|
|
81
|
+
with self._i2c as i2c:
|
|
82
|
+
buf = bytearray([COMMAND_1W_RESET])
|
|
83
|
+
i2c.write(buf)
|
|
84
|
+
while True:
|
|
85
|
+
i2c.readinto(buf)
|
|
86
|
+
if not buf[0] & STATUS_1W_BUSY:
|
|
87
|
+
break
|
|
88
|
+
time.sleep(0.001)
|
|
89
|
+
return not buf[0] & STATUS_PRESENCE_PULSE
|
|
90
|
+
|
|
91
|
+
def single_bit(self, bit=1, strong_pullup=False, busy=None):
|
|
92
|
+
with self._i2c as i2c:
|
|
93
|
+
buf = bytearray(2)
|
|
94
|
+
if strong_pullup:
|
|
95
|
+
buf[0:2] = [COMMAND_SET_POINTER, POINTER_CONFIG]
|
|
96
|
+
i2c.write_then_readinto(buf, buf, in_start=1)
|
|
97
|
+
buf[0] = COMMAND_WRITE_CONFIG
|
|
98
|
+
buf[1] = buf[1] & CONFIG_MASK | CONFIG_STRONG_PULLUP
|
|
99
|
+
buf[1] |= (~buf[1] << 4) & 0xFF
|
|
100
|
+
i2c.write(buf)
|
|
101
|
+
buf[0:2] = [COMMAND_1W_SINGLE_BIT, 0x80 if bit else 0x00]
|
|
102
|
+
i2c.write(buf)
|
|
103
|
+
while True:
|
|
104
|
+
i2c.readinto(buf, end=1)
|
|
105
|
+
if not buf[0] & STATUS_1W_BUSY:
|
|
106
|
+
break
|
|
107
|
+
time.sleep(0.001)
|
|
108
|
+
if busy:
|
|
109
|
+
self._bus_busy = time.monotonic() + busy
|
|
110
|
+
return buf[0] & STATUS_SINGLE_BIT != 0
|
|
111
|
+
|
|
112
|
+
def write_byte(self, data, strong_pullup=False, busy=None):
|
|
113
|
+
with self._i2c as i2c:
|
|
114
|
+
buf = bytearray(2)
|
|
115
|
+
if strong_pullup:
|
|
116
|
+
buf[0:2] = [COMMAND_SET_POINTER, POINTER_CONFIG]
|
|
117
|
+
i2c.write_then_readinto(buf, buf, in_start=1)
|
|
118
|
+
buf[0] = COMMAND_WRITE_CONFIG
|
|
119
|
+
buf[1] = buf[1] & CONFIG_MASK | CONFIG_STRONG_PULLUP
|
|
120
|
+
buf[1] |= (~buf[1] << 4) & 0xFF
|
|
121
|
+
i2c.write(buf)
|
|
122
|
+
buf[0:2] = [COMMAND_1W_WRITE_BYTE, data]
|
|
123
|
+
i2c.write(buf)
|
|
124
|
+
while True:
|
|
125
|
+
i2c.readinto(buf, end=1)
|
|
126
|
+
if buf[0] & STATUS_1W_BUSY == 0:
|
|
127
|
+
break
|
|
128
|
+
time.sleep(0.001)
|
|
129
|
+
if busy:
|
|
130
|
+
self._bus_busy = time.monotonic() + busy
|
|
131
|
+
|
|
132
|
+
def read_byte(self):
|
|
133
|
+
with self._i2c as i2c:
|
|
134
|
+
buf = bytearray([COMMAND_1W_READ_BYTE, 0x00])
|
|
135
|
+
i2c.write(buf, end=1)
|
|
136
|
+
while True:
|
|
137
|
+
i2c.readinto(buf, end=1)
|
|
138
|
+
if not buf[0] & STATUS_1W_BUSY:
|
|
139
|
+
break
|
|
140
|
+
time.sleep(0.001)
|
|
141
|
+
buf[0:2] = [COMMAND_SET_POINTER, POINTER_DATA]
|
|
142
|
+
i2c.write_then_readinto(buf, buf, in_end=1)
|
|
143
|
+
return buf[0]
|
|
144
|
+
|
|
145
|
+
def wait_ready(self):
|
|
146
|
+
while True:
|
|
147
|
+
t = self._bus_busy - time.monotonic()
|
|
148
|
+
if t > 0:
|
|
149
|
+
time.sleep(t)
|
|
150
|
+
else:
|
|
151
|
+
break
|
|
152
|
+
with self._i2c as i2c:
|
|
153
|
+
buf = bytearray([COMMAND_SET_POINTER, POINTER_STATUS])
|
|
154
|
+
i2c.write(buf)
|
|
155
|
+
while True:
|
|
156
|
+
i2c.readinto(buf, end=1)
|
|
157
|
+
if not buf[0] & STATUS_1W_BUSY:
|
|
158
|
+
break
|
|
159
|
+
time.sleep(0.001)
|
|
160
|
+
return buf[0]
|
|
161
|
+
|
|
162
|
+
def triplet(self, dir):
|
|
163
|
+
pass
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"""OneWire base class for DS2482.
|
|
2
|
+
Module by https://github.com/fgervais/ds2482
|
|
3
|
+
"""
|
|
4
|
+
import adafruit_onewire.bus
|
|
5
|
+
import busio
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class OneWire(busio.OneWire):
|
|
9
|
+
def __init__(self, ds2482):
|
|
10
|
+
self.ds2482 = ds2482
|
|
11
|
+
|
|
12
|
+
def deinit(self):
|
|
13
|
+
"""
|
|
14
|
+
Deinitialize the OneWire bus and release any hardware resources for reuse.
|
|
15
|
+
"""
|
|
16
|
+
self.ds2482.device_reset()
|
|
17
|
+
|
|
18
|
+
def reset(self):
|
|
19
|
+
"""
|
|
20
|
+
Reset the OneWire bus and read presence
|
|
21
|
+
|
|
22
|
+
:return: False when at least one device is present
|
|
23
|
+
"""
|
|
24
|
+
return self.ds2482.reset()
|
|
25
|
+
|
|
26
|
+
def read_bit(self):
|
|
27
|
+
"""
|
|
28
|
+
Read in a bit
|
|
29
|
+
"""
|
|
30
|
+
return self.ds2482.single_bit()
|
|
31
|
+
|
|
32
|
+
def write_bit(self, value):
|
|
33
|
+
"""
|
|
34
|
+
Write out a bit based on value.
|
|
35
|
+
"""
|
|
36
|
+
self.ds2482.single_bit(value)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class OneWireBus(adafruit_onewire.bus.OneWireBus):
|
|
40
|
+
def __init__(self, ds2482):
|
|
41
|
+
self._ow = OneWire(ds2482)
|
|
42
|
+
self._readbit = self._ow.read_bit
|
|
43
|
+
self._writebit = self._ow.write_bit
|
|
44
|
+
self._maximum_devices = adafruit_onewire.bus._MAX_DEV
|
|
@@ -3,9 +3,9 @@ import datetime as dt
|
|
|
3
3
|
import signal
|
|
4
4
|
import logging
|
|
5
5
|
import time
|
|
6
|
-
from typing import Callable
|
|
6
|
+
from typing import Callable, Optional
|
|
7
7
|
from datetime import datetime
|
|
8
|
-
from boneio.helper import callback
|
|
8
|
+
from boneio.helper.util import callback
|
|
9
9
|
|
|
10
10
|
_LOGGER = logging.getLogger(__name__)
|
|
11
11
|
UTC = dt.timezone.utc
|
|
@@ -139,9 +139,9 @@ def async_track_point_in_time(
|
|
|
139
139
|
# Ensure point_in_time is UTC
|
|
140
140
|
utc_point_in_time = as_utc(point_in_time)
|
|
141
141
|
|
|
142
|
-
# Since this is called once, we accept a
|
|
142
|
+
# Since this is called once, we accept a so we can avoid
|
|
143
143
|
# having to figure out how to call the action every time its called.
|
|
144
|
-
cancel_callback: asyncio.TimerHandle
|
|
144
|
+
cancel_callback: Optional[asyncio.TimerHandle] = None
|
|
145
145
|
|
|
146
146
|
@callback
|
|
147
147
|
def run_action(job) -> None:
|
|
@@ -97,7 +97,7 @@ class GpioBaseClass:
|
|
|
97
97
|
self._pin = pin
|
|
98
98
|
gpio = kwargs.get("rest_pin", {GPIO_MODE: GPIO_STR})
|
|
99
99
|
gpio_mode = gpio.get(GPIO_MODE, GPIO_STR)
|
|
100
|
-
self._bounce_time = gpio.get("bounce_time", TimePeriod(milliseconds=
|
|
100
|
+
self._bounce_time = gpio.get("bounce_time", TimePeriod(milliseconds=10))
|
|
101
101
|
self._loop = asyncio.get_running_loop()
|
|
102
102
|
self._press_callback = press_callback
|
|
103
103
|
setup_input(pin=self._pin, pull_mode=gpio_mode)
|
|
@@ -43,10 +43,13 @@ from boneio.helper import (
|
|
|
43
43
|
ha_input_availabilty_message,
|
|
44
44
|
ha_sensor_temp_availabilty_message,
|
|
45
45
|
)
|
|
46
|
+
from adafruit_onewire.bus import OneWireAddress
|
|
47
|
+
from boneio.helper.ds2482 import DS2482, OneWireBus, ds_address, DS2482_ADDRESS
|
|
46
48
|
from boneio.helper.ha_discovery import ha_cover_availabilty_message
|
|
47
49
|
from boneio.helper.timeperiod import TimePeriod
|
|
48
50
|
from boneio.input.gpio import GpioInputButton
|
|
49
51
|
from boneio.helper.config import ConfigHelper
|
|
52
|
+
from boneio.sensor import DallasSensor
|
|
50
53
|
|
|
51
54
|
# Typing imports that create a circular dependency
|
|
52
55
|
if TYPE_CHECKING:
|
|
@@ -116,6 +119,7 @@ def create_temp_sensor(
|
|
|
116
119
|
address=temp_def[ADDRESS],
|
|
117
120
|
send_message=manager.send_message,
|
|
118
121
|
topic_prefix=topic_prefix,
|
|
122
|
+
update_interval=temp_def.get(UPDATE_INTERVAL, TimePeriod(seconds=60)),
|
|
119
123
|
)
|
|
120
124
|
manager.send_ha_autodiscovery(
|
|
121
125
|
id=id,
|
|
@@ -343,3 +347,47 @@ def configure_cover(
|
|
|
343
347
|
availability_msg_func=ha_cover_availabilty_message,
|
|
344
348
|
)
|
|
345
349
|
return cover
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
def configure_ds2482(i2cbusio: I2C, address: str = DS2482_ADDRESS) -> OneWireBus:
|
|
353
|
+
ds2482 = DS2482(i2c=i2cbusio, address=address)
|
|
354
|
+
ow_bus = OneWireBus(ds2482=ds2482)
|
|
355
|
+
return ow_bus
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
def find_onewire_devices(ow_bus: OneWireBus):
|
|
359
|
+
devices = ow_bus.scan()
|
|
360
|
+
out = {}
|
|
361
|
+
for device in devices:
|
|
362
|
+
_addr: int = ds_address(device.rom)
|
|
363
|
+
_LOGGER.debug("Found device with address %s", hex(_addr))
|
|
364
|
+
out[_addr] = device
|
|
365
|
+
return out
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
def create_ds2482_dallas_sensor(
|
|
369
|
+
manager: Manager,
|
|
370
|
+
ds2482_bus: OneWireBus,
|
|
371
|
+
address: OneWireAddress,
|
|
372
|
+
config: dict,
|
|
373
|
+
**kwargs,
|
|
374
|
+
):
|
|
375
|
+
name = config.get(ID) or hex(address)
|
|
376
|
+
id = name.replace(" ", "")
|
|
377
|
+
sensor = DallasSensor(
|
|
378
|
+
bus=ds2482_bus,
|
|
379
|
+
address=address,
|
|
380
|
+
id=id,
|
|
381
|
+
name=name,
|
|
382
|
+
update_interval=config.get(UPDATE_INTERVAL, TimePeriod(seconds=60)),
|
|
383
|
+
send_message=manager.send_message,
|
|
384
|
+
**kwargs,
|
|
385
|
+
)
|
|
386
|
+
if config.get(SHOW_HA, True):
|
|
387
|
+
manager.send_ha_autodiscovery(
|
|
388
|
+
id=sensor.id,
|
|
389
|
+
name=sensor.name,
|
|
390
|
+
ha_type=SENSOR,
|
|
391
|
+
availability_msg_func=ha_sensor_temp_availabilty_message,
|
|
392
|
+
)
|
|
393
|
+
return sensor
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from typing import Callable, TypeVar, Any
|
|
2
|
+
|
|
3
|
+
CALLABLE_T = TypeVar("CALLABLE_T", bound=Callable[..., Any])
|
|
4
|
+
CALLBACK_TYPE = Callable[[], None]
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def callback(func: CALLABLE_T) -> CALLABLE_T:
|
|
8
|
+
"""Annotation to mark method as safe to call from within the event loop."""
|
|
9
|
+
setattr(func, "_boneio_callback", True)
|
|
10
|
+
return func
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def is_callback(func: Callable[..., Any]) -> bool:
|
|
14
|
+
"""Check if function is safe to be called in the event loop."""
|
|
15
|
+
return getattr(func, "_boneio_callback", False) is True
|
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
"""GPIOInputButton to receive signals."""
|
|
2
2
|
import logging
|
|
3
|
-
from datetime import datetime
|
|
3
|
+
from datetime import datetime, timedelta
|
|
4
4
|
from functools import partial
|
|
5
5
|
|
|
6
6
|
from boneio.const import (
|
|
7
|
-
DEBOUNCE_DURATION,
|
|
8
|
-
DELAY_DURATION,
|
|
9
7
|
DOUBLE,
|
|
10
8
|
LONG,
|
|
11
|
-
LONG_PRESS_DURATION,
|
|
12
|
-
SECOND_DELAY_DURATION,
|
|
13
9
|
SINGLE,
|
|
14
10
|
)
|
|
15
11
|
from boneio.helper import edge_detect, GpioBaseClass
|
|
16
12
|
|
|
13
|
+
# TIMINGS FOR BUTTONS
|
|
14
|
+
DEBOUNCE_DURATION = timedelta(microseconds=150000)
|
|
15
|
+
LONG_PRESS_DURATION = timedelta(microseconds=700000)
|
|
16
|
+
DELAY_DURATION = 0.08
|
|
17
|
+
SECOND_DELAY_DURATION = 0.14
|
|
18
|
+
|
|
17
19
|
_LOGGER = logging.getLogger(__name__)
|
|
18
20
|
|
|
19
21
|
|
|
@@ -54,7 +56,6 @@ class GpioInputButton(GpioBaseClass):
|
|
|
54
56
|
and now - self._second_press_timestamp < DEBOUNCE_DURATION
|
|
55
57
|
):
|
|
56
58
|
return
|
|
57
|
-
|
|
58
59
|
if not self._first_press_timestamp:
|
|
59
60
|
self._first_press_timestamp = now
|
|
60
61
|
elif not self._second_press_timestamp:
|
|
@@ -105,7 +106,7 @@ class GpioInputButton(GpioBaseClass):
|
|
|
105
106
|
if self._second_check:
|
|
106
107
|
if self._second_press_timestamp:
|
|
107
108
|
_LOGGER.debug(
|
|
108
|
-
"Double click event on pin %s,
|
|
109
|
+
"Double click event on pin %s, diff %s",
|
|
109
110
|
self._pin,
|
|
110
111
|
self._second_press_timestamp - self._first_press_timestamp,
|
|
111
112
|
)
|
|
@@ -7,6 +7,7 @@ from busio import I2C
|
|
|
7
7
|
|
|
8
8
|
from boneio.const import (
|
|
9
9
|
ACTION,
|
|
10
|
+
ADDRESS,
|
|
10
11
|
BUTTON,
|
|
11
12
|
CLOSE,
|
|
12
13
|
COVER,
|
|
@@ -51,6 +52,7 @@ from boneio.helper.loader import (
|
|
|
51
52
|
configure_relay,
|
|
52
53
|
create_mcp23017,
|
|
53
54
|
create_temp_sensor,
|
|
55
|
+
create_ds2482_dallas_sensor,
|
|
54
56
|
)
|
|
55
57
|
from boneio.helper.yaml_util import load_config_from_file
|
|
56
58
|
from boneio.modbus import Modbus
|
|
@@ -75,6 +77,8 @@ class Manager:
|
|
|
75
77
|
sensors: dict = {},
|
|
76
78
|
modbus: dict = None,
|
|
77
79
|
mcp23017: Optional[List] = None,
|
|
80
|
+
ds2482: Optional[dict] = None,
|
|
81
|
+
dallas: Optional[List] = None,
|
|
78
82
|
oled: dict = {},
|
|
79
83
|
adc_list: Optional[List] = None,
|
|
80
84
|
covers: Optional[List] = [],
|
|
@@ -98,6 +102,8 @@ class Manager:
|
|
|
98
102
|
self._oled = None
|
|
99
103
|
self._tasks: List[asyncio.Task] = []
|
|
100
104
|
self._covers = {}
|
|
105
|
+
self._ds_onewire = {}
|
|
106
|
+
self._ds_onewire_bus = {}
|
|
101
107
|
self._temp_sensors = []
|
|
102
108
|
self._modbus = None
|
|
103
109
|
if modbus and modbus.get(UART) in UARTS:
|
|
@@ -130,6 +136,33 @@ class Manager:
|
|
|
130
136
|
manager=self, mcp23017=mcp23017, i2cbusio=self._i2cbusio
|
|
131
137
|
)
|
|
132
138
|
|
|
139
|
+
if ds2482:
|
|
140
|
+
_LOGGER.debug("Preparing DS2482 bus.")
|
|
141
|
+
from boneio.helper.loader import configure_ds2482, find_onewire_devices
|
|
142
|
+
|
|
143
|
+
self._ds_onewire_bus[ds2482[ID]] = configure_ds2482(
|
|
144
|
+
i2cbusio=self._i2cbusio, address=ds2482[ADDRESS]
|
|
145
|
+
)
|
|
146
|
+
self._ds_onewire = find_onewire_devices(
|
|
147
|
+
ow_bus=self._ds_onewire_bus[ds2482[ID]]
|
|
148
|
+
)
|
|
149
|
+
for sensor in dallas:
|
|
150
|
+
ds2482_bus_id = sensor.get("ds2482_id")
|
|
151
|
+
if ds2482_bus_id and ds2482_bus_id in self._ds_onewire_bus:
|
|
152
|
+
address = self._ds_onewire.get(sensor[ADDRESS])
|
|
153
|
+
if not address:
|
|
154
|
+
continue
|
|
155
|
+
|
|
156
|
+
self._temp_sensors.append(
|
|
157
|
+
create_ds2482_dallas_sensor(
|
|
158
|
+
manager=self,
|
|
159
|
+
ds2482_bus=self._ds_onewire_bus[ds2482_bus_id],
|
|
160
|
+
address=address,
|
|
161
|
+
topic_prefix=self._config_helper.topic_prefix,
|
|
162
|
+
config=sensor,
|
|
163
|
+
)
|
|
164
|
+
)
|
|
165
|
+
|
|
133
166
|
if adc_list:
|
|
134
167
|
from boneio.helper.loader import create_adc
|
|
135
168
|
|
|
@@ -341,14 +374,14 @@ class Manager:
|
|
|
341
374
|
if not self._config_helper.ha_discovery:
|
|
342
375
|
return
|
|
343
376
|
topic_prefix = topic_prefix or self._config_helper.topic_prefix
|
|
344
|
-
|
|
377
|
+
payload = availability_msg_func(topic=topic_prefix, id=id, name=name, **kwargs)
|
|
345
378
|
topic = f"{self._config_helper.ha_discovery_prefix}/{ha_type}/{topic_prefix}/{id}/config"
|
|
346
379
|
_LOGGER.debug("Sending HA discovery for %s, %s.", ha_type, name)
|
|
347
|
-
self.
|
|
348
|
-
self.send_message(topic=topic, payload=
|
|
380
|
+
self._config_helper.add_autodiscovery_msg(topic=topic, payload=payload)
|
|
381
|
+
self.send_message(topic=topic, payload=payload, retain=True)
|
|
349
382
|
|
|
350
383
|
def resend_autodiscovery(self):
|
|
351
|
-
for msg in self.
|
|
384
|
+
for msg in self._config_helper.autodiscovery_msgs:
|
|
352
385
|
self.send_message(**msg, retain=True)
|
|
353
386
|
|
|
354
387
|
async def receive_message(self, topic: str, message: str) -> None:
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
4
|
from adafruit_mcp230xx.mcp23017 import MCP23017, DigitalInOut
|
|
5
|
-
from boneio.helper import callback
|
|
5
|
+
from boneio.helper.util import callback
|
|
6
6
|
from boneio.relay.basic import BasicRelay
|
|
7
7
|
from boneio.const import SWITCH, NONE
|
|
8
8
|
from boneio.helper.events import async_track_point_in_time, utcnow
|
|
@@ -5,6 +5,7 @@ import os
|
|
|
5
5
|
from boneio.const import (
|
|
6
6
|
ADC,
|
|
7
7
|
COVER,
|
|
8
|
+
DALLAS,
|
|
8
9
|
ENABLED,
|
|
9
10
|
HA_DISCOVERY,
|
|
10
11
|
HOST,
|
|
@@ -20,6 +21,7 @@ from boneio.const import (
|
|
|
20
21
|
PORT,
|
|
21
22
|
TOPIC_PREFIX,
|
|
22
23
|
USERNAME,
|
|
24
|
+
DS2482,
|
|
23
25
|
)
|
|
24
26
|
|
|
25
27
|
_LOGGER = logging.getLogger(__name__)
|
|
@@ -66,6 +68,8 @@ async def async_run(
|
|
|
66
68
|
MODBUS: config.get("modbus_sensors"),
|
|
67
69
|
},
|
|
68
70
|
mcp23017=config.get(MCP23017, []),
|
|
71
|
+
ds2482=config.get(DS2482),
|
|
72
|
+
dallas=config.get(DALLAS, []),
|
|
69
73
|
modbus=config.get(MODBUS),
|
|
70
74
|
oled=config.get(OLED),
|
|
71
75
|
adc_list=config.get(ADC, []),
|
|
@@ -146,6 +146,17 @@ lm75:
|
|
|
146
146
|
default: 0x48
|
|
147
147
|
meta:
|
|
148
148
|
label: Address of I2C
|
|
149
|
+
update_interval:
|
|
150
|
+
type:
|
|
151
|
+
- string
|
|
152
|
+
- timeperiod
|
|
153
|
+
coerce:
|
|
154
|
+
- str
|
|
155
|
+
- positive_time_period
|
|
156
|
+
required: True
|
|
157
|
+
default: 60s
|
|
158
|
+
meta:
|
|
159
|
+
label: Update interval.
|
|
149
160
|
|
|
150
161
|
|
|
151
162
|
mcp9808:
|
|
@@ -162,7 +173,18 @@ mcp9808:
|
|
|
162
173
|
required: True
|
|
163
174
|
default: 0x18
|
|
164
175
|
meta:
|
|
165
|
-
label:
|
|
176
|
+
label: Address of I2C device
|
|
177
|
+
update_interval:
|
|
178
|
+
type:
|
|
179
|
+
- string
|
|
180
|
+
- timeperiod
|
|
181
|
+
coerce:
|
|
182
|
+
- str
|
|
183
|
+
- positive_time_period
|
|
184
|
+
required: True
|
|
185
|
+
default: 60s
|
|
186
|
+
meta:
|
|
187
|
+
label: Update interval.
|
|
166
188
|
|
|
167
189
|
mcp23017:
|
|
168
190
|
type: list
|
|
@@ -356,6 +378,7 @@ adc:
|
|
|
356
378
|
label: If you want you can disable discovering this input in HA.
|
|
357
379
|
cover:
|
|
358
380
|
type: list
|
|
381
|
+
required: False
|
|
359
382
|
meta:
|
|
360
383
|
label: Cover section
|
|
361
384
|
schema:
|
|
@@ -414,3 +437,60 @@ cover:
|
|
|
414
437
|
default: True
|
|
415
438
|
meta:
|
|
416
439
|
label: If you want you can disable discovering this input in HA.
|
|
440
|
+
|
|
441
|
+
ds2482:
|
|
442
|
+
type: dict
|
|
443
|
+
required: False
|
|
444
|
+
schema:
|
|
445
|
+
id:
|
|
446
|
+
type: string
|
|
447
|
+
required: True
|
|
448
|
+
meta:
|
|
449
|
+
label: Id of I2C to use in pin config
|
|
450
|
+
address:
|
|
451
|
+
type: string
|
|
452
|
+
required: True
|
|
453
|
+
default: 0x18
|
|
454
|
+
meta:
|
|
455
|
+
label: GPIO of I2C SDA
|
|
456
|
+
|
|
457
|
+
dallas:
|
|
458
|
+
type: list
|
|
459
|
+
required: False
|
|
460
|
+
meta:
|
|
461
|
+
label: Dallas DS18B20 section
|
|
462
|
+
schema:
|
|
463
|
+
type: dict
|
|
464
|
+
schema:
|
|
465
|
+
id:
|
|
466
|
+
type: string
|
|
467
|
+
required: False
|
|
468
|
+
meta:
|
|
469
|
+
label: Id to use in HA if needed. Default to address.
|
|
470
|
+
address:
|
|
471
|
+
type: integer
|
|
472
|
+
required: True
|
|
473
|
+
meta:
|
|
474
|
+
label: Address of Dallas device
|
|
475
|
+
ds2482_id:
|
|
476
|
+
type: string
|
|
477
|
+
required: False
|
|
478
|
+
meta:
|
|
479
|
+
label: Put DS2482 defined id if you want to add DS18B20 connected via DS2482.
|
|
480
|
+
show_in_ha:
|
|
481
|
+
type: boolean
|
|
482
|
+
required: True
|
|
483
|
+
default: True
|
|
484
|
+
meta:
|
|
485
|
+
label: If you want you can disable discovering this input in HA.
|
|
486
|
+
update_interval:
|
|
487
|
+
type:
|
|
488
|
+
- string
|
|
489
|
+
- timeperiod
|
|
490
|
+
coerce:
|
|
491
|
+
- str
|
|
492
|
+
- positive_time_period
|
|
493
|
+
required: True
|
|
494
|
+
default: 60s
|
|
495
|
+
meta:
|
|
496
|
+
label: Update interval.
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
"""Sensor module."""
|
|
2
|
-
from boneio.sensor.temp import LM75Sensor
|
|
2
|
+
from boneio.sensor.temp.lm75 import LM75Sensor
|
|
3
|
+
from boneio.sensor.temp.mcp9808 import MCP9808Sensor
|
|
4
|
+
from boneio.sensor.temp.dallas import DallasSensor
|
|
3
5
|
from boneio.sensor.gpio import GpioInputSensor
|
|
4
6
|
from boneio.sensor.adc import initialize_adc, GpioADCSensor
|
|
5
7
|
|
|
6
8
|
__all__ = [
|
|
9
|
+
"DallasSensor",
|
|
7
10
|
"LM75Sensor",
|
|
8
11
|
"MCP9808Sensor",
|
|
9
12
|
"GpioInputSensor",
|
|
@@ -122,20 +122,20 @@ class ModbusSensor(BasicMqtt):
|
|
|
122
122
|
) -> None:
|
|
123
123
|
"""Send HA autodiscovery information for each Modbus sensor."""
|
|
124
124
|
_LOGGER.debug("Sending HA discovery for sensor %s %s.", sdm_name, sensor_id)
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
f"/{id}{sensor_id.replace('_', '').replace(' ', '').lower()}/config"
|
|
129
|
-
),
|
|
130
|
-
payload=modbus_sensor_availabilty_message(
|
|
131
|
-
topic=self._config_helper.topic_prefix,
|
|
132
|
-
id=id,
|
|
133
|
-
name=sdm_name,
|
|
134
|
-
model=self._model,
|
|
135
|
-
sensor_id=sensor_id,
|
|
136
|
-
**kwargs,
|
|
137
|
-
),
|
|
125
|
+
topic = (
|
|
126
|
+
f"{self._config_helper.ha_discovery_prefix}/{SENSOR}/{self._config_helper.topic_prefix}{id}"
|
|
127
|
+
f"/{id}{sensor_id.replace('_', '').replace(' ', '').lower()}/config"
|
|
138
128
|
)
|
|
129
|
+
payload = modbus_sensor_availabilty_message(
|
|
130
|
+
topic=self._config_helper.topic_prefix,
|
|
131
|
+
id=id,
|
|
132
|
+
name=sdm_name,
|
|
133
|
+
model=self._model,
|
|
134
|
+
sensor_id=sensor_id,
|
|
135
|
+
**kwargs,
|
|
136
|
+
)
|
|
137
|
+
self._config_helper.add_autodiscovery_msg(topic=topic, payload=payload)
|
|
138
|
+
self._send_message(topic=topic, payload=payload)
|
|
139
139
|
|
|
140
140
|
def _send_discovery_for_all_registers(self, register: int = 0) -> bool:
|
|
141
141
|
"""Send discovery message to HA for each register."""
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"""Manage BoneIO onboard temp sensors."""
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
from datetime import datetime, timedelta
|
|
5
|
+
from typing import Optional
|
|
6
|
+
|
|
7
|
+
from boneio.const import STATE, SENSOR, TEMPERATURE
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
from boneio.helper.exceptions import I2CError
|
|
11
|
+
from boneio.helper import BasicMqtt
|
|
12
|
+
|
|
13
|
+
from boneio.helper.util import callback
|
|
14
|
+
from boneio.helper.events import async_track_point_in_time, utcnow
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
from boneio.helper.timeperiod import TimePeriod
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class TempSensor(BasicMqtt):
|
|
21
|
+
"""Represent Temp sensor in BoneIO."""
|
|
22
|
+
|
|
23
|
+
SensorClass = None
|
|
24
|
+
DefaultName = TEMPERATURE
|
|
25
|
+
|
|
26
|
+
def __init__(
|
|
27
|
+
self,
|
|
28
|
+
i2c,
|
|
29
|
+
address: str,
|
|
30
|
+
id: str = DefaultName,
|
|
31
|
+
update_interval: int = TimePeriod(seconds=60),
|
|
32
|
+
**kwargs
|
|
33
|
+
):
|
|
34
|
+
"""Initialize Temp class."""
|
|
35
|
+
super().__init__(id=id, topic_type=SENSOR, **kwargs)
|
|
36
|
+
self._update_interval = update_interval
|
|
37
|
+
self._loop = asyncio.get_event_loop()
|
|
38
|
+
try:
|
|
39
|
+
self._pct = self.SensorClass(i2c_bus=i2c, address=address)
|
|
40
|
+
self._unsub_refresh = None
|
|
41
|
+
self._schedule_refresh(utcnow() + timedelta(seconds=2))
|
|
42
|
+
except ValueError as err:
|
|
43
|
+
raise I2CError(err)
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def state(self):
|
|
47
|
+
"""Give rounded value of temperature."""
|
|
48
|
+
return round(self._pct.temperature, 2)
|
|
49
|
+
|
|
50
|
+
def _schedule_refresh(self, update_time: Optional[datetime] = None):
|
|
51
|
+
if self._unsub_refresh:
|
|
52
|
+
self._unsub_refresh()
|
|
53
|
+
self._unsub_refresh = None
|
|
54
|
+
if not update_time:
|
|
55
|
+
update_time = utcnow() + self._update_interval.as_timedelta
|
|
56
|
+
self._unsub_refresh = async_track_point_in_time(
|
|
57
|
+
loop=self._loop,
|
|
58
|
+
action=self._refresh,
|
|
59
|
+
point_in_time=update_time,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
@callback
|
|
63
|
+
def _refresh(self, time: datetime):
|
|
64
|
+
if self._unsub_refresh:
|
|
65
|
+
self._unsub_refresh()
|
|
66
|
+
self._unsub_refresh = None
|
|
67
|
+
|
|
68
|
+
self.send_state()
|
|
69
|
+
self._schedule_refresh()
|
|
70
|
+
|
|
71
|
+
def send_state(self):
|
|
72
|
+
"""Fetch temperature periodically and send to MQTT."""
|
|
73
|
+
self._send_message(
|
|
74
|
+
topic=self._send_topic,
|
|
75
|
+
payload={STATE: self.state},
|
|
76
|
+
)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""Dallas temp sensor."""
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
from datetime import timedelta
|
|
5
|
+
|
|
6
|
+
# from datetime import timedelta
|
|
7
|
+
from adafruit_ds18x20 import DS18X20
|
|
8
|
+
from adafruit_onewire.bus import OneWireAddress
|
|
9
|
+
from boneio.const import SENSOR, TEMPERATURE
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
from boneio.helper.exceptions import OneWireError
|
|
13
|
+
from boneio.helper import BasicMqtt
|
|
14
|
+
|
|
15
|
+
from boneio.helper.events import utcnow
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
from boneio.helper.timeperiod import TimePeriod
|
|
19
|
+
from . import TempSensor
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class DallasSensor(TempSensor):
|
|
23
|
+
DefaultName = TEMPERATURE
|
|
24
|
+
SensorClass = DS18X20
|
|
25
|
+
|
|
26
|
+
def __init__(
|
|
27
|
+
self,
|
|
28
|
+
bus,
|
|
29
|
+
address: OneWireAddress,
|
|
30
|
+
id: str = DefaultName,
|
|
31
|
+
update_interval: int = TimePeriod(seconds=60),
|
|
32
|
+
**kwargs
|
|
33
|
+
):
|
|
34
|
+
"""Initialize Temp class."""
|
|
35
|
+
self._update_interval = update_interval
|
|
36
|
+
self._loop = asyncio.get_event_loop()
|
|
37
|
+
BasicMqtt.__init__(self, id=id, topic_type=SENSOR, **kwargs)
|
|
38
|
+
try:
|
|
39
|
+
self._pct = DS18X20(bus=bus, address=address)
|
|
40
|
+
self._unsub_refresh = None
|
|
41
|
+
self._schedule_refresh(utcnow() + timedelta(seconds=2))
|
|
42
|
+
except ValueError as err:
|
|
43
|
+
raise OneWireError(err)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""MCP9808 temp sensor."""
|
|
2
|
+
|
|
3
|
+
from . import TempSensor
|
|
4
|
+
from adafruit_mcp9808 import MCP9808
|
|
5
|
+
from boneio.const import MCP_TEMP_9808
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class MCP9808Sensor(TempSensor):
|
|
9
|
+
"""Represent MCP9808 sensor in BoneIO."""
|
|
10
|
+
|
|
11
|
+
SensorClass = MCP9808
|
|
12
|
+
DefaultName = MCP_TEMP_9808
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: boneio
|
|
3
|
-
Version: 0.3.0.
|
|
3
|
+
Version: 0.3.0.dev7
|
|
4
4
|
Summary: Python App for BoneIO
|
|
5
5
|
Home-page: https://github.com/boneIO-eu/app_bbb
|
|
6
|
-
Download-URL: https://github.com/boneIO-eu/app_bbb/archive/0.3.0.
|
|
6
|
+
Download-URL: https://github.com/boneIO-eu/app_bbb/archive/0.3.0.dev7.zip
|
|
7
7
|
License: GNU General Public License v3.0
|
|
8
8
|
Platform: UNKNOWN
|
|
9
9
|
Classifier: Programming Language :: Python
|
|
@@ -41,7 +41,11 @@ boneio/helper/queue.py
|
|
|
41
41
|
boneio/helper/state_manager.py
|
|
42
42
|
boneio/helper/stats.py
|
|
43
43
|
boneio/helper/timeperiod.py
|
|
44
|
+
boneio/helper/util.py
|
|
44
45
|
boneio/helper/yaml_util.py
|
|
46
|
+
boneio/helper/ds2482/__init__.py
|
|
47
|
+
boneio/helper/ds2482/ds2482.py
|
|
48
|
+
boneio/helper/ds2482/onewire.py
|
|
45
49
|
boneio/input/__init__.py
|
|
46
50
|
boneio/input/gpio.py
|
|
47
51
|
boneio/relay/__init__.py
|
|
@@ -59,4 +63,7 @@ boneio/sensor/modbus/__init__.py
|
|
|
59
63
|
boneio/sensor/modbus/sdm120.json
|
|
60
64
|
boneio/sensor/modbus/sdm630.json
|
|
61
65
|
boneio/sensor/modbus/sofar.json
|
|
62
|
-
boneio/sensor/temp/__init__.py
|
|
66
|
+
boneio/sensor/temp/__init__.py
|
|
67
|
+
boneio/sensor/temp/dallas.py
|
|
68
|
+
boneio/sensor/temp/lm75.py
|
|
69
|
+
boneio/sensor/temp/mcp9808.py
|
|
@@ -31,6 +31,7 @@ setup(
|
|
|
31
31
|
install_requires=[
|
|
32
32
|
"Adafruit-BBIO==1.2.0",
|
|
33
33
|
"Adafruit-Blinka==6.20.4",
|
|
34
|
+
"adafruit-circuitpython-ds18x20==1.3.10",
|
|
34
35
|
"adafruit-circuitpython-mcp230xx==2.5.3",
|
|
35
36
|
"adafruit-circuitpython-mcp9808==3.3.10",
|
|
36
37
|
"adafruit-circuitpython-pct2075==1.1.12",
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
"""Manage BoneIO onboard temp sensors."""
|
|
2
|
-
|
|
3
|
-
import asyncio
|
|
4
|
-
from adafruit_pct2075 import PCT2075
|
|
5
|
-
from adafruit_mcp9808 import MCP9808
|
|
6
|
-
from boneio.const import STATE, SENSOR, LM75, MCP_TEMP_9808, TEMPERATURE
|
|
7
|
-
|
|
8
|
-
from boneio.helper.exceptions import I2CError
|
|
9
|
-
from boneio.helper import BasicMqtt
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class TempSensor(BasicMqtt):
|
|
13
|
-
"""Represent Temp sensor in BoneIO."""
|
|
14
|
-
|
|
15
|
-
SensorClass = None
|
|
16
|
-
DefaultName = TEMPERATURE
|
|
17
|
-
|
|
18
|
-
def __init__(self, i2c, address, id: str = DefaultName, **kwargs):
|
|
19
|
-
"""Initialize Temp class."""
|
|
20
|
-
super().__init__(id=id, topic_type=SENSOR, **kwargs)
|
|
21
|
-
try:
|
|
22
|
-
self._pct = self.SensorClass(i2c_bus=i2c, address=address)
|
|
23
|
-
except ValueError as err:
|
|
24
|
-
raise I2CError(err)
|
|
25
|
-
|
|
26
|
-
@property
|
|
27
|
-
def state(self):
|
|
28
|
-
"""Give rounded value of temperature."""
|
|
29
|
-
return round(self._pct.temperature, 2)
|
|
30
|
-
|
|
31
|
-
async def send_state(self):
|
|
32
|
-
"""Fetch temperature periodically and send to MQTT."""
|
|
33
|
-
while True:
|
|
34
|
-
self._send_message(
|
|
35
|
-
topic=self._send_topic,
|
|
36
|
-
payload={STATE: self.state},
|
|
37
|
-
)
|
|
38
|
-
await asyncio.sleep(60)
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
class LM75Sensor(TempSensor):
|
|
42
|
-
"""Represent LM75 sensor in BoneIO."""
|
|
43
|
-
|
|
44
|
-
SensorClass = PCT2075
|
|
45
|
-
DefaultName = LM75
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
class MCP9808Sensor(TempSensor):
|
|
49
|
-
"""Represent MCP9808 sensor in BoneIO."""
|
|
50
|
-
|
|
51
|
-
SensorClass = MCP9808
|
|
52
|
-
DefaultName = MCP_TEMP_9808
|
|
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
|