From 83467531b028a0e5daaa7e621358f12e038eb190 Mon Sep 17 00:00:00 2001 From: Akbar Rahman Date: Fri, 15 May 2026 20:41:41 +0100 Subject: [PATCH] add python blinkie example --- config.toml | 9 ++++++ readme.md | 6 ++++ requirements.txt | 5 ++++ res/pdweather.py | 61 +++++++++++++++++++++++++++++++++++++++ res/templates/forest.gif | Bin 0 -> 1436 bytes src/main.py | 4 +-- 6 files changed, 83 insertions(+), 2 deletions(-) create mode 100755 res/pdweather.py create mode 100644 res/templates/forest.gif diff --git a/config.toml b/config.toml index 0643918..81b4f14 100644 --- a/config.toml +++ b/config.toml @@ -20,3 +20,12 @@ command = ["bash", "-c", "/usr/bin/uptime -p | cut -d, -f-2"] font = "./res/curie.bdf" text_filters = [ "lowercase" ] text_offset = [21, 4] + +[[image]] +output = "out/pdweather.gif" +template = "./res/templates/forest.gif" +command = [ "python", "./res/pdweather.py" ] + +font = "./res/curie.bdf" +text_filters = [ "lowercase" ] +text_offset = [45, 4] diff --git a/readme.md b/readme.md index e8d7ef9..924501e 100644 --- a/readme.md +++ b/readme.md @@ -18,6 +18,12 @@ a [dockerfile](./Dockerfile) and [compose file](./compose.yaml) have been provid keep in mind the commands will run in the docker container, too. you do not need to clone this repository to use the compose file provided. +the docker image installs the python +[`requests` library](https://docs.python-requests.org/en/latest/index.html), +so you can use it for calling external APIs inside the container. + +the `pdweather` blinkie example does this. + ### custom images to use utilities not installed in the standard docker image, diff --git a/requirements.txt b/requirements.txt index 91422db..2c4d27a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,6 @@ +certifi==2026.4.22 +charset-normalizer==3.4.7 +idna==3.15 pillow==12.2.0 +requests==2.34.2 +urllib3==2.7.0 diff --git a/res/pdweather.py b/res/pdweather.py new file mode 100755 index 0000000..638f1f9 --- /dev/null +++ b/res/pdweather.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 +# +# Akbar Rahman +# + +import sys +from datetime import datetime as dt + +import requests + + +def get_args(): + """ Get command line arguments """ + + import argparse + parser = argparse.ArgumentParser() + return parser.parse_args() + + +def main(args): + """ Entry point for script """ + resp = requests.get("https://api.open-meteo.com/v1/forecast?latitude=53.35&longitude=-1.8333&hourly=temperature_2m,rain,cloud_cover&timezone=GMT&forecast_days=1").json() + + now = dt.now() + closest_past_date = None + for idx, datetime_string in enumerate(resp['hourly']['time']): + date = dt.fromisoformat(datetime_string) + + if closest_past_date is None: + closest_past_date = (idx, date) + continue + + if date > now: # date > now means date is in future, ignore + continue + + if (now - date) < (now - closest_past_date[1]): + closest_past_date = (idx, date) + continue + + cur_weather = {} + for key in resp['hourly'].keys(): + cur_weather[key] = resp['hourly'][key][closest_past_date[0]] + + output = "sunny in peaks" + + if cur_weather['cloud_cover'] > 40: + output = "cloudy in peaks" + + if cur_weather['rain'] > 0.5: + output = "raining in peaks" + + print(output, end='') + + return 0 + + +if __name__ == '__main__': + try: + sys.exit(main(get_args())) + except KeyboardInterrupt: + sys.exit(0) diff --git a/res/templates/forest.gif b/res/templates/forest.gif new file mode 100644 index 0000000000000000000000000000000000000000..0b7954c0d8943f8d54e332b1e4fbc10f355bf5d6 GIT binary patch literal 1436 zcmZ?wbhEHboW>x+&?3R0FU8EG!y{-SEMg(LI2BQ4{sBNlD+ZBE|pQey$ zm$7PH&g*?2s%@uzjVZ2uZszxW&t3l&pGBM99vFCr$W1??QSxhz)%vqD%1*zn+OHG6 z&_H0uS$4;Svw8B@p6^&tAR*4vQDb-T#qa;Tjg9s7oK=-mP@n#M7ur*}pFnkgHqHqGVPdUVGE zf~<{ySK?j!AQ%qpsV6&pcI3|>Eb&bzkZrHKeJ93{`6{UTX_Dx zd9{D#IDVPL9`O_A4su#ivUKjW)~DZQuJAeHI#*C3<=(2DpRdoFX}(>jIwEVGOWBoq ziLbvI-btDyStIo@FGRaGy72K~Ude4Y7iEYV`n~)ins}p4wQg0!Zl8UupB8*BW!U>` zU)q($@2hRUe82O+!&%^RnOlJ$kPBEX6dGMf_{~3#7%UPcv3gufWo}bKQTr?#h`&h2<^tMeKgQsh- z&jlqZ3#OA@3_7ChJ&MPgV(RPvl!vr?@=CZjR^RDZP+!uR_++Ao+DlepAFo7LG2fs@ z*D3x%mP;pxdvU5xbJ2MDbb5l8BoinJG72%s<4%Ivk>^Wo2`9ld # -import shlex import sys import subprocess import time @@ -21,6 +20,7 @@ def get_args(): parser.add_argument("-L", "--no-loop", action="store_true") return parser.parse_args() + def generate(config): if config.get('template'): img = Image.open(config['template']) @@ -44,7 +44,7 @@ def generate(config): elif filter == "uppercase": text = text.upper() - draw.text(config.get('text_offset', [0, 0]), text, font=font) + draw.text(config.get('text_offset', [0, 0]), text, font=font, fill=(255, 255, 255, 255)) img.save(config['output'], save_all=True)