boneIO 0.1.0.dev14__tar.gz → 0.1.0.dev16__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.1.0.dev14 → boneio-0.1.0.dev16}/PKG-INFO +2 -2
- {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/bonecli.py +4 -2
- {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/const.py +57 -30
- {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/helper/__init__.py +23 -2
- boneio-0.1.0.dev16/boneio/helper/gpio.py +79 -0
- {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/helper/ha_discovery.py +43 -4
- boneio-0.1.0.dev16/boneio/helper/mqtt.py +30 -0
- {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/helper/stats.py +6 -6
- boneio-0.1.0.dev16/boneio/input/__init__.py +5 -0
- {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/input/gpio.py +9 -36
- {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/manager.py +92 -21
- {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/oled.py +15 -5
- {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/relay/basic.py +5 -13
- {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/relay/gpio.py +2 -1
- {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/schema.yaml +69 -1
- boneio-0.1.0.dev16/boneio/sensor/__init__.py +6 -0
- boneio-0.1.0.dev16/boneio/sensor/adc.py +38 -0
- boneio-0.1.0.dev16/boneio/sensor/gpio.py +32 -0
- {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/sensor/lm75.py +4 -20
- boneio-0.1.0.dev16/boneio/version.py +2 -0
- {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio.egg-info/PKG-INFO +2 -2
- {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio.egg-info/SOURCES.txt +3 -0
- boneio-0.1.0.dev14/boneio/helper/gpio.py +0 -38
- boneio-0.1.0.dev14/boneio/input/__init__.py +0 -5
- boneio-0.1.0.dev14/boneio/sensor/__init__.py +0 -4
- boneio-0.1.0.dev14/boneio/version.py +0 -2
- {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/MANIFEST.in +0 -0
- {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/README.md +0 -0
- {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/__init__.py +0 -0
- {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/fonts/danube__.ttf +0 -0
- {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/helper/exceptions.py +0 -0
- {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/helper/oled.py +0 -0
- {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/helper/yaml.py +0 -0
- {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/mqtt_client.py +0 -0
- {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/relay/__init__.py +0 -0
- {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/relay/mcp.py +0 -0
- {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio.egg-info/dependency_links.txt +0 -0
- {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio.egg-info/entry_points.txt +0 -0
- {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio.egg-info/requires.txt +0 -0
- {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio.egg-info/top_level.txt +0 -0
- {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/requirements.txt +0 -0
- {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/setup.cfg +0 -0
- {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/setup.py +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: boneio
|
|
3
|
-
Version: 0.1.0.
|
|
3
|
+
Version: 0.1.0.dev16
|
|
4
4
|
Summary: Python Helper for BoneIO
|
|
5
5
|
Home-page: https://github.com/maciejk1984/boneIO
|
|
6
6
|
License: GNU General Public License v3.0
|
|
7
|
-
Download-URL: https://github.com/maciejk1984/boneIO/archive/0.1.0.
|
|
7
|
+
Download-URL: https://github.com/maciejk1984/boneIO/archive/0.1.0.dev16.zip
|
|
8
8
|
Platform: UNKNOWN
|
|
9
9
|
Classifier: Programming Language :: Python
|
|
10
10
|
Classifier: Programming Language :: Python :: 3.7
|
|
@@ -8,7 +8,7 @@ from colorlog import ColoredFormatter
|
|
|
8
8
|
|
|
9
9
|
from boneio.const import (
|
|
10
10
|
ENABLED,
|
|
11
|
-
|
|
11
|
+
INPUT,
|
|
12
12
|
HA_DISCOVERY,
|
|
13
13
|
HOST,
|
|
14
14
|
MCP23017,
|
|
@@ -20,6 +20,7 @@ from boneio.const import (
|
|
|
20
20
|
TOPIC_PREFIX,
|
|
21
21
|
USERNAME,
|
|
22
22
|
LM75,
|
|
23
|
+
ADC,
|
|
23
24
|
)
|
|
24
25
|
from boneio.helper import CustomValidator, load_yaml_file
|
|
25
26
|
from boneio.manager import Manager
|
|
@@ -135,12 +136,13 @@ async def run(ctx, debug: int, config: str, mqttpassword: str = ""):
|
|
|
135
136
|
send_message=client.send_message,
|
|
136
137
|
topic_prefix=_config[MQTT][TOPIC_PREFIX],
|
|
137
138
|
relay_pins=_config.get(OUTPUT, []),
|
|
138
|
-
input_pins=_config.get(
|
|
139
|
+
input_pins=_config.get(INPUT, []),
|
|
139
140
|
ha_discovery=_config[MQTT][HA_DISCOVERY][ENABLED],
|
|
140
141
|
ha_discovery_prefix=_config[MQTT][HA_DISCOVERY][TOPIC_PREFIX],
|
|
141
142
|
mcp23017=_config.get(MCP23017, []),
|
|
142
143
|
lm75=_config.get(LM75),
|
|
143
144
|
oled=_config.get(OLED),
|
|
145
|
+
adc_list=_config.get(ADC, []),
|
|
144
146
|
)
|
|
145
147
|
tasks = set()
|
|
146
148
|
tasks.update(manager.get_tasks())
|
|
@@ -1,31 +1,15 @@
|
|
|
1
1
|
# from typing import Literal
|
|
2
2
|
from datetime import timedelta
|
|
3
|
-
|
|
3
|
+
from Adafruit_BBIO.GPIO import HIGH, LOW, BOTH, FALLING
|
|
4
4
|
from typing_extensions import Literal
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
DELAY_DURATION = 0.1
|
|
9
|
-
SECOND_DELAY_DURATION = 0.3
|
|
6
|
+
|
|
7
|
+
# MISCELLANEOUS CONSTS
|
|
10
8
|
RELAY = "relay"
|
|
11
|
-
SINGLE = "single"
|
|
12
|
-
DOUBLE = "double"
|
|
13
|
-
LONG = "long"
|
|
14
|
-
ONLINE = "online"
|
|
15
9
|
ON = "ON"
|
|
16
10
|
OFF = "OFF"
|
|
17
11
|
STATE = "state"
|
|
18
|
-
PAHO = "paho.mqtt.client"
|
|
19
|
-
ClickTypes = Literal[SINGLE, DOUBLE, LONG]
|
|
20
|
-
MQTT = "mqtt"
|
|
21
|
-
HOST = "host"
|
|
22
|
-
USERNAME = "username"
|
|
23
|
-
PASSWORD = "password"
|
|
24
|
-
TOPIC_PREFIX = "topic_prefix"
|
|
25
|
-
HOMEASSISTANT = "homeassistant"
|
|
26
|
-
HA_DISCOVERY = "ha_discovery"
|
|
27
12
|
ENABLED = "enabled"
|
|
28
|
-
GPIO_INPUT = "gpio_input"
|
|
29
13
|
OUTPUT = "output"
|
|
30
14
|
PIN = "pin"
|
|
31
15
|
ID = "id"
|
|
@@ -34,17 +18,29 @@ GPIO = "gpio"
|
|
|
34
18
|
ACTIONS = "actions"
|
|
35
19
|
ACTION = "action"
|
|
36
20
|
OUTPUT = "output"
|
|
37
|
-
ADDRESS = "address"
|
|
38
|
-
MCP23017 = "mcp23017"
|
|
39
21
|
SWITCH = "switch"
|
|
40
22
|
CONFIG_PIN = "/usr/bin/config-pin"
|
|
41
|
-
|
|
42
|
-
|
|
23
|
+
UPDATE_INTERVAL = "update_interval"
|
|
24
|
+
ADC = "adc"
|
|
25
|
+
|
|
26
|
+
# TIMINGS FOR BUTTONS
|
|
27
|
+
DEBOUNCE_DURATION = timedelta(seconds=0.2)
|
|
28
|
+
LONG_PRESS_DURATION = timedelta(seconds=0.7)
|
|
29
|
+
DELAY_DURATION = 0.1
|
|
30
|
+
SECOND_DELAY_DURATION = 0.3
|
|
31
|
+
|
|
32
|
+
# HA CONSTS
|
|
33
|
+
HOMEASSISTANT = "homeassistant"
|
|
34
|
+
HA_DISCOVERY = "ha_discovery"
|
|
43
35
|
HA_TYPE = "ha_type"
|
|
36
|
+
SHOW_HA = "show_in_ha"
|
|
37
|
+
|
|
38
|
+
# OLED CONST
|
|
39
|
+
OLED = "oled"
|
|
40
|
+
FONTS = "fonts"
|
|
41
|
+
OLED_PIN = "P9_41"
|
|
44
42
|
GIGABYTE = 1073741824
|
|
45
43
|
MEGABYTE = 1048576
|
|
46
|
-
OLED_PIN = "P9_41"
|
|
47
|
-
NUM_OF_SCREENS = 6
|
|
48
44
|
WIDTH = 128
|
|
49
45
|
UPTIME = "uptime"
|
|
50
46
|
NETWORK = "network"
|
|
@@ -53,11 +49,42 @@ DISK = "disk"
|
|
|
53
49
|
MEMORY = "memory"
|
|
54
50
|
SWAP = "swap"
|
|
55
51
|
WHITE = "white"
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
OledDataTypes = Literal[UPTIME, NETWORK, CPU, DISK, MEMORY, SWAP, OUTPUT]
|
|
59
|
-
INIT_SLEEP = "init_sleep"
|
|
52
|
+
|
|
53
|
+
# INPUT CONST
|
|
60
54
|
INPUT = "input"
|
|
55
|
+
SINGLE = "single"
|
|
56
|
+
DOUBLE = "double"
|
|
57
|
+
LONG = "long"
|
|
58
|
+
PRESSED = "pressed"
|
|
59
|
+
RELEASED = "released"
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
# MQTT CONST
|
|
63
|
+
PAHO = "paho.mqtt.client"
|
|
64
|
+
MQTT = "mqtt"
|
|
65
|
+
HOST = "host"
|
|
66
|
+
USERNAME = "username"
|
|
67
|
+
PASSWORD = "password"
|
|
68
|
+
ONLINE = "online"
|
|
69
|
+
TOPIC_PREFIX = "topic_prefix"
|
|
70
|
+
|
|
71
|
+
# I2C and MCP CONST
|
|
72
|
+
ADDRESS = "address"
|
|
73
|
+
MCP23017 = "mcp23017"
|
|
74
|
+
MCP = "mcp"
|
|
75
|
+
MCP_ID = "mcp_id"
|
|
76
|
+
INIT_SLEEP = "init_sleep"
|
|
77
|
+
|
|
78
|
+
# SENSOR CONST
|
|
61
79
|
TEMPERATURE = "temperature"
|
|
62
80
|
SENSOR = "sensor"
|
|
63
|
-
|
|
81
|
+
BINARY_SENSOR = "binary_sensor"
|
|
82
|
+
LM75 = "lm75"
|
|
83
|
+
INPUT_SENSOR = "inputsensor"
|
|
84
|
+
|
|
85
|
+
# TYPING
|
|
86
|
+
ClickTypes = Literal[SINGLE, DOUBLE, LONG, PRESSED, RELEASED]
|
|
87
|
+
OledDataTypes = Literal[UPTIME, NETWORK, CPU, DISK, MEMORY, SWAP, OUTPUT]
|
|
88
|
+
Gpio_States = Literal[HIGH, LOW]
|
|
89
|
+
Gpio_Edges = Literal[BOTH, FALLING]
|
|
90
|
+
InputTypes = Literal[INPUT, INPUT_SENSOR]
|
|
@@ -1,27 +1,48 @@
|
|
|
1
1
|
"""Helper dir for BoneIO."""
|
|
2
|
-
from boneio.helper.gpio import
|
|
2
|
+
from boneio.helper.gpio import (
|
|
3
|
+
edge_detect,
|
|
4
|
+
setup_input,
|
|
5
|
+
setup_output,
|
|
6
|
+
read_input,
|
|
7
|
+
write_output,
|
|
8
|
+
GpioBaseClass,
|
|
9
|
+
configure_pin,
|
|
10
|
+
)
|
|
3
11
|
from boneio.helper.oled import make_font
|
|
12
|
+
from boneio.helper.mqtt import BasicMqtt
|
|
4
13
|
from boneio.helper.stats import HostData, host_stats
|
|
5
14
|
from boneio.helper.yaml import CustomValidator, load_yaml_file
|
|
6
15
|
from boneio.helper.ha_discovery import (
|
|
7
16
|
ha_relay_availibilty_message,
|
|
8
|
-
ha_sensor_availibilty_message,
|
|
9
17
|
ha_sensor_temp_availibilty_message,
|
|
18
|
+
ha_binary_sensor_availibilty_message,
|
|
19
|
+
ha_input_availibilty_message,
|
|
20
|
+
ha_sensor_availibilty_message,
|
|
21
|
+
ha_adc_sensor_availibilty_message,
|
|
10
22
|
)
|
|
11
23
|
from boneio.helper.exceptions import GPIOInputException, I2CError
|
|
12
24
|
|
|
25
|
+
|
|
13
26
|
__all__ = [
|
|
14
27
|
"CustomValidator",
|
|
15
28
|
"load_yaml_file",
|
|
16
29
|
"HostData",
|
|
17
30
|
"host_stats",
|
|
18
31
|
"setup_input",
|
|
32
|
+
"setup_output",
|
|
19
33
|
"edge_detect",
|
|
20
34
|
"read_input",
|
|
35
|
+
"write_output",
|
|
21
36
|
"make_font",
|
|
22
37
|
"ha_relay_availibilty_message",
|
|
23
38
|
"ha_sensor_availibilty_message",
|
|
39
|
+
"ha_adc_sensor_availibilty_message",
|
|
24
40
|
"ha_sensor_temp_availibilty_message",
|
|
41
|
+
"ha_binary_sensor_availibilty_message",
|
|
42
|
+
"ha_input_availibilty_message",
|
|
25
43
|
"GPIOInputException",
|
|
26
44
|
"I2CError",
|
|
45
|
+
"GpioBaseClass",
|
|
46
|
+
"configure_pin",
|
|
47
|
+
"BasicMqtt",
|
|
27
48
|
]
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import logging
|
|
3
|
+
from Adafruit_BBIO import GPIO
|
|
4
|
+
|
|
5
|
+
from boneio.helper.exceptions import GPIOInputException
|
|
6
|
+
from boneio.const import LOW, FALLING, Gpio_Edges, Gpio_States
|
|
7
|
+
from typing import Callable
|
|
8
|
+
import subprocess
|
|
9
|
+
|
|
10
|
+
from boneio.const import (
|
|
11
|
+
CONFIG_PIN,
|
|
12
|
+
GPIO as GPIO_STR,
|
|
13
|
+
ClickTypes,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
_LOGGER = logging.getLogger(__name__)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def configure_pin(pin: str) -> None:
|
|
20
|
+
pin = f"{pin[0:3]}0{pin[3]}" if len(pin) == 4 else pin
|
|
21
|
+
_LOGGER.debug(f"Configuring pin for GPIO {pin}")
|
|
22
|
+
subprocess.run(
|
|
23
|
+
[CONFIG_PIN, pin, GPIO_STR],
|
|
24
|
+
stdout=subprocess.DEVNULL,
|
|
25
|
+
stderr=subprocess.STDOUT,
|
|
26
|
+
timeout=1,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def setup_output(pin: str):
|
|
31
|
+
"""Set up a GPIO as output."""
|
|
32
|
+
|
|
33
|
+
GPIO.setup(pin, GPIO.OUT, pull_up_down=GPIO.PUD_DOWN)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def setup_input(pin: str, pull_mode: str = "UP"):
|
|
37
|
+
"""Set up a GPIO as input."""
|
|
38
|
+
try:
|
|
39
|
+
GPIO.setup(pin, GPIO.IN, GPIO.PUD_DOWN if pull_mode == "DOWN" else GPIO.PUD_UP)
|
|
40
|
+
except (ValueError, SystemError) as err:
|
|
41
|
+
raise GPIOInputException(err)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def write_output(pin: str, value: str):
|
|
45
|
+
"""Write a value to a GPIO."""
|
|
46
|
+
|
|
47
|
+
GPIO.output(pin, value)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def read_input(pin: str, on_state: Gpio_States = LOW):
|
|
51
|
+
"""Read a value from a GPIO."""
|
|
52
|
+
return GPIO.input(pin) is on_state
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def edge_detect(pin: str, callback: Callable, bounce: int, edge: Gpio_Edges = FALLING):
|
|
56
|
+
"""Add detection for RISING and FALLING events."""
|
|
57
|
+
try:
|
|
58
|
+
GPIO.add_event_detect(gpio=pin, edge=edge, callback=callback, bouncetime=bounce)
|
|
59
|
+
except RuntimeError as err:
|
|
60
|
+
raise GPIOInputException(err)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class GpioBaseClass:
|
|
64
|
+
"""Base class for initialize GPIO"""
|
|
65
|
+
|
|
66
|
+
def __init__(
|
|
67
|
+
self, pin: str, press_callback: Callable[[ClickTypes, str], None], **kwargs
|
|
68
|
+
) -> None:
|
|
69
|
+
"""Setup GPIO Input Button"""
|
|
70
|
+
self._pin = pin
|
|
71
|
+
configure_pin(pin)
|
|
72
|
+
self._loop = asyncio.get_running_loop()
|
|
73
|
+
self._press_callback = press_callback
|
|
74
|
+
setup_input(self._pin)
|
|
75
|
+
|
|
76
|
+
@property
|
|
77
|
+
def is_pressed(self):
|
|
78
|
+
"""Is button pressed."""
|
|
79
|
+
return read_input(self._pin)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from boneio.version import __version__
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
from boneio.const import INPUT, OFF, ON, RELAY, STATE, SENSOR
|
|
4
|
+
from boneio.const import INPUT, OFF, ON, RELAY, STATE, SENSOR, INPUT_SENSOR
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
def ha_relay_availibilty_message(id: str, name: str, topic: str = "boneio"):
|
|
@@ -25,7 +25,9 @@ def ha_relay_availibilty_message(id: str, name: str, topic: str = "boneio"):
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
|
|
28
|
-
def
|
|
28
|
+
def ha_availibilty_message(
|
|
29
|
+
id: str, name: str, topic: str = "boneio", sensor_type: str = INPUT
|
|
30
|
+
):
|
|
29
31
|
"""Create availability topic for HA."""
|
|
30
32
|
return {
|
|
31
33
|
"availability": [{"topic": f"{topic}/{STATE}"}],
|
|
@@ -38,8 +40,45 @@ def ha_sensor_availibilty_message(id: str, name: str, topic: str = "boneio"):
|
|
|
38
40
|
},
|
|
39
41
|
"icon": "mdi:gesture-double-tap",
|
|
40
42
|
"name": name,
|
|
41
|
-
"state_topic": f"{topic}/{
|
|
42
|
-
"unique_id": f"{topic}{
|
|
43
|
+
"state_topic": f"{topic}/{sensor_type}/{id}",
|
|
44
|
+
"unique_id": f"{topic}{sensor_type}{id}",
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def ha_input_availibilty_message(**kwargs):
|
|
49
|
+
return ha_availibilty_message(sensor_type=INPUT, **kwargs)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def ha_adc_sensor_availibilty_message(**kwargs):
|
|
53
|
+
msg = ha_availibilty_message(sensor_type=SENSOR, **kwargs)
|
|
54
|
+
msg["unit_of_measurement"] = "V"
|
|
55
|
+
msg["device_class"] = "voltage"
|
|
56
|
+
msg["state_class"] = "measurement"
|
|
57
|
+
return msg
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def ha_sensor_availibilty_message(unit_of_measurement: str = None, **kwargs):
|
|
61
|
+
msg = ha_availibilty_message(sensor_type=SENSOR, **kwargs)
|
|
62
|
+
if not unit_of_measurement:
|
|
63
|
+
return msg
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def ha_binary_sensor_availibilty_message(id: str, name: str, topic: str = "boneio"):
|
|
67
|
+
"""Create availability topic for HA."""
|
|
68
|
+
return {
|
|
69
|
+
"availability": [{"topic": f"{topic}/{STATE}"}],
|
|
70
|
+
"device": {
|
|
71
|
+
"identifiers": [topic],
|
|
72
|
+
"manufacturer": "BoneIO",
|
|
73
|
+
"model": "BoneIO Relay Board",
|
|
74
|
+
"name": f"BoneIO {topic}",
|
|
75
|
+
"sw_version": __version__,
|
|
76
|
+
},
|
|
77
|
+
"payload_on": "pressed",
|
|
78
|
+
"payload_off": "released",
|
|
79
|
+
"name": name,
|
|
80
|
+
"state_topic": f"{topic}/{INPUT_SENSOR}/{id}",
|
|
81
|
+
"unique_id": f"{topic}{INPUT_SENSOR}{id}",
|
|
43
82
|
}
|
|
44
83
|
|
|
45
84
|
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""Class to help initialize classes which uses mqtt send."""
|
|
2
|
+
from typing import Callable, Union
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class BasicMqtt:
|
|
6
|
+
"""Basic MQTT class."""
|
|
7
|
+
|
|
8
|
+
def __init__(
|
|
9
|
+
self,
|
|
10
|
+
id: str,
|
|
11
|
+
topic_prefix: str,
|
|
12
|
+
name: str,
|
|
13
|
+
send_message: Callable[[str, Union[str, dict]], None],
|
|
14
|
+
topic_type: str,
|
|
15
|
+
):
|
|
16
|
+
"""Initialize module."""
|
|
17
|
+
self._id = id.replace(" ", "")
|
|
18
|
+
self._name = name
|
|
19
|
+
self._send_message = send_message
|
|
20
|
+
self._send_topic = f"{topic_prefix}/{topic_type}/{self.id}"
|
|
21
|
+
|
|
22
|
+
@property
|
|
23
|
+
def id(self) -> bool:
|
|
24
|
+
"""Id of the module."""
|
|
25
|
+
return self._id
|
|
26
|
+
|
|
27
|
+
@property
|
|
28
|
+
def name(self):
|
|
29
|
+
"""Return name of the sensor."""
|
|
30
|
+
return self._name
|
|
@@ -85,9 +85,9 @@ async def get_memory_info(host_data):
|
|
|
85
85
|
host_data.write(
|
|
86
86
|
MEMORY,
|
|
87
87
|
{
|
|
88
|
-
"total": f"{floor(vm.total / MEGABYTE)}
|
|
89
|
-
"used": f"{floor(vm.used / MEGABYTE)}
|
|
90
|
-
"free": f"{floor(vm.available / MEGABYTE)}
|
|
88
|
+
"total": f"{floor(vm.total / MEGABYTE)}MB",
|
|
89
|
+
"used": f"{floor(vm.used / MEGABYTE)}MB",
|
|
90
|
+
"free": f"{floor(vm.available / MEGABYTE)}MB",
|
|
91
91
|
},
|
|
92
92
|
)
|
|
93
93
|
await asyncio.sleep(10)
|
|
@@ -100,9 +100,9 @@ async def get_swap_info(host_data):
|
|
|
100
100
|
host_data.write(
|
|
101
101
|
SWAP,
|
|
102
102
|
{
|
|
103
|
-
"total": f"{floor(swap.total / MEGABYTE)}
|
|
104
|
-
"used": f"{floor(swap.used / MEGABYTE)}
|
|
105
|
-
"free": f"{floor(swap.free / MEGABYTE)}
|
|
103
|
+
"total": f"{floor(swap.total / MEGABYTE)}MB",
|
|
104
|
+
"used": f"{floor(swap.used / MEGABYTE)}MB",
|
|
105
|
+
"free": f"{floor(swap.free / MEGABYTE)}MB",
|
|
106
106
|
},
|
|
107
107
|
)
|
|
108
108
|
await asyncio.sleep(10)
|
|
@@ -1,51 +1,28 @@
|
|
|
1
1
|
"""GPIOInputButton to receive signals."""
|
|
2
|
-
import asyncio
|
|
3
2
|
import logging
|
|
4
|
-
import subprocess
|
|
5
3
|
from datetime import datetime
|
|
6
4
|
from functools import partial
|
|
7
|
-
from typing import Callable
|
|
8
5
|
|
|
9
6
|
from boneio.const import (
|
|
10
|
-
CONFIG_PIN,
|
|
11
7
|
DEBOUNCE_DURATION,
|
|
12
8
|
DELAY_DURATION,
|
|
13
9
|
DOUBLE,
|
|
14
|
-
GPIO,
|
|
15
10
|
LONG,
|
|
16
11
|
LONG_PRESS_DURATION,
|
|
17
12
|
SECOND_DELAY_DURATION,
|
|
18
13
|
SINGLE,
|
|
19
|
-
ClickTypes,
|
|
20
14
|
)
|
|
21
|
-
from boneio.helper import edge_detect,
|
|
15
|
+
from boneio.helper import edge_detect, GpioBaseClass
|
|
22
16
|
|
|
23
17
|
_LOGGER = logging.getLogger(__name__)
|
|
24
18
|
|
|
25
19
|
|
|
26
|
-
|
|
27
|
-
pin = f"{pin[0:3]}0{pin[3]}" if len(pin) == 4 else pin
|
|
28
|
-
_LOGGER.debug(f"Configuring pin for GPIO {pin}")
|
|
29
|
-
subprocess.run(
|
|
30
|
-
[CONFIG_PIN, pin, GPIO],
|
|
31
|
-
stdout=subprocess.DEVNULL,
|
|
32
|
-
stderr=subprocess.STDOUT,
|
|
33
|
-
timeout=1,
|
|
34
|
-
)
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
class GpioInputButton:
|
|
20
|
+
class GpioInputButton(GpioBaseClass):
|
|
38
21
|
"""Represent Gpio input switch."""
|
|
39
22
|
|
|
40
|
-
def __init__(
|
|
41
|
-
self, pin: str, press_callback: Callable[[ClickTypes, str], None], **kwargs
|
|
42
|
-
) -> None:
|
|
23
|
+
def __init__(self, **kwargs) -> None:
|
|
43
24
|
"""Setup GPIO Input Button"""
|
|
44
|
-
|
|
45
|
-
configure_pin(pin)
|
|
46
|
-
self._loop = asyncio.get_running_loop()
|
|
47
|
-
self._press_callback = press_callback
|
|
48
|
-
setup_input(self._pin)
|
|
25
|
+
super().__init__(**kwargs)
|
|
49
26
|
edge_detect(self._pin, callback=self._handle_press, bounce=25)
|
|
50
27
|
self._first_press_timestamp = None
|
|
51
28
|
self._is_long_press = False
|
|
@@ -53,7 +30,7 @@ class GpioInputButton:
|
|
|
53
30
|
self._second_check = False
|
|
54
31
|
_LOGGER.debug("Configured listening for input pin %s", self._pin)
|
|
55
32
|
|
|
56
|
-
def _handle_press(self, pin) -> None:
|
|
33
|
+
def _handle_press(self, pin: str) -> None:
|
|
57
34
|
"""Handle the button press callback"""
|
|
58
35
|
# Ignore if we are in a long press
|
|
59
36
|
if self._is_long_press:
|
|
@@ -85,11 +62,6 @@ class GpioInputButton:
|
|
|
85
62
|
self.check_press_length,
|
|
86
63
|
)
|
|
87
64
|
|
|
88
|
-
@property
|
|
89
|
-
def is_pressed(self):
|
|
90
|
-
"""Is button pressed."""
|
|
91
|
-
return read_input(self._pin)
|
|
92
|
-
|
|
93
65
|
def check_press_length(self) -> None:
|
|
94
66
|
"""Check if it's a single, double or long press"""
|
|
95
67
|
# Check if button is still pressed
|
|
@@ -109,7 +81,7 @@ class GpioInputButton:
|
|
|
109
81
|
diff = datetime.now() - self._first_press_timestamp
|
|
110
82
|
if not self._is_long_press and diff > LONG_PRESS_DURATION:
|
|
111
83
|
self._is_long_press = True
|
|
112
|
-
_LOGGER.debug("Long button press, call callback")
|
|
84
|
+
_LOGGER.debug("Long button press on pin %s, call callback", self._pin)
|
|
113
85
|
self._loop.call_soon_threadsafe(
|
|
114
86
|
partial(self._press_callback, LONG, self._pin)
|
|
115
87
|
)
|
|
@@ -129,7 +101,8 @@ class GpioInputButton:
|
|
|
129
101
|
if self._second_check:
|
|
130
102
|
if self._second_press_timestamp:
|
|
131
103
|
_LOGGER.debug(
|
|
132
|
-
"Double click event, roznica %s",
|
|
104
|
+
"Double click event on pin %s, roznica %s",
|
|
105
|
+
self._pin,
|
|
133
106
|
self._second_press_timestamp - self._first_press_timestamp,
|
|
134
107
|
)
|
|
135
108
|
self._loop.call_soon_threadsafe(
|
|
@@ -137,7 +110,7 @@ class GpioInputButton:
|
|
|
137
110
|
)
|
|
138
111
|
|
|
139
112
|
elif self._first_press_timestamp:
|
|
140
|
-
_LOGGER.debug("One click event, call callback")
|
|
113
|
+
_LOGGER.debug("One click event on pin %s, call callback", self._pin)
|
|
141
114
|
self._loop.call_soon_threadsafe(
|
|
142
115
|
partial(self._press_callback, SINGLE, self._pin)
|
|
143
116
|
)
|
|
@@ -28,19 +28,28 @@ from boneio.const import (
|
|
|
28
28
|
RELAY,
|
|
29
29
|
STATE,
|
|
30
30
|
ClickTypes,
|
|
31
|
+
InputTypes,
|
|
32
|
+
SENSOR,
|
|
33
|
+
SHOW_HA,
|
|
34
|
+
BINARY_SENSOR,
|
|
35
|
+
INPUT_SENSOR,
|
|
36
|
+
UPDATE_INTERVAL,
|
|
31
37
|
)
|
|
32
38
|
from boneio.helper import (
|
|
33
39
|
HostData,
|
|
34
40
|
ha_relay_availibilty_message,
|
|
35
|
-
|
|
41
|
+
ha_input_availibilty_message,
|
|
42
|
+
ha_adc_sensor_availibilty_message,
|
|
36
43
|
ha_sensor_temp_availibilty_message,
|
|
44
|
+
ha_binary_sensor_availibilty_message,
|
|
37
45
|
host_stats,
|
|
38
46
|
GPIOInputException,
|
|
39
47
|
I2CError,
|
|
40
48
|
)
|
|
41
49
|
from boneio.input import GpioInputButton
|
|
42
|
-
|
|
50
|
+
|
|
43
51
|
from boneio.relay import GpioRelay, MCPRelay
|
|
52
|
+
from boneio.sensor import GpioInputSensor
|
|
44
53
|
|
|
45
54
|
_LOGGER = logging.getLogger(__name__)
|
|
46
55
|
|
|
@@ -59,6 +68,7 @@ class Manager:
|
|
|
59
68
|
ha_discovery_prefix: str = HOMEASSISTANT,
|
|
60
69
|
mcp23017: Optional[List] = None,
|
|
61
70
|
oled: bool = False,
|
|
71
|
+
adc_list: Optional[List] = None,
|
|
62
72
|
) -> None:
|
|
63
73
|
"""Initialize the manager."""
|
|
64
74
|
_LOGGER.info("Initializing manager module.")
|
|
@@ -119,12 +129,48 @@ class Manager:
|
|
|
119
129
|
_LOGGER.error("Can't connect to MCP %s. %s", id, err)
|
|
120
130
|
pass
|
|
121
131
|
|
|
132
|
+
def create_adc():
|
|
133
|
+
from boneio.sensor import initialize_adc, GpioADCSensor
|
|
134
|
+
|
|
135
|
+
initialize_adc()
|
|
136
|
+
|
|
137
|
+
## TODO: find what exception can ADC gpio throw.
|
|
138
|
+
for gpio in adc_list:
|
|
139
|
+
name = gpio.get(ID)
|
|
140
|
+
id = name.replace(" ", "")
|
|
141
|
+
pin = gpio[PIN]
|
|
142
|
+
try:
|
|
143
|
+
adc = GpioADCSensor(
|
|
144
|
+
id=id,
|
|
145
|
+
pin=pin,
|
|
146
|
+
name=name,
|
|
147
|
+
send_message=self.send_message,
|
|
148
|
+
topic_prefix=topic_prefix,
|
|
149
|
+
update_interval=gpio.get(UPDATE_INTERVAL, 60),
|
|
150
|
+
)
|
|
151
|
+
self.send_ha_autodiscovery(
|
|
152
|
+
id=id,
|
|
153
|
+
name=name,
|
|
154
|
+
ha_type=SENSOR,
|
|
155
|
+
prefix=ha_discovery_prefix,
|
|
156
|
+
availibilty_msg_func=ha_adc_sensor_availibilty_message,
|
|
157
|
+
)
|
|
158
|
+
self._tasks.append(asyncio.create_task(adc.send_state()))
|
|
159
|
+
except I2CError as err:
|
|
160
|
+
_LOGGER.error("Can't configure ADC sensor %s. %s", id, err)
|
|
161
|
+
pass
|
|
162
|
+
|
|
163
|
+
return True
|
|
164
|
+
|
|
122
165
|
if lm75:
|
|
123
166
|
create_lm75_sensor()
|
|
124
167
|
|
|
125
168
|
if mcp23017:
|
|
126
169
|
create_mcp23017()
|
|
127
170
|
|
|
171
|
+
if adc_list:
|
|
172
|
+
create_adc()
|
|
173
|
+
|
|
128
174
|
def configure_relay(gpio: dict) -> Any:
|
|
129
175
|
"""Configure kind of relay. Most common MCP."""
|
|
130
176
|
relay_id = gpio[ID].replace(" ", "")
|
|
@@ -177,31 +223,54 @@ class Manager:
|
|
|
177
223
|
out.send_state,
|
|
178
224
|
)
|
|
179
225
|
|
|
180
|
-
def
|
|
226
|
+
def configure_input(gpio):
|
|
181
227
|
try:
|
|
182
228
|
pin = gpio[PIN]
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
availibilty_msg_func=
|
|
196
|
-
|
|
229
|
+
input_type = gpio.get(KIND)
|
|
230
|
+
if input_type == SENSOR:
|
|
231
|
+
GpioInputSensor(
|
|
232
|
+
pin=pin,
|
|
233
|
+
press_callback=lambda x, i: self.press_callback(
|
|
234
|
+
x=x,
|
|
235
|
+
inpin=i,
|
|
236
|
+
actions=gpio.get(ACTIONS, {}),
|
|
237
|
+
input_type=INPUT_SENSOR,
|
|
238
|
+
),
|
|
239
|
+
rest_pin=gpio,
|
|
240
|
+
)
|
|
241
|
+
availibilty_msg_func = ha_binary_sensor_availibilty_message
|
|
242
|
+
ha_type = BINARY_SENSOR
|
|
243
|
+
else:
|
|
244
|
+
GpioInputButton(
|
|
245
|
+
pin=pin,
|
|
246
|
+
press_callback=lambda x, i: self.press_callback(
|
|
247
|
+
x=x,
|
|
248
|
+
inpin=i,
|
|
249
|
+
actions=gpio.get(ACTIONS, {}),
|
|
250
|
+
input_type=INPUT,
|
|
251
|
+
),
|
|
252
|
+
rest_pin=gpio,
|
|
253
|
+
)
|
|
254
|
+
availibilty_msg_func = ha_input_availibilty_message
|
|
255
|
+
ha_type = SENSOR
|
|
256
|
+
if gpio.get(SHOW_HA, True):
|
|
257
|
+
self.send_ha_autodiscovery(
|
|
258
|
+
id=pin,
|
|
259
|
+
name=gpio.get(ID, pin),
|
|
260
|
+
ha_type=ha_type,
|
|
261
|
+
prefix=ha_discovery_prefix,
|
|
262
|
+
availibilty_msg_func=availibilty_msg_func,
|
|
263
|
+
)
|
|
197
264
|
except GPIOInputException as err:
|
|
198
265
|
_LOGGER.error("This PIN %s can't be configured. %s", pin, err)
|
|
199
266
|
pass
|
|
200
267
|
|
|
201
268
|
for gpio in self._input_pins:
|
|
202
|
-
|
|
269
|
+
configure_input(gpio=gpio)
|
|
203
270
|
|
|
204
271
|
if oled:
|
|
272
|
+
from boneio.oled import Oled
|
|
273
|
+
|
|
205
274
|
self._host_data = HostData(
|
|
206
275
|
output=self._grouped_outputs,
|
|
207
276
|
lm75=self._lm75,
|
|
@@ -214,7 +283,7 @@ class Manager:
|
|
|
214
283
|
self._oled = Oled(
|
|
215
284
|
host_data=self._host_data, output_groups=list(self._grouped_outputs)
|
|
216
285
|
)
|
|
217
|
-
except GPIOInputException as err:
|
|
286
|
+
except (GPIOInputException, I2CError) as err:
|
|
218
287
|
_LOGGER.error("Can't configure OLED display. %s", err)
|
|
219
288
|
|
|
220
289
|
self.send_message(topic=f"{topic_prefix}/{STATE}", payload=ONLINE)
|
|
@@ -227,10 +296,12 @@ class Manager:
|
|
|
227
296
|
def get_tasks(self) -> Set[asyncio.Task]:
|
|
228
297
|
return self._tasks
|
|
229
298
|
|
|
230
|
-
def press_callback(
|
|
299
|
+
def press_callback(
|
|
300
|
+
self, x: ClickTypes, inpin: str, actions: dict, input_type: InputTypes = INPUT
|
|
301
|
+
) -> None:
|
|
231
302
|
"""Press callback to use in input gpio.
|
|
232
303
|
If relay input map is provided also toggle action on relay."""
|
|
233
|
-
topic = f"{self._topic_prefix}/{
|
|
304
|
+
topic = f"{self._topic_prefix}/{input_type}/{inpin}"
|
|
234
305
|
self.send_message(topic=topic, payload=x)
|
|
235
306
|
action = actions.get(x)
|
|
236
307
|
if action:
|
|
@@ -5,11 +5,18 @@ from typing import List
|
|
|
5
5
|
from luma.core.interface.serial import i2c
|
|
6
6
|
from luma.core.render import canvas
|
|
7
7
|
from luma.oled.device import sh1106
|
|
8
|
+
from luma.core.error import DeviceNotFoundError
|
|
8
9
|
from PIL import ImageDraw
|
|
9
10
|
|
|
10
11
|
from boneio.const import CPU, DISK, MEMORY, NETWORK, OLED_PIN, SWAP, UPTIME, WHITE
|
|
11
|
-
from boneio.helper import
|
|
12
|
-
|
|
12
|
+
from boneio.helper import (
|
|
13
|
+
HostData,
|
|
14
|
+
configure_pin,
|
|
15
|
+
edge_detect,
|
|
16
|
+
make_font,
|
|
17
|
+
setup_input,
|
|
18
|
+
I2CError,
|
|
19
|
+
)
|
|
13
20
|
|
|
14
21
|
_LOGGER = logging.getLogger(__name__)
|
|
15
22
|
|
|
@@ -38,9 +45,12 @@ class Oled:
|
|
|
38
45
|
self._host_data = host_data
|
|
39
46
|
configure_pin(OLED_PIN)
|
|
40
47
|
setup_input(OLED_PIN)
|
|
41
|
-
edge_detect(OLED_PIN, callback=self._handle_press, bounce=50)
|
|
42
|
-
|
|
43
|
-
|
|
48
|
+
edge_detect(pin=OLED_PIN, callback=self._handle_press, bounce=50)
|
|
49
|
+
try:
|
|
50
|
+
serial = i2c(port=2, address=0x3C)
|
|
51
|
+
self._device = sh1106(serial)
|
|
52
|
+
except DeviceNotFoundError as err:
|
|
53
|
+
raise I2CError(err)
|
|
44
54
|
_LOGGER.debug("Configuring OLED screen.")
|
|
45
55
|
|
|
46
56
|
def _draw_standard(self, data: dict, draw: ImageDraw) -> None:
|
|
@@ -2,31 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
4
|
import logging
|
|
5
|
-
from typing import Callable
|
|
5
|
+
from typing import Callable
|
|
6
6
|
|
|
7
7
|
from boneio.const import OFF, ON, RELAY, STATE, SWITCH
|
|
8
|
+
from boneio.helper import BasicMqtt
|
|
8
9
|
|
|
9
10
|
_LOGGER = logging.getLogger(__name__)
|
|
10
11
|
|
|
11
12
|
|
|
12
|
-
class BasicRelay:
|
|
13
|
+
class BasicRelay(BasicMqtt):
|
|
13
14
|
"""Basic relay class."""
|
|
14
15
|
|
|
15
16
|
def __init__(
|
|
16
|
-
self,
|
|
17
|
-
send_message: Callable[[str, Union[str, dict]], None],
|
|
18
|
-
callback: Callable,
|
|
19
|
-
topic_prefix: str,
|
|
20
|
-
id: str = None,
|
|
21
|
-
ha_type=SWITCH,
|
|
17
|
+
self, callback: Callable, id: str = None, ha_type=SWITCH, **kwargs
|
|
22
18
|
) -> None:
|
|
23
19
|
"""Initialize Basic relay."""
|
|
24
|
-
|
|
25
|
-
self._name = id
|
|
20
|
+
super().__init__(id=id, name=id, topic_type=RELAY, **kwargs)
|
|
26
21
|
self._ha_type = ha_type
|
|
27
|
-
self._send_message = send_message
|
|
28
|
-
self._relay_topic = f"{topic_prefix}/{RELAY}/"
|
|
29
|
-
self._send_topic = f"{self._relay_topic}{self.id}"
|
|
30
22
|
self._state = False
|
|
31
23
|
self._callback = callback
|
|
32
24
|
self._loop = asyncio.get_running_loop()
|
|
@@ -5,8 +5,9 @@ Created just in case.
|
|
|
5
5
|
|
|
6
6
|
import logging
|
|
7
7
|
|
|
8
|
-
from boneio.helper
|
|
8
|
+
from boneio.helper import read_input, setup_output, write_output
|
|
9
9
|
from boneio.relay.basic import BasicRelay
|
|
10
|
+
from boneio.const import HIGH, LOW
|
|
10
11
|
|
|
11
12
|
_LOGGER = logging.getLogger(__name__)
|
|
12
13
|
|
|
@@ -131,7 +131,7 @@ output:
|
|
|
131
131
|
label: If HA discovery is used device if relay is light or switch.
|
|
132
132
|
|
|
133
133
|
|
|
134
|
-
|
|
134
|
+
input:
|
|
135
135
|
type: list
|
|
136
136
|
meta:
|
|
137
137
|
label: GPIO inputs section
|
|
@@ -148,6 +148,19 @@ gpio_input:
|
|
|
148
148
|
required: True
|
|
149
149
|
meta:
|
|
150
150
|
label: PIN to use.
|
|
151
|
+
show_in_ha:
|
|
152
|
+
type: boolean
|
|
153
|
+
required: True
|
|
154
|
+
default: True
|
|
155
|
+
meta:
|
|
156
|
+
label: If you want you can disable discovering this input in HA.
|
|
157
|
+
kind:
|
|
158
|
+
type: string
|
|
159
|
+
allowed: ['switch', 'sensor']
|
|
160
|
+
default: switch
|
|
161
|
+
required: True
|
|
162
|
+
meta:
|
|
163
|
+
label: Either switch or sensor. If sensor then no clicks are detected, just simple on/off on gpio.
|
|
151
164
|
actions:
|
|
152
165
|
required: False
|
|
153
166
|
type: dict
|
|
@@ -188,3 +201,58 @@ gpio_input:
|
|
|
188
201
|
type: string
|
|
189
202
|
message:
|
|
190
203
|
type: string
|
|
204
|
+
pressed:
|
|
205
|
+
required: False
|
|
206
|
+
type: dict
|
|
207
|
+
schema:
|
|
208
|
+
action:
|
|
209
|
+
type: string
|
|
210
|
+
allowed: ['mqtt', 'output']
|
|
211
|
+
default: output
|
|
212
|
+
pin:
|
|
213
|
+
type: string
|
|
214
|
+
message:
|
|
215
|
+
type: string
|
|
216
|
+
released:
|
|
217
|
+
required: False
|
|
218
|
+
type: dict
|
|
219
|
+
schema:
|
|
220
|
+
action:
|
|
221
|
+
type: string
|
|
222
|
+
allowed: ['mqtt', 'output']
|
|
223
|
+
default: output
|
|
224
|
+
pin:
|
|
225
|
+
type: string
|
|
226
|
+
message:
|
|
227
|
+
type: string
|
|
228
|
+
|
|
229
|
+
adc:
|
|
230
|
+
type: list
|
|
231
|
+
meta:
|
|
232
|
+
label: GPIO ADC section
|
|
233
|
+
schema:
|
|
234
|
+
type: dict
|
|
235
|
+
schema:
|
|
236
|
+
id:
|
|
237
|
+
type: string
|
|
238
|
+
required: False
|
|
239
|
+
meta:
|
|
240
|
+
label: Id to use in HA if needed. Default to pin number.
|
|
241
|
+
pin:
|
|
242
|
+
type: string
|
|
243
|
+
required: True
|
|
244
|
+
allowed: ['P9_33', 'P9_35', 'P9_36', 'P9_37', 'P9_38', 'P9_39', 'P9_40']
|
|
245
|
+
meta:
|
|
246
|
+
label: PIN to use.
|
|
247
|
+
update_interval:
|
|
248
|
+
type: integer
|
|
249
|
+
required: True
|
|
250
|
+
default: 60
|
|
251
|
+
meta:
|
|
252
|
+
label: Update interval in seconds.
|
|
253
|
+
show_in_ha:
|
|
254
|
+
type: boolean
|
|
255
|
+
required: True
|
|
256
|
+
default: True
|
|
257
|
+
meta:
|
|
258
|
+
label: If you want you can disable discovering this input in HA.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""ADC GPIO BBB sensor."""
|
|
2
|
+
import logging
|
|
3
|
+
import asyncio
|
|
4
|
+
|
|
5
|
+
from boneio.const import SENSOR
|
|
6
|
+
from boneio.helper import BasicMqtt
|
|
7
|
+
import Adafruit_BBIO.ADC as ADC
|
|
8
|
+
|
|
9
|
+
_LOGGER = logging.getLogger(__name__)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def initialize_adc():
|
|
13
|
+
ADC.setup()
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class GpioADCSensor(BasicMqtt):
|
|
17
|
+
"""Represent Gpio ADC sensor."""
|
|
18
|
+
|
|
19
|
+
def __init__(self, pin: str, update_interval: int = 60, **kwargs) -> None:
|
|
20
|
+
"""Setup GPIO ADC Sensor"""
|
|
21
|
+
super().__init__(topic_type=SENSOR, **kwargs)
|
|
22
|
+
self._pin = pin
|
|
23
|
+
self._update_interval = update_interval
|
|
24
|
+
_LOGGER.debug("Configured sensor pin %s", self._pin)
|
|
25
|
+
|
|
26
|
+
@property
|
|
27
|
+
def state(self):
|
|
28
|
+
"""Give rounded value of temperature."""
|
|
29
|
+
return round(ADC.read(self._pin) * 1.8, 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=self.state,
|
|
37
|
+
)
|
|
38
|
+
await asyncio.sleep(self._update_interval)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""GPIOInputButton to receive signals."""
|
|
2
|
+
import logging
|
|
3
|
+
from functools import partial
|
|
4
|
+
|
|
5
|
+
from boneio.const import BOTH, PRESSED, RELEASED
|
|
6
|
+
from boneio.helper import edge_detect, GpioBaseClass
|
|
7
|
+
|
|
8
|
+
_LOGGER = logging.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class GpioInputSensor(GpioBaseClass):
|
|
12
|
+
"""Represent Gpio sensor on input boards."""
|
|
13
|
+
|
|
14
|
+
def __init__(self, **kwargs) -> None:
|
|
15
|
+
"""Setup GPIO Input Button"""
|
|
16
|
+
super().__init__(**kwargs)
|
|
17
|
+
edge_detect(self._pin, callback=self._handle_press, bounce=25, edge=BOTH)
|
|
18
|
+
_LOGGER.debug("Configured sensor pin %s", self._pin)
|
|
19
|
+
|
|
20
|
+
def _handle_press(self, pin: str) -> None:
|
|
21
|
+
"""Handle the button press callback"""
|
|
22
|
+
# Ignore if we are in a long press
|
|
23
|
+
if self.is_pressed:
|
|
24
|
+
_LOGGER.debug("Pressed event on pin %s", self._pin)
|
|
25
|
+
self._loop.call_soon_threadsafe(
|
|
26
|
+
partial(self._press_callback, PRESSED, self._pin)
|
|
27
|
+
)
|
|
28
|
+
else:
|
|
29
|
+
_LOGGER.debug("Released event on pin %s", self._pin)
|
|
30
|
+
self._loop.call_soon_threadsafe(
|
|
31
|
+
partial(self._press_callback, RELEASED, self._pin)
|
|
32
|
+
)
|
|
@@ -2,39 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
4
|
from adafruit_pct2075 import PCT2075
|
|
5
|
-
from typing import Callable, Union
|
|
6
5
|
from boneio.const import STATE, SENSOR, LM75
|
|
7
6
|
|
|
8
7
|
from boneio.helper.exceptions import I2CError
|
|
8
|
+
from boneio.helper import BasicMqtt
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
class LM75Sensor:
|
|
11
|
+
class LM75Sensor(BasicMqtt):
|
|
12
12
|
"""Represent LM75 sensor in BoneIO."""
|
|
13
13
|
|
|
14
|
-
def __init__(
|
|
15
|
-
self,
|
|
16
|
-
i2c,
|
|
17
|
-
address,
|
|
18
|
-
topic_prefix: str,
|
|
19
|
-
name: str,
|
|
20
|
-
send_message: Callable[[str, Union[str, dict]], None],
|
|
21
|
-
id: str = LM75,
|
|
22
|
-
):
|
|
14
|
+
def __init__(self, i2c, address, id: str = LM75, **kwargs):
|
|
23
15
|
"""Initialize LM75 class."""
|
|
24
|
-
|
|
25
|
-
self._name = name
|
|
26
|
-
self._send_message = send_message
|
|
27
|
-
self._send_topic = f"{topic_prefix}/{SENSOR}/{self._id}"
|
|
16
|
+
super().__init__(id=id, topic_type=SENSOR, **kwargs)
|
|
28
17
|
try:
|
|
29
18
|
self._pct = PCT2075(i2c_bus=i2c, address=address)
|
|
30
19
|
except ValueError as err:
|
|
31
20
|
raise I2CError(err)
|
|
32
21
|
|
|
33
|
-
@property
|
|
34
|
-
def name(self):
|
|
35
|
-
"""Return name of the sensor."""
|
|
36
|
-
return self._name
|
|
37
|
-
|
|
38
22
|
@property
|
|
39
23
|
def state(self):
|
|
40
24
|
"""Give rounded value of temperature."""
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: boneio
|
|
3
|
-
Version: 0.1.0.
|
|
3
|
+
Version: 0.1.0.dev16
|
|
4
4
|
Summary: Python Helper for BoneIO
|
|
5
5
|
Home-page: https://github.com/maciejk1984/boneIO
|
|
6
6
|
License: GNU General Public License v3.0
|
|
7
|
-
Download-URL: https://github.com/maciejk1984/boneIO/archive/0.1.0.
|
|
7
|
+
Download-URL: https://github.com/maciejk1984/boneIO/archive/0.1.0.dev16.zip
|
|
8
8
|
Platform: UNKNOWN
|
|
9
9
|
Classifier: Programming Language :: Python
|
|
10
10
|
Classifier: Programming Language :: Python :: 3.7
|
|
@@ -21,6 +21,7 @@ boneio/helper/__init__.py
|
|
|
21
21
|
boneio/helper/exceptions.py
|
|
22
22
|
boneio/helper/gpio.py
|
|
23
23
|
boneio/helper/ha_discovery.py
|
|
24
|
+
boneio/helper/mqtt.py
|
|
24
25
|
boneio/helper/oled.py
|
|
25
26
|
boneio/helper/stats.py
|
|
26
27
|
boneio/helper/yaml.py
|
|
@@ -31,4 +32,6 @@ boneio/relay/basic.py
|
|
|
31
32
|
boneio/relay/gpio.py
|
|
32
33
|
boneio/relay/mcp.py
|
|
33
34
|
boneio/sensor/__init__.py
|
|
35
|
+
boneio/sensor/adc.py
|
|
36
|
+
boneio/sensor/gpio.py
|
|
34
37
|
boneio/sensor/lm75.py
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
from Adafruit_BBIO import GPIO
|
|
3
|
-
from Adafruit_BBIO.GPIO import HIGH, LOW
|
|
4
|
-
|
|
5
|
-
from boneio.helper.exceptions import GPIOInputException
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def setup_output(pin: str):
|
|
9
|
-
"""Set up a GPIO as output."""
|
|
10
|
-
|
|
11
|
-
GPIO.setup(pin, GPIO.OUT, pull_up_down=GPIO.PUD_DOWN)
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
def setup_input(pin: str, pull_mode: str = "UP"):
|
|
15
|
-
"""Set up a GPIO as input."""
|
|
16
|
-
try:
|
|
17
|
-
GPIO.setup(pin, GPIO.IN, GPIO.PUD_DOWN if pull_mode == "DOWN" else GPIO.PUD_UP)
|
|
18
|
-
except (ValueError, SystemError) as err:
|
|
19
|
-
raise GPIOInputException(err)
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
def write_output(pin: str, value: str):
|
|
23
|
-
"""Write a value to a GPIO."""
|
|
24
|
-
|
|
25
|
-
GPIO.output(pin, value)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
def read_input(pin: str, on_state=LOW):
|
|
29
|
-
"""Read a value from a GPIO."""
|
|
30
|
-
return GPIO.input(pin) is on_state
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
def edge_detect(pin, callback, bounce):
|
|
34
|
-
"""Add detection for RISING and FALLING events."""
|
|
35
|
-
try:
|
|
36
|
-
GPIO.add_event_detect(pin, GPIO.FALLING, callback=callback, bouncetime=bounce)
|
|
37
|
-
except RuntimeError as err:
|
|
38
|
-
raise GPIOInputException(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
|