boneIO 0.1.0.dev5__tar.gz → 0.1.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.
Files changed (34) hide show
  1. {boneio-0.1.0.dev5 → boneio-0.1.0.dev7}/PKG-INFO +2 -2
  2. {boneio-0.1.0.dev5 → boneio-0.1.0.dev7}/boneio/bonecli.py +5 -1
  3. {boneio-0.1.0.dev5 → boneio-0.1.0.dev7}/boneio/helper/stats.py +48 -1
  4. {boneio-0.1.0.dev5 → boneio-0.1.0.dev7}/boneio/manager.py +18 -5
  5. {boneio-0.1.0.dev5 → boneio-0.1.0.dev7}/boneio/mqtt_client.py +1 -3
  6. boneio-0.1.0.dev7/boneio/oled.py +82 -0
  7. boneio-0.1.0.dev7/boneio/version.py +2 -0
  8. {boneio-0.1.0.dev5 → boneio-0.1.0.dev7}/boneio.egg-info/PKG-INFO +2 -2
  9. boneio-0.1.0.dev5/boneio/oled.py +0 -120
  10. boneio-0.1.0.dev5/boneio/version.py +0 -2
  11. {boneio-0.1.0.dev5 → boneio-0.1.0.dev7}/MANIFEST.in +0 -0
  12. {boneio-0.1.0.dev5 → boneio-0.1.0.dev7}/README.md +0 -0
  13. {boneio-0.1.0.dev5 → boneio-0.1.0.dev7}/boneio/__init__.py +0 -0
  14. {boneio-0.1.0.dev5 → boneio-0.1.0.dev7}/boneio/config.example.yaml +0 -0
  15. {boneio-0.1.0.dev5 → boneio-0.1.0.dev7}/boneio/config.yaml +0 -0
  16. {boneio-0.1.0.dev5 → boneio-0.1.0.dev7}/boneio/const.py +0 -0
  17. {boneio-0.1.0.dev5 → boneio-0.1.0.dev7}/boneio/helper/__init__.py +0 -0
  18. {boneio-0.1.0.dev5 → boneio-0.1.0.dev7}/boneio/helper/gpio.py +0 -0
  19. {boneio-0.1.0.dev5 → boneio-0.1.0.dev7}/boneio/helper/yaml.py +0 -0
  20. {boneio-0.1.0.dev5 → boneio-0.1.0.dev7}/boneio/input/__init__.py +0 -0
  21. {boneio-0.1.0.dev5 → boneio-0.1.0.dev7}/boneio/input/gpio.py +0 -0
  22. {boneio-0.1.0.dev5 → boneio-0.1.0.dev7}/boneio/relay/__init__.py +0 -0
  23. {boneio-0.1.0.dev5 → boneio-0.1.0.dev7}/boneio/relay/basic.py +0 -0
  24. {boneio-0.1.0.dev5 → boneio-0.1.0.dev7}/boneio/relay/gpio.py +0 -0
  25. {boneio-0.1.0.dev5 → boneio-0.1.0.dev7}/boneio/relay/mcp.py +0 -0
  26. {boneio-0.1.0.dev5 → boneio-0.1.0.dev7}/boneio/schema.yaml +0 -0
  27. {boneio-0.1.0.dev5 → boneio-0.1.0.dev7}/boneio.egg-info/SOURCES.txt +0 -0
  28. {boneio-0.1.0.dev5 → boneio-0.1.0.dev7}/boneio.egg-info/dependency_links.txt +0 -0
  29. {boneio-0.1.0.dev5 → boneio-0.1.0.dev7}/boneio.egg-info/entry_points.txt +0 -0
  30. {boneio-0.1.0.dev5 → boneio-0.1.0.dev7}/boneio.egg-info/requires.txt +0 -0
  31. {boneio-0.1.0.dev5 → boneio-0.1.0.dev7}/boneio.egg-info/top_level.txt +0 -0
  32. {boneio-0.1.0.dev5 → boneio-0.1.0.dev7}/requirements.txt +0 -0
  33. {boneio-0.1.0.dev5 → boneio-0.1.0.dev7}/setup.cfg +0 -0
  34. {boneio-0.1.0.dev5 → boneio-0.1.0.dev7}/setup.py +0 -0
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: boneio
3
- Version: 0.1.0.dev5
3
+ Version: 0.1.0.dev7
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.dev5.zip
7
+ Download-URL: https://github.com/maciejk1984/boneIO/archive/0.1.0.dev7.zip
8
8
  Platform: UNKNOWN
9
9
  Classifier: Programming Language :: Python
10
10
  Classifier: Programming Language :: Python :: 3.7
@@ -1,6 +1,7 @@
1
1
  from .helper import CustomValidator, load_yaml_file
2
2
  import click
3
3
  import logging
4
+ from contextlib import AsyncExitStack
4
5
  from colorlog import ColoredFormatter
5
6
  from .mqtt_client import MQTTClient
6
7
  from .manager import Manager
@@ -136,7 +137,10 @@ async def run(ctx, debug: int, config: str, mqttpassword: str = ""):
136
137
  mcp23017=_config[MCP23017],
137
138
  oled=_config.get(OLED),
138
139
  )
139
- await client.start_client(manager)
140
+ tasks = set()
141
+ tasks.add(client.start_client(manager))
142
+ tasks.update(manager.get_tasks())
143
+ await asyncio.gather(*tasks)
140
144
 
141
145
 
142
146
  if __name__ == "__main__":
@@ -1,7 +1,19 @@
1
1
  import asyncio
2
2
  import psutil
3
3
  from math import floor
4
- from ..const import GIGABYTE, MEGABYTE, NETWORK, DISK, MEMORY, CPU, SWAP, UPTIME
4
+ from ..const import (
5
+ GIGABYTE,
6
+ MEGABYTE,
7
+ NETWORK,
8
+ DISK,
9
+ MEMORY,
10
+ CPU,
11
+ SWAP,
12
+ UPTIME,
13
+ HOST,
14
+ OUTPUT,
15
+ OledDataTypes,
16
+ )
5
17
  import time
6
18
 
7
19
  intervals = (
@@ -113,3 +125,38 @@ host_stats = {
113
125
  SWAP: get_swap_info,
114
126
  UPTIME: get_uptime,
115
127
  }
128
+
129
+ import socket
130
+
131
+
132
+ class HostData:
133
+ """Helper class to store host data."""
134
+
135
+ data = {UPTIME: {}, NETWORK: {}, CPU: {}, DISK: {}, MEMORY: {}, SWAP: {}}
136
+
137
+ def __init__(self, output: dict) -> None:
138
+ """Initialize HostData."""
139
+ self._hostname = socket.gethostname()
140
+ self.data[UPTIME] = {HOST: self._hostname, UPTIME: 0}
141
+ self._output = output
142
+
143
+ def write(self, type: str, data: dict) -> None:
144
+ """Write data of chosen type."""
145
+ self.data[type] = data
146
+
147
+ def write_uptime(self, uptime: str) -> None:
148
+ """Write uptime."""
149
+ self.data[UPTIME][UPTIME] = uptime
150
+
151
+ def get(self, type: OledDataTypes) -> dict:
152
+ """Get saved stats."""
153
+ if type == OUTPUT:
154
+ return self._get_output()
155
+ return self.data[type]
156
+
157
+ def _get_output(self) -> dict:
158
+ """Get stats for output."""
159
+ out = {}
160
+ for output in self._output.values():
161
+ out[output.id] = output.state
162
+ return out
@@ -1,8 +1,14 @@
1
1
  from .input import GpioInputButton
2
2
  from .relay import GpioRelay, MCPRelay
3
3
  from .oled import Oled
4
+ from .helper.stats import host_stats, HostData
5
+ from typing import Set
6
+ import asyncio
7
+ import logging
8
+
4
9
  from .const import (
5
10
  ACTION,
11
+ OUTPUT,
6
12
  ACTIONS,
7
13
  ADDRESS,
8
14
  GPIO,
@@ -64,9 +70,11 @@ class Manager:
64
70
  ha_discovery_prefix: str = "homeassistant",
65
71
  mcp23017: Optional[List] = None,
66
72
  oled: bool = False,
73
+ web: bool = False,
67
74
  ) -> None:
68
75
  """Initialize the manager."""
69
76
  loop = asyncio.get_event_loop()
77
+ self._host_data = None
70
78
 
71
79
  self.send_message = send_message
72
80
  self._topic_prefix = topic_prefix
@@ -75,6 +83,7 @@ class Manager:
75
83
  self._i2cbusio = I2C(SCL, SDA)
76
84
  self._mcp = {}
77
85
  self._oled = None
86
+ self._tasks: List[asyncio.Task] = []
78
87
 
79
88
  if mcp23017:
80
89
  for mcp in mcp23017:
@@ -127,15 +136,19 @@ class Manager:
127
136
  for gpio in self._input_pins
128
137
  ]
129
138
 
139
+ if oled or web:
140
+ self._host_data = HostData(output=self.output)
141
+ for f in host_stats.values():
142
+ self._tasks.append(asyncio.create_task(f(self._host_data)))
143
+
130
144
  if oled:
131
- self._oled = Oled(self.output)
145
+ self._oled = Oled(self._host_data)
146
+ self._tasks.append(self._oled.get_task())
132
147
 
133
148
  self.send_message(topic=f"{topic_prefix}/{STATE}", payload=ONLINE)
134
149
 
135
- def get_oled_tasks(self) -> any:
136
- if not self._oled:
137
- return []
138
- return self._oled.get_tasks()
150
+ def get_tasks(self) -> Set[asyncio.Task]:
151
+ return self._tasks
139
152
 
140
153
  def press_callback(self, x: ClickTypes, inpin: str, actions: dict) -> None:
141
154
  """Press callback to use in input gpio.
@@ -144,7 +144,7 @@ class MQTTClient:
144
144
  self.create_client() # reset connect/reconnect futures
145
145
 
146
146
  async def _subscribe_manager(self, manager: any) -> None:
147
- """Connect and subscribe to manager topics."""
147
+ """Connect and subscribe to manager topics + host stats."""
148
148
  async with AsyncExitStack() as stack:
149
149
  tasks: Set[asyncio.Task] = set()
150
150
 
@@ -166,8 +166,6 @@ class MQTTClient:
166
166
  )
167
167
  tasks.add(messages_task)
168
168
 
169
- tasks.update(manager.get_oled_tasks())
170
-
171
169
  topic = f"{manager.relay_topic}"
172
170
  await self.subscribe(topic)
173
171
 
@@ -0,0 +1,82 @@
1
+ from .helper.gpio import setup_input, edge_detect
2
+ from .helper.stats import HostData
3
+ from .input.gpio import configure_pin
4
+ from .const import (
5
+ OLED_PIN,
6
+ NETWORK,
7
+ CPU,
8
+ DISK,
9
+ MEMORY,
10
+ SWAP,
11
+ NUM_OF_SCREENS,
12
+ UPTIME,
13
+ OUTPUT,
14
+ WHITE,
15
+ )
16
+ import asyncio
17
+ import os
18
+ import logging
19
+
20
+ from luma.core.interface.serial import i2c
21
+ from luma.core.render import canvas
22
+ from luma.oled.device import sh1106
23
+ from PIL import ImageFont
24
+
25
+ _LOGGER = logging.getLogger(__name__)
26
+
27
+
28
+ def make_font(name, size):
29
+ font_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "fonts", name))
30
+ return ImageFont.truetype(font_path, size)
31
+
32
+
33
+ fontBig = make_font("DejaVuSans.ttf", 12)
34
+ fontSmall = make_font("DejaVuSans.ttf", 10)
35
+
36
+ screen_order = [UPTIME, NETWORK, CPU, DISK, MEMORY, SWAP, OUTPUT]
37
+ lines = [17, 32, 47]
38
+
39
+
40
+ class Oled:
41
+ """Oled display class."""
42
+
43
+ def __init__(self, host_data: HostData) -> None:
44
+ """Initialize OLED screen."""
45
+ self._screen_no = 0
46
+ self._loop = asyncio.get_running_loop()
47
+ self._host_data = host_data
48
+ configure_pin(OLED_PIN)
49
+ setup_input(OLED_PIN)
50
+ edge_detect(OLED_PIN, callback=self._handle_press, bounce=50)
51
+ serial = i2c(port=2, address=0x3C)
52
+ self._device = sh1106(serial)
53
+ _LOGGER.debug("Configuring OLED screen.")
54
+
55
+ def get_task(self) -> list:
56
+ """Periodically check for host statistics."""
57
+ return asyncio.create_task(self.render_display())
58
+
59
+ async def render_display(self):
60
+ while True:
61
+ screen = screen_order[self._screen_no]
62
+ data = self._host_data.get(screen)
63
+ if data:
64
+ with canvas(self._device) as draw:
65
+ draw.text((1, 1), screen, font=fontBig, fill=WHITE)
66
+ i = 0
67
+ for k in data:
68
+ draw.text(
69
+ (3, lines[i]),
70
+ f"{k} {data[k]}",
71
+ font=fontSmall,
72
+ fill=WHITE,
73
+ )
74
+ i += 1
75
+ await asyncio.sleep(0.5)
76
+
77
+ def _handle_press(self, pin: any) -> None:
78
+ """Handle press of PIN for OLED display."""
79
+ if self._screen_no < NUM_OF_SCREENS:
80
+ self._screen_no += 1
81
+ else:
82
+ self._screen_no = 0
@@ -0,0 +1,2 @@
1
+ # flake8: noqa
2
+ __version__ = "0.1.0.dev7"
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: boneio
3
- Version: 0.1.0.dev5
3
+ Version: 0.1.0.dev7
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.dev5.zip
7
+ Download-URL: https://github.com/maciejk1984/boneIO/archive/0.1.0.dev7.zip
8
8
  Platform: UNKNOWN
9
9
  Classifier: Programming Language :: Python
10
10
  Classifier: Programming Language :: Python :: 3.7
@@ -1,120 +0,0 @@
1
- from .helper.gpio import setup_input, edge_detect
2
- from .helper.stats import host_stats
3
- from .input.gpio import configure_pin
4
- from .const import (
5
- OLED_PIN,
6
- NETWORK,
7
- CPU,
8
- DISK,
9
- MEMORY,
10
- SWAP,
11
- NUM_OF_SCREENS,
12
- UPTIME,
13
- HOST,
14
- OUTPUT,
15
- WHITE,
16
- OledDataTypes,
17
- )
18
- import asyncio
19
- import os
20
- import socket
21
- import logging
22
-
23
- from functools import partial
24
- from luma.core.interface.serial import i2c
25
- from luma.core.render import canvas
26
- from luma.oled.device import sh1106
27
- from PIL import ImageFont
28
-
29
- _LOGGER = logging.getLogger(__name__)
30
-
31
-
32
- def make_font(name, size):
33
- font_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "fonts", name))
34
- return ImageFont.truetype(font_path, size)
35
-
36
-
37
- fontBig = make_font("DejaVuSans.ttf", 12)
38
- fontSmall = make_font("DejaVuSans.ttf", 10)
39
-
40
- screen_order = [UPTIME, NETWORK, CPU, DISK, MEMORY, SWAP, OUTPUT]
41
- lines = [17, 32, 47]
42
-
43
-
44
- class HostData:
45
- """Helper class to store host data."""
46
-
47
- data = {UPTIME: {}, NETWORK: {}, CPU: {}, DISK: {}, MEMORY: {}, SWAP: {}}
48
-
49
- def __init__(self, output: dict) -> None:
50
- """Initialize HostData."""
51
- self._hostname = socket.gethostname()
52
- self.data[UPTIME] = {HOST: self._hostname, UPTIME: 0}
53
- self._output = output
54
-
55
- def write(self, type: str, data: dict) -> None:
56
- """Write data of chosen type."""
57
- self.data[type] = data
58
-
59
- def write_uptime(self, uptime: str) -> None:
60
- """Write uptime."""
61
- self.data[UPTIME][UPTIME] = uptime
62
-
63
- def get(self, type: OledDataTypes) -> dict:
64
- """Get saved stats."""
65
- if type == OUTPUT:
66
- return self._get_output()
67
- return self.data[type]
68
-
69
- def _get_output(self) -> dict:
70
- """Get stats for output."""
71
- out = {}
72
- for output in self._output.values():
73
- out[output.id] = output.state
74
- return out
75
-
76
-
77
- class Oled:
78
- """Oled display class."""
79
-
80
- def __init__(self, output: dict) -> None:
81
- """Initialize OLED screen."""
82
- self._screen_no = 0
83
- self._loop = asyncio.get_running_loop()
84
- self._host_data = HostData(output=output)
85
- configure_pin(OLED_PIN)
86
- setup_input(OLED_PIN)
87
- edge_detect(OLED_PIN, callback=self._handle_press, bounce=50)
88
- serial = i2c(port=2, address=0x3C)
89
- self._device = sh1106(serial)
90
- _LOGGER.debug("Configuring OLED screen.")
91
-
92
- def get_tasks(self) -> list:
93
- """Periodically check for host statistics."""
94
- return [
95
- asyncio.create_task(func(self._host_data)) for func in host_stats.values()
96
- ]
97
-
98
- def _handle_press(self, pin: any) -> None:
99
- """Handle press of PIN for OLED display."""
100
-
101
- def press_callback(screen_no):
102
- screen = screen_order[screen_no]
103
- data = self._host_data.get(screen)
104
- with canvas(self._device) as draw:
105
- draw.text((1, 1), screen, font=fontBig, fill=WHITE)
106
- i = 0
107
- for k in data:
108
- draw.text(
109
- (3, lines[i]),
110
- f"{k} {data[k]}",
111
- font=fontSmall,
112
- fill=WHITE,
113
- )
114
- i += 1
115
-
116
- self._loop.call_soon_threadsafe(partial(press_callback, self._screen_no))
117
- if self._screen_no < NUM_OF_SCREENS:
118
- self._screen_no += 1
119
- else:
120
- self._screen_no = 0
@@ -1,2 +0,0 @@
1
- # flake8: noqa
2
- __version__ = "0.1.0.dev5"
File without changes
File without changes
File without changes
File without changes
File without changes