pioled-display-plugin 0.0.1__py3-none-any.whl

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.
@@ -0,0 +1,7 @@
1
+ Copyright Pioreactor
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,14 @@
1
+ Metadata-Version: 2.1
2
+ Name: piOLED-display-plugin
3
+ Version: 0.0.1
4
+ Summary: Use an OLED display with your Pioreactor
5
+ Home-page: https://github.com/Pioreactor/PiOLED-display-plugin
6
+ Author: Cameron Davidson-Pilon
7
+ Author-email: hello@pioreactor.com
8
+ Description-Content-Type: text/markdown
9
+ License-File: LICENSE.txt
10
+ Requires-Dist: adafruit-circuitpython-ssd1306
11
+
12
+ ## PiOLD Display plugin for the Pioreactor
13
+
14
+ Display growth rate, normalized OD, and temperature for each Pioreactor.
@@ -0,0 +1,8 @@
1
+ src/__init__.py,sha256=9EJajAlnuPP4tcu6ldCu89kbAswlffYARqj6hgKINOs,3955
2
+ src/ui/contrib/jobs/piOLED_display.yaml,sha256=bvfBrtSnU5iGSiXq4BYw0kHBcaGRmbYa_LXmD4WvLWE,199
3
+ piOLED_display_plugin-0.0.1.dist-info/LICENSE.txt,sha256=ocekcdri6meHuZdEP-AjJ_MucbIJ6VAG-CTqTIwJa_8,1052
4
+ piOLED_display_plugin-0.0.1.dist-info/METADATA,sha256=CSR0oP03HK9Ul4bkYEQLGWK1IwT8rRxyZ4AahL0bH-U,474
5
+ piOLED_display_plugin-0.0.1.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
6
+ piOLED_display_plugin-0.0.1.dist-info/entry_points.txt,sha256=0GllHNoaQ8f2hlQMTB4YGTheHvigJzMCKQb9Rb-OckQ,49
7
+ piOLED_display_plugin-0.0.1.dist-info/top_level.txt,sha256=74rtVfumQlgAPzR5_2CgYN24MB0XARCg0t-gzk6gTrM,4
8
+ piOLED_display_plugin-0.0.1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: bdist_wheel (0.40.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [pioreactor.plugins]
2
+ piOLED-display-plugin = src
src/__init__.py ADDED
@@ -0,0 +1,113 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ import busio
4
+ from PIL import Image, ImageDraw, ImageFont
5
+ import adafruit_ssd1306
6
+ import click
7
+
8
+ from msgspec.json import decode
9
+ from pioreactor.hardware import SCL, SDA
10
+ from pioreactor.whoami import get_unit_name, get_latest_experiment_name
11
+ from pioreactor import structs
12
+ from pioreactor.background_jobs.base import BackgroundJobContrib
13
+ from pioreactor import types as pt
14
+
15
+
16
+ class PiOLEDDisplay(BackgroundJobContrib):
17
+
18
+ job_name = "piOLED_display"
19
+
20
+ def __init__(self, unit: str, experiment: str):
21
+ super().__init__(unit, experiment, plugin_name="PiOLED-display-plugin")
22
+
23
+ # Create the I2C interface.
24
+ i2c = busio.I2C(SCL, SDA)
25
+
26
+ self.disp = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c)
27
+ self.disp.rotation = 2
28
+
29
+ # Clear display.
30
+ self.disp.fill(0)
31
+ self.disp.show()
32
+
33
+ # Create blank image for drawing.
34
+ # Make sure to create image with mode '1' for 1-bit color.
35
+ self.width = self.disp.width
36
+ self.height = self.disp.height
37
+ self.image = Image.new("1", (self.width, self.height))
38
+
39
+ # Get drawing object to draw on image.
40
+ self.draw = ImageDraw.Draw(self.image)
41
+
42
+
43
+ # Draw some shapes.
44
+ # First define some constants to allow easy resizing of shapes.
45
+ padding = -2
46
+ self.top = padding
47
+ self.bottom = self.height - padding
48
+ # Move left to right keeping track of the current x position for drawing shapes.
49
+ self.x = 0
50
+
51
+
52
+ # Load default font.
53
+ self.font = ImageFont.load_default()
54
+
55
+ # intialize data
56
+ self.growth_rate = None
57
+ self.od = None
58
+ self.temp = None
59
+
60
+ self.update_display()
61
+ self.start_passive_listeners()
62
+
63
+
64
+ def update_od(self, msg: pt.MQTTMessage):
65
+ if msg.payload:
66
+ self.od = decode(msg.payload, type=structs.ODFiltered).od_filtered
67
+ else:
68
+ self.od = None
69
+ self.update_display()
70
+
71
+ def update_temp(self, msg: pt.MQTTMessage):
72
+ if msg.payload:
73
+ self.growth_rate = decode(msg.payload, type=structs.GrowthRate).growth_rate
74
+ else:
75
+ self.growth_rate = None
76
+ self.update_display()
77
+
78
+ def update_growth_rate(self, msg: pt.MQTTMessage):
79
+ if msg.payload:
80
+ self.temp = decode(msg.payload, type=structs.Temperature).temperature
81
+ else:
82
+ self.temp = None
83
+ self.update_display()
84
+
85
+ def start_passive_listeners(self):
86
+ self.subscribe_and_callback(self.update_od, f"pioreactor/{self.unit}/{self.experiment}/growth_rate_calculating/od_filtered", allow_retained=False)
87
+ self.subscribe_and_callback(self.update_growth_rate, f"pioreactor/{self.unit}/{self.experiment}/growth_rate_calculating/growth_rate", allow_retained=False)
88
+ self.subscribe_and_callback(self.update_temp, f"pioreactor/{self.unit}/{self.experiment}/temperature_control/temperature", allow_retained=False)
89
+
90
+ def update_display(self):
91
+ # Draw a black filled box to clear the image.
92
+ self.draw.rectangle((0, 0, self.width, self.height), outline=0, fill=0)
93
+ # Write four lines of text.
94
+ self.draw.text((self.x, self.top + 0), self.unit, font=self.font, fill=255)
95
+ if self.growth_rate:
96
+ self.draw.text((self.x, self.top + 8), f" Growth rate: {self.growth_rate:.2f}/h", font=self.font, fill=255)
97
+ if self.od:
98
+ self.draw.text((self.x, self.top + 16), f" OD: {self.od:.2f} AU", font=self.font, fill=255)
99
+ if self.temp:
100
+ self.draw.text((self.x, self.top + 25), f" Temp: {self.temp:.0f} C", font=self.font, fill=255)
101
+
102
+ # Display image.
103
+ self.disp.image(self.image)
104
+ self.disp.show()
105
+
106
+
107
+ @click.command(name="piOLED_display")
108
+ def click_pioled_display():
109
+ lg = PiOLEDDisplay(
110
+ unit=get_unit_name(), experiment=get_latest_experiment_name()
111
+ )
112
+ lg.block_until_disconnected()
113
+
@@ -0,0 +1,7 @@
1
+ ---
2
+ display_name: Display
3
+ job_name: piOLED_display
4
+ display: true # true to display on the /Pioreactors card
5
+ source: PiOLED_display_plugin
6
+ description: Turn on the OLED display
7
+ published_settings: []