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.
Files changed (43) hide show
  1. {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/PKG-INFO +2 -2
  2. {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/bonecli.py +4 -2
  3. {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/const.py +57 -30
  4. {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/helper/__init__.py +23 -2
  5. boneio-0.1.0.dev16/boneio/helper/gpio.py +79 -0
  6. {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/helper/ha_discovery.py +43 -4
  7. boneio-0.1.0.dev16/boneio/helper/mqtt.py +30 -0
  8. {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/helper/stats.py +6 -6
  9. boneio-0.1.0.dev16/boneio/input/__init__.py +5 -0
  10. {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/input/gpio.py +9 -36
  11. {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/manager.py +92 -21
  12. {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/oled.py +15 -5
  13. {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/relay/basic.py +5 -13
  14. {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/relay/gpio.py +2 -1
  15. {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/schema.yaml +69 -1
  16. boneio-0.1.0.dev16/boneio/sensor/__init__.py +6 -0
  17. boneio-0.1.0.dev16/boneio/sensor/adc.py +38 -0
  18. boneio-0.1.0.dev16/boneio/sensor/gpio.py +32 -0
  19. {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/sensor/lm75.py +4 -20
  20. boneio-0.1.0.dev16/boneio/version.py +2 -0
  21. {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio.egg-info/PKG-INFO +2 -2
  22. {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio.egg-info/SOURCES.txt +3 -0
  23. boneio-0.1.0.dev14/boneio/helper/gpio.py +0 -38
  24. boneio-0.1.0.dev14/boneio/input/__init__.py +0 -5
  25. boneio-0.1.0.dev14/boneio/sensor/__init__.py +0 -4
  26. boneio-0.1.0.dev14/boneio/version.py +0 -2
  27. {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/MANIFEST.in +0 -0
  28. {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/README.md +0 -0
  29. {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/__init__.py +0 -0
  30. {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/fonts/danube__.ttf +0 -0
  31. {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/helper/exceptions.py +0 -0
  32. {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/helper/oled.py +0 -0
  33. {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/helper/yaml.py +0 -0
  34. {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/mqtt_client.py +0 -0
  35. {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/relay/__init__.py +0 -0
  36. {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio/relay/mcp.py +0 -0
  37. {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio.egg-info/dependency_links.txt +0 -0
  38. {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio.egg-info/entry_points.txt +0 -0
  39. {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio.egg-info/requires.txt +0 -0
  40. {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/boneio.egg-info/top_level.txt +0 -0
  41. {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/requirements.txt +0 -0
  42. {boneio-0.1.0.dev14 → boneio-0.1.0.dev16}/setup.cfg +0 -0
  43. {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.dev14
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.dev14.zip
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
- GPIO_INPUT,
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(GPIO_INPUT, []),
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
- DEBOUNCE_DURATION = timedelta(seconds=0.2)
7
- LONG_PRESS_DURATION = timedelta(seconds=0.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
- MCP = "mcp"
42
- MCP_ID = "mcp_id"
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
- OLED = "oled"
57
- FONTS = "fonts"
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
- LM75="lm75"
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 edge_detect, setup_input, read_input
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 ha_sensor_availibilty_message(id: str, name: str, topic: str = "boneio"):
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}/{INPUT}/{id}",
42
- "unique_id": f"{topic}{INPUT}{id}",
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)
@@ -0,0 +1,5 @@
1
+ """Input classes."""
2
+
3
+ from boneio.input.gpio import GpioInputButton
4
+
5
+ __all__ = ["GpioInputButton"]
@@ -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, read_input, setup_input
15
+ from boneio.helper import edge_detect, GpioBaseClass
22
16
 
23
17
  _LOGGER = logging.getLogger(__name__)
24
18
 
25
19
 
26
- def configure_pin(pin: str) -> None:
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
- self._pin = pin
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
- ha_sensor_availibilty_message,
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
- from boneio.oled import Oled
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 configure_button(gpio):
226
+ def configure_input(gpio):
181
227
  try:
182
228
  pin = gpio[PIN]
183
- GpioInputButton(
184
- pin=pin,
185
- press_callback=lambda x, i: self.press_callback(
186
- x, i, gpio.get(ACTIONS, {})
187
- ),
188
- rest_pin=gpio,
189
- )
190
- self.send_ha_autodiscovery(
191
- id=pin,
192
- name=gpio.get(ID, pin),
193
- ha_type="sensor",
194
- prefix=ha_discovery_prefix,
195
- availibilty_msg_func=ha_sensor_availibilty_message,
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
- configure_button(gpio=gpio)
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(self, x: ClickTypes, inpin: str, actions: dict) -> None:
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}/{INPUT}/{inpin}"
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 HostData, edge_detect, make_font, setup_input
12
- from boneio.input import configure_pin
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
- serial = i2c(port=2, address=0x3C)
43
- self._device = sh1106(serial)
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, Union
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
- self._id = id.replace(" ", "")
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.gpio import HIGH, LOW, read_input, setup_output, write_output
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
- gpio_input:
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,6 @@
1
+ """Sensor module."""
2
+ from boneio.sensor.lm75 import LM75Sensor
3
+ from boneio.sensor.gpio import GpioInputSensor
4
+ from boneio.sensor.adc import initialize_adc, GpioADCSensor
5
+
6
+ __all__ = ["LM75Sensor", "GpioInputSensor", "initialize_adc", "GpioADCSensor"]
@@ -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
- self._id = id
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."""
@@ -0,0 +1,2 @@
1
+ # flake8: noqa
2
+ __version__ = "0.1.0.dev16"
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: boneio
3
- Version: 0.1.0.dev14
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.dev14.zip
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)
@@ -1,5 +0,0 @@
1
- """Input classes."""
2
-
3
- from boneio.input.gpio import GpioInputButton, configure_pin
4
-
5
- __all__ = ["GpioInputButton", "configure_pin"]
@@ -1,4 +0,0 @@
1
- """Sensor module."""
2
- from boneio.sensor.lm75 import LM75Sensor
3
-
4
- __all__ = ["LM75Sensor"]
@@ -1,2 +0,0 @@
1
- # flake8: noqa
2
- __version__ = "0.1.0.dev14"
File without changes
File without changes
File without changes
File without changes