first commit
This commit is contained in:
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
__pycache__
|
||||
luma.examples
|
||||
venv
|
||||
.ipynb_checkpoints
|
||||
testdata
|
||||
|
||||
111
requirements.txt
Normal file
111
requirements.txt
Normal file
@@ -0,0 +1,111 @@
|
||||
Adafruit-GPIO==1.0.3
|
||||
Adafruit-PureIO==1.1.11
|
||||
anyio==4.7.0
|
||||
argcomplete==3.5.3
|
||||
argon2-cffi==23.1.0
|
||||
argon2-cffi-bindings==21.2.0
|
||||
arrow==1.3.0
|
||||
asttokens==3.0.0
|
||||
async-lru==2.0.4
|
||||
attrs==24.3.0
|
||||
babel==2.16.0
|
||||
beautifulsoup4==4.12.3
|
||||
bleach==6.2.0
|
||||
cbor2==5.6.5
|
||||
certifi==2024.12.14
|
||||
cffi==1.17.1
|
||||
charset-normalizer==3.4.1
|
||||
comm==0.2.2
|
||||
debugpy==1.8.11
|
||||
decorator==5.1.1
|
||||
defusedxml==0.7.1
|
||||
executing==2.1.0
|
||||
fastjsonschema==2.21.1
|
||||
fqdn==1.5.1
|
||||
gpiod==2.2.3
|
||||
gpiodevice==0.0.5
|
||||
h11==0.14.0
|
||||
httpcore==1.0.7
|
||||
httpx==0.28.1
|
||||
idna==3.10
|
||||
ipykernel==6.29.5
|
||||
ipython==8.31.0
|
||||
isoduration==20.11.0
|
||||
jedi==0.19.2
|
||||
Jinja2==3.1.5
|
||||
json5==0.10.0
|
||||
jsonpointer==3.0.0
|
||||
jsonschema==4.23.0
|
||||
jsonschema-specifications==2024.10.1
|
||||
jupyter-events==0.11.0
|
||||
jupyter-lsp==2.2.5
|
||||
jupyter_client==8.6.3
|
||||
jupyter_core==5.7.2
|
||||
jupyter_server==2.15.0
|
||||
jupyter_server_terminals==0.5.3
|
||||
jupyterlab==4.3.4
|
||||
jupyterlab_pygments==0.3.0
|
||||
jupyterlab_server==2.27.3
|
||||
luma.core==2.4.2
|
||||
luma.emulator==1.5.0
|
||||
-e git+https://github.com/rm-hull/luma.examples.git@56551e17c0c5b46e01033abfbd1dec59e51bd1b5#egg=luma.examples
|
||||
luma.lcd==2.11.0
|
||||
luma.led-matrix==1.7.1
|
||||
luma.oled==3.14.0
|
||||
MarkupSafe==3.0.2
|
||||
matplotlib-inline==0.1.7
|
||||
mistune==3.1.0
|
||||
nbclient==0.10.2
|
||||
nbconvert==7.16.5
|
||||
nbformat==5.10.4
|
||||
nest_asyncio==1.6.0
|
||||
notebook_shim==0.2.4
|
||||
numpy==2.2.1
|
||||
overrides==7.7.0
|
||||
packaging==24.2
|
||||
pandocfilters==1.5.1
|
||||
parso==0.8.4
|
||||
pexpect==4.9.0
|
||||
pillow==11.1.0
|
||||
platformdirs==4.3.6
|
||||
prometheus_client==0.21.1
|
||||
prompt_toolkit==3.0.48
|
||||
psutil==6.1.1
|
||||
ptyprocess==0.7.0
|
||||
pure_eval==0.2.3
|
||||
pycparser==2.22
|
||||
pyftdi==0.56.0
|
||||
pygame==2.6.1
|
||||
Pygments==2.18.0
|
||||
pyserial==3.5
|
||||
python-dateutil==2.9.0.post0
|
||||
python-json-logger==3.2.1
|
||||
pyusb==1.3.0
|
||||
PyYAML==6.0.2
|
||||
pyzmq==26.2.0
|
||||
referencing==0.35.1
|
||||
requests==2.32.3
|
||||
rfc3339-validator==0.1.4
|
||||
rfc3986-validator==0.1.1
|
||||
rpds-py==0.22.3
|
||||
RPi.GPIO==0.7.1
|
||||
Send2Trash==1.8.3
|
||||
six==1.17.0
|
||||
smbus2==0.5.0
|
||||
sniffio==1.3.1
|
||||
soupsieve==2.6
|
||||
spidev==3.6
|
||||
st7735==1.0.0
|
||||
stack-data==0.6.3
|
||||
terminado==0.18.1
|
||||
tinycss2==1.4.0
|
||||
tornado==6.4.2
|
||||
traitlets==5.14.3
|
||||
types-python-dateutil==2.9.0.20241206
|
||||
typing_extensions==4.12.2
|
||||
uri-template==1.3.0
|
||||
urllib3==2.3.0
|
||||
wcwidth==0.2.13
|
||||
webcolors==24.11.1
|
||||
webencodings==0.5.1
|
||||
websocket-client==1.8.0
|
||||
275
test.ipynb
Normal file
275
test.ipynb
Normal file
@@ -0,0 +1,275 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "775aa673-2c89-4237-bab7-edc09d8688f4",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import time\n",
|
||||
"\n",
|
||||
"from PIL import Image, ImageDraw, ImageFont\n",
|
||||
"\n",
|
||||
"import st7735 as ST7735\n",
|
||||
"\n",
|
||||
"# Initialize display\n",
|
||||
"disp = ST7735.ST7735(\n",
|
||||
" port=0,\n",
|
||||
" cs=0,\n",
|
||||
" dc=24,\n",
|
||||
" backlight=22,\n",
|
||||
" rst=25,\n",
|
||||
" width=128,\n",
|
||||
" height=160,\n",
|
||||
" rotation=90,\n",
|
||||
" invert=False,\n",
|
||||
" spi_speed_hz=16000000\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "59f91f30-a3f1-46bc-9df3-a2ebfab35c59",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## hello world"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "9936314f-56b9-4147-bdd1-46a3afc048e6",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"disp.begin()\n",
|
||||
"img = Image.new('RGB', (disp.width, disp.height), color=(0, 0, 0))\n",
|
||||
"draw = ImageDraw.Draw(img)\n",
|
||||
"font = ImageFont.truetype(\"/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf\", 10)\n",
|
||||
"\n",
|
||||
"draw.rectangle((0, 0, disp.width, disp.height), fill=(0, 0, 0))\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"draw.text((5, 5), \"hello\", font=font, fill=(255, 255, 255))\n",
|
||||
"\n",
|
||||
"disp.display(img)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "1c25178b-41fd-42df-83bf-82cd72afb6a3",
|
||||
"metadata": {
|
||||
"jp-MarkdownHeadingCollapsed": true
|
||||
},
|
||||
"source": [
|
||||
"## scrolling text"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "7a8a8fcf-d747-4c8f-bdbd-d1d2d9e95ca1",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"KeyboardInterrupt\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"WIDTH = disp.width\n",
|
||||
"HEIGHT = disp.height\n",
|
||||
"\n",
|
||||
"MESSAGE = \"Aşkım seni çok seviyorum <3 <3 <3\"\n",
|
||||
"\n",
|
||||
"img = Image.new('RGB', (WIDTH, HEIGHT), color=(0, 0, 0))\n",
|
||||
"\n",
|
||||
"draw = ImageDraw.Draw(img)\n",
|
||||
"\n",
|
||||
"font = ImageFont.truetype(\"/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf\", 30)\n",
|
||||
"#font = ImageFont.truetype(\"/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf\", 40)\n",
|
||||
"#font = ImageFont.load_default()\n",
|
||||
"\n",
|
||||
"x1, y1, x2, y2 = font.getbbox(MESSAGE)\n",
|
||||
"size_x = x2 - x1\n",
|
||||
"size_y = y2 - y1\n",
|
||||
"\n",
|
||||
"text_x = 160\n",
|
||||
"text_y = (80 - size_y) // 2\n",
|
||||
"\n",
|
||||
"t_start = time.time()\n",
|
||||
"\n",
|
||||
"while True:\n",
|
||||
" x = (time.time() - t_start) * 100\n",
|
||||
" x %= (size_x + 160)\n",
|
||||
" draw.rectangle((0, 0, 160, 80), (0, 0, 0))\n",
|
||||
" draw.text((int(text_x - x), text_y), MESSAGE, font=font, fill=(255, 255, 255))\n",
|
||||
" disp.display(img)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "00bcd42e-3996-4b0f-9812-f8f6c332896f",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## display image "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "af75588d-c705-4717-bf9c-ddae1d705fff",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Loading image: testdata/20250104_193925.jpg...\n",
|
||||
"Drawing image\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"\"\"\"\n",
|
||||
"image.py - Display an image on the LCD.\n",
|
||||
"\n",
|
||||
"If you're using Breakout Garden, plug the 0.96\" LCD (SPI)\n",
|
||||
"breakout into the rear slot.\n",
|
||||
"\"\"\"\n",
|
||||
"\n",
|
||||
"image_file = \"testdata/20250104_193925.jpg\"# sys.argv[1]\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"WIDTH = disp.width\n",
|
||||
"HEIGHT = disp.height\n",
|
||||
"\n",
|
||||
"# Initialize display.\n",
|
||||
"disp.begin()\n",
|
||||
"\n",
|
||||
"# Load an image.\n",
|
||||
"print(f\"Loading image: {image_file}...\")\n",
|
||||
"image = Image.open(image_file)\n",
|
||||
"\n",
|
||||
"# Resize the image\n",
|
||||
"image = image.resize((WIDTH, HEIGHT))\n",
|
||||
"\n",
|
||||
"# Draw the image on the display hardware.\n",
|
||||
"print(\"Drawing image\")\n",
|
||||
"\n",
|
||||
"disp.display(image)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "69c9551f-13fe-450e-9b0d-ab28024ed0ba",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## ups stats"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"id": "6766902b-26b3-4cd9-8183-8de385d3081d",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import ups_plus"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"id": "3133f2de-2efd-4a90-b817-762ceb8d3ba4",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"RPi Volt: 4.93 V\n",
|
||||
"RPi Curr: 959.97 mA\n",
|
||||
"RPi Power: 4740.12 mW\n",
|
||||
"\n",
|
||||
"Bat Volt: 3.30 V\n",
|
||||
"Bat Curr: 43.90 mA\n",
|
||||
"Bat Power: 390.24 mW\n",
|
||||
"Bat Status: charging\n",
|
||||
"\n",
|
||||
"Charging Source: Type C Port\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"ups_stats = ups_plus.collect_data()\n",
|
||||
"ups_stats_to_display = ups_plus.prepare_for_display(ups_stats)\n",
|
||||
"print(ups_stats_to_display)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 42,
|
||||
"id": "453a24f6-f962-4a20-8f0f-793b908a7b04",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"ups_stats = ups_plus.collect_data()\n",
|
||||
"ups_stats_to_display = ups_plus.prepare_for_display(ups_stats)\n",
|
||||
"\n",
|
||||
"disp.begin()\n",
|
||||
"img = Image.new('RGB', (disp.width, disp.height), color=(0, 0, 0))\n",
|
||||
"draw = ImageDraw.Draw(img)\n",
|
||||
"font = ImageFont.truetype(\"/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf\", 10)\n",
|
||||
"\n",
|
||||
"draw.rectangle((0, 0, disp.width, disp.height), fill=(0, 0, 0))\n",
|
||||
"draw.text((5, 5), ups_stats_to_display, font=font, fill=(255, 255, 255))\n",
|
||||
"\n",
|
||||
"disp.display(img)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "c6fd6ea2-ec94-418b-9a4c-a06df33912f4",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "847aa97b-9a40-474e-becf-0038038c53d0",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.11.2"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
81
ups_plus.py
Normal file
81
ups_plus.py
Normal file
@@ -0,0 +1,81 @@
|
||||
import os
|
||||
import time
|
||||
import smbus2
|
||||
from ina219 import INA219, DeviceRangeError
|
||||
|
||||
# Define constants
|
||||
DEVICE_BUS = 1
|
||||
DEVICE_ADDR = 0x17
|
||||
PROTECT_VOLT = 3500
|
||||
|
||||
def get_supply_data():
|
||||
"""Retrieve Raspberry Pi supply data."""
|
||||
ina_supply = INA219(0.00725, busnum=DEVICE_BUS, address=0x40)
|
||||
ina_supply.configure()
|
||||
return {
|
||||
"voltage": ina_supply.voltage(),
|
||||
"current": ina_supply.current(),
|
||||
"power": ina_supply.power(),
|
||||
}
|
||||
|
||||
def get_battery_data():
|
||||
"""Retrieve battery data."""
|
||||
ina_batt = INA219(0.005, busnum=DEVICE_BUS, address=0x45)
|
||||
ina_batt.configure()
|
||||
batt_data = {
|
||||
"voltage": ina_batt.voltage(),
|
||||
"current": ina_batt.current(),
|
||||
"power": ina_batt.power(),
|
||||
}
|
||||
batt_data["status"] = "charging" if batt_data["current"] > 0 else "discharging"
|
||||
return batt_data
|
||||
|
||||
def get_uid(bus):
|
||||
"""Retrieve UID from the device."""
|
||||
aReceiveBuf = [0x00] + [bus.read_byte_data(DEVICE_ADDR, i) for i in range(1, 255)]
|
||||
return {
|
||||
"UID0": "%08X" % (aReceiveBuf[243] << 24 | aReceiveBuf[242] << 16 | aReceiveBuf[241] << 8 | aReceiveBuf[240]),
|
||||
"UID1": "%08X" % (aReceiveBuf[247] << 24 | aReceiveBuf[246] << 16 | aReceiveBuf[245] << 8 | aReceiveBuf[244]),
|
||||
"UID2": "%08X" % (aReceiveBuf[251] << 24 | aReceiveBuf[250] << 16 | aReceiveBuf[249] << 8 | aReceiveBuf[248]),
|
||||
}
|
||||
|
||||
def get_charging_source(bus):
|
||||
"""Determine the charging source."""
|
||||
aReceiveBuf = [0x00] + [bus.read_byte_data(DEVICE_ADDR, i) for i in range(1, 255)]
|
||||
if (aReceiveBuf[8] << 8 | aReceiveBuf[7]) > 4000:
|
||||
return "Type C Port"
|
||||
elif (aReceiveBuf[10] << 8 | aReceiveBuf[9]) > 4000:
|
||||
return "Micro USB Port"
|
||||
else:
|
||||
return "Not charging"
|
||||
|
||||
def collect_data():
|
||||
"""Collect all data and return as a dictionary."""
|
||||
bus = smbus2.SMBus(DEVICE_BUS)
|
||||
return {
|
||||
"raspberry_pi": get_supply_data(),
|
||||
"battery": get_battery_data(),
|
||||
"uid": get_uid(bus),
|
||||
"charging_source": get_charging_source(bus),
|
||||
}
|
||||
|
||||
def prepare_for_display(data):
|
||||
"""Format data as a string suitable for a 128x160 TFT screen.
|
||||
(print(prepare_for_display(ups_stats)))"""
|
||||
lines = [
|
||||
f"RPi Volt: {data['raspberry_pi']['voltage']:.2f} V",
|
||||
f"RPi Curr: {data['raspberry_pi']['current']:.2f} mA",
|
||||
f"RPi Power: {data['raspberry_pi']['power']:.2f} mW",
|
||||
"",
|
||||
f"Bat Volt: {data['battery']['voltage']:.2f} V",
|
||||
f"Bat Curr: {data['battery']['current']:.2f} mA",
|
||||
f"Bat Power: {data['battery']['power']:.2f} mW",
|
||||
f"Bat Status: {data['battery']['status']}",
|
||||
"",
|
||||
f"Charging Source: {data['charging_source']}",
|
||||
]
|
||||
return "\n".join(lines)
|
||||
|
||||
if __name__ == "__main__":
|
||||
data = collect_data()
|
||||
print(data)
|
||||
Reference in New Issue
Block a user