Reorganize code
This commit is contained in:
parent
3ef379b0b7
commit
2bb3159385
5 changed files with 243 additions and 70 deletions
|
@ -2,12 +2,13 @@ import tomllib
|
||||||
from datetime import date, datetime, timedelta, timezone
|
from datetime import date, datetime, timedelta, timezone
|
||||||
import json
|
import json
|
||||||
from threading import Timer
|
from threading import Timer
|
||||||
import psycopg2
|
|
||||||
from sense_hat import SenseHat
|
from sense_hat import SenseHat
|
||||||
from signal import pause
|
from signal import pause
|
||||||
from urllib import request, parse
|
from urllib import request, parse
|
||||||
|
|
||||||
from .tempo import TempoAPI, convert_color
|
from .tempo import TempoAPI
|
||||||
|
from .logger import SenseLogger
|
||||||
|
from .info import InfoPanel
|
||||||
|
|
||||||
with open("config.toml", "rb") as config_file:
|
with open("config.toml", "rb") as config_file:
|
||||||
config = tomllib.load(config_file)
|
config = tomllib.load(config_file)
|
||||||
|
@ -16,71 +17,7 @@ sense = SenseHat()
|
||||||
tempo_api = TempoAPI(config.get("rte_api_key"))
|
tempo_api = TempoAPI(config.get("rte_api_key"))
|
||||||
|
|
||||||
|
|
||||||
def show_trash():
|
sense_logger = SenseLogger(sense, "dbname=tsdb user=edpibu host=/run/postgresql")
|
||||||
if date.today().isocalendar().week % 2:
|
info_panel = InfoPanel(sense, tempo_api)
|
||||||
sense.show_message("DR", text_colour=[255, 255, 0])
|
|
||||||
else:
|
|
||||||
sense.show_message("OM", text_colour=[0, 127, 0])
|
|
||||||
|
|
||||||
|
|
||||||
def show_temp():
|
|
||||||
sense.show_message(f"{sense.temperature:.1f}", text_colour=[255, 0, 255])
|
|
||||||
|
|
||||||
|
|
||||||
def show_humidity():
|
|
||||||
sense.show_message(f"{sense.humidity:.1f}", text_colour=[0, 0, 255])
|
|
||||||
|
|
||||||
|
|
||||||
def show_tempo():
|
|
||||||
tempo_colors = [convert_color(c) for c in tempo_api.tempo]
|
|
||||||
sense.set_pixels([tempo_colors[1]] * 48 + [tempo_colors[0]] * 16)
|
|
||||||
tc = Timer(5, sense.clear)
|
|
||||||
tc.start()
|
|
||||||
|
|
||||||
|
|
||||||
def stick_loop():
|
|
||||||
event = sense.stick.wait_for_event(emptybuffer=True)
|
|
||||||
match event.direction:
|
|
||||||
case "up":
|
|
||||||
show_trash()
|
|
||||||
case "right":
|
|
||||||
show_temp()
|
|
||||||
case "left":
|
|
||||||
show_humidity()
|
|
||||||
case "down":
|
|
||||||
show_tempo()
|
|
||||||
case "middle":
|
|
||||||
sense.clear()
|
|
||||||
|
|
||||||
ts = Timer(0, stick_loop)
|
|
||||||
ts.start()
|
|
||||||
|
|
||||||
|
|
||||||
def save_loop(conn):
|
|
||||||
tp = Timer(30, save_loop, (conn,))
|
|
||||||
tp.start()
|
|
||||||
dt = datetime.now()
|
|
||||||
|
|
||||||
temp = sense.temperature
|
|
||||||
pres = sense.pressure
|
|
||||||
humi = sense.humidity
|
|
||||||
|
|
||||||
print(dt)
|
|
||||||
cursor = conn.cursor()
|
|
||||||
INS = "INSERT INTO sensor_data (time, sensor, value) VALUES (%s, %s, %s);"
|
|
||||||
try:
|
|
||||||
cursor.execute(INS, (dt, "temp", temp))
|
|
||||||
cursor.execute(INS, (dt, "pres", pres))
|
|
||||||
cursor.execute(INS, (dt, "humi", humi))
|
|
||||||
except (Exception, psycopg2.Error) as error:
|
|
||||||
print(error.pgerror)
|
|
||||||
conn.commit()
|
|
||||||
|
|
||||||
|
|
||||||
with psycopg2.connect(database="tsdb", user="edpibu", host="/run/postgresql") as conn:
|
|
||||||
tp = Timer(0, save_loop, (conn,))
|
|
||||||
tp.start()
|
|
||||||
|
|
||||||
ts = Timer(0, stick_loop)
|
|
||||||
ts.start()
|
|
||||||
sense.show_message(">")
|
sense.show_message(">")
|
||||||
|
|
65
oin/info/__init__.py
Normal file
65
oin/info/__init__.py
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
from threading import Thread, Timer
|
||||||
|
from datetime import date
|
||||||
|
|
||||||
|
from .utils import num_to_pixels
|
||||||
|
from ..tempo import convert_color
|
||||||
|
|
||||||
|
|
||||||
|
class InfoPanel:
|
||||||
|
def __init__(self, sense, tempo_api, rotation=0):
|
||||||
|
self.sense = sense
|
||||||
|
self.stick = self.sense.stick
|
||||||
|
self.rotation = rotation
|
||||||
|
self.sense.set_rotation(self.rotation)
|
||||||
|
|
||||||
|
self.tempo_api = tempo_api
|
||||||
|
|
||||||
|
self.start_stick_info()
|
||||||
|
self.clear_timer = Timer(5, self.sense.clear)
|
||||||
|
|
||||||
|
def start_stick_info(self):
|
||||||
|
self.thread = Thread(target=self.stick_info)
|
||||||
|
self.thread.start()
|
||||||
|
|
||||||
|
def start_clear_timer(self):
|
||||||
|
self.clear_timer.cancel()
|
||||||
|
self.clear_timer = Timer(5, self.sense.clear)
|
||||||
|
self.clear_timer.start()
|
||||||
|
|
||||||
|
def stick_info(self):
|
||||||
|
event = self.stick.wait_for_event(emptybuffer=True)
|
||||||
|
self.start_stick_info()
|
||||||
|
|
||||||
|
match event.direction:
|
||||||
|
case "up":
|
||||||
|
self.show_trash()
|
||||||
|
case "right":
|
||||||
|
self.show_temp()
|
||||||
|
case "left":
|
||||||
|
self.show_humidity()
|
||||||
|
case "down":
|
||||||
|
self.show_tempo()
|
||||||
|
case "middle":
|
||||||
|
self.sense.clear()
|
||||||
|
|
||||||
|
self.start_clear_timer()
|
||||||
|
|
||||||
|
def show_trash(self):
|
||||||
|
today = date.today().isocalendar()
|
||||||
|
if (today.week % 2) ^ (today.weekday >= 4):
|
||||||
|
self.sense.set_pixels(64 * [[255, 255, 0]])
|
||||||
|
else:
|
||||||
|
grid_line = 4 * [[0, 127, 0], [0, 15, 0]]
|
||||||
|
self.sense.set_pixels(4 * (grid_line + grid_line[::-1]))
|
||||||
|
|
||||||
|
def show_temp(self):
|
||||||
|
self.sense.set_pixels(
|
||||||
|
num_to_pixels(self.sense.temperature, color=[255, 0, 255])
|
||||||
|
)
|
||||||
|
|
||||||
|
def show_humidity(self):
|
||||||
|
self.sense.set_pixels(num_to_pixels(self.sense.humidity, color=[0, 255, 255]))
|
||||||
|
|
||||||
|
def show_tempo(self):
|
||||||
|
tempo_colors = [convert_color(c) for c in self.tempo_api.tempo]
|
||||||
|
self.sense.set_pixels([tempo_colors[1]] * 48 + [tempo_colors[0]] * 16)
|
133
oin/info/utils.py
Normal file
133
oin/info/utils.py
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
from itertools import chain
|
||||||
|
|
||||||
|
|
||||||
|
def digit_to_pixels(n, color=[255, 255, 255], bg_color=[0, 0, 0]):
|
||||||
|
X = color
|
||||||
|
O = bg_color
|
||||||
|
match n:
|
||||||
|
case "0":
|
||||||
|
return [
|
||||||
|
[O, O, O, O],
|
||||||
|
[O, X, X, O],
|
||||||
|
[X, O, O, X],
|
||||||
|
[X, O, O, X],
|
||||||
|
[X, O, O, X],
|
||||||
|
[X, O, O, X],
|
||||||
|
[O, X, X, O],
|
||||||
|
[O, O, O, O],
|
||||||
|
]
|
||||||
|
case "1":
|
||||||
|
return [
|
||||||
|
[O, O, O, O],
|
||||||
|
[O, O, O, X],
|
||||||
|
[O, O, X, X],
|
||||||
|
[O, X, O, X],
|
||||||
|
[O, O, O, X],
|
||||||
|
[O, O, O, X],
|
||||||
|
[O, O, O, X],
|
||||||
|
[O, O, O, O],
|
||||||
|
]
|
||||||
|
case "2":
|
||||||
|
return [
|
||||||
|
[O, O, O, O],
|
||||||
|
[O, X, X, O],
|
||||||
|
[X, O, O, X],
|
||||||
|
[O, O, O, X],
|
||||||
|
[O, O, X, O],
|
||||||
|
[O, X, O, O],
|
||||||
|
[X, X, X, X],
|
||||||
|
[O, O, O, O],
|
||||||
|
]
|
||||||
|
case "3":
|
||||||
|
return [
|
||||||
|
[O, O, O, O],
|
||||||
|
[X, X, X, X],
|
||||||
|
[O, O, O, X],
|
||||||
|
[O, O, X, O],
|
||||||
|
[O, O, O, X],
|
||||||
|
[X, O, O, X],
|
||||||
|
[O, X, X, O],
|
||||||
|
[O, O, O, O],
|
||||||
|
]
|
||||||
|
case "4":
|
||||||
|
return [
|
||||||
|
[O, O, O, O],
|
||||||
|
[O, O, O, X],
|
||||||
|
[O, O, X, X],
|
||||||
|
[O, X, O, X],
|
||||||
|
[X, O, X, X],
|
||||||
|
[X, X, X, X],
|
||||||
|
[O, O, O, X],
|
||||||
|
[O, O, O, O],
|
||||||
|
]
|
||||||
|
case "5":
|
||||||
|
return [
|
||||||
|
[O, O, O, O],
|
||||||
|
[X, X, X, X],
|
||||||
|
[X, O, O, O],
|
||||||
|
[X, X, X, O],
|
||||||
|
[O, O, O, X],
|
||||||
|
[X, O, O, X],
|
||||||
|
[O, X, X, O],
|
||||||
|
[O, O, O, O],
|
||||||
|
]
|
||||||
|
case "6":
|
||||||
|
return [
|
||||||
|
[O, O, O, O],
|
||||||
|
[O, X, X, X],
|
||||||
|
[X, O, O, O],
|
||||||
|
[X, X, X, O],
|
||||||
|
[X, O, O, X],
|
||||||
|
[X, O, O, X],
|
||||||
|
[O, X, X, O],
|
||||||
|
[O, O, O, O],
|
||||||
|
]
|
||||||
|
case "7":
|
||||||
|
return [
|
||||||
|
[O, O, O, O],
|
||||||
|
[X, X, X, X],
|
||||||
|
[O, O, O, X],
|
||||||
|
[O, O, X, O],
|
||||||
|
[O, X, O, O],
|
||||||
|
[X, O, O, O],
|
||||||
|
[X, O, O, O],
|
||||||
|
[O, O, O, O],
|
||||||
|
]
|
||||||
|
case "8":
|
||||||
|
return [
|
||||||
|
[O, O, O, O],
|
||||||
|
[O, X, X, O],
|
||||||
|
[X, O, O, X],
|
||||||
|
[O, X, X, O],
|
||||||
|
[X, O, O, X],
|
||||||
|
[X, O, O, X],
|
||||||
|
[O, X, X, O],
|
||||||
|
[O, O, O, O],
|
||||||
|
]
|
||||||
|
case "9":
|
||||||
|
return [
|
||||||
|
[O, O, O, O],
|
||||||
|
[O, X, X, O],
|
||||||
|
[X, O, O, X],
|
||||||
|
[X, O, O, X],
|
||||||
|
[O, X, X, X],
|
||||||
|
[O, O, O, X],
|
||||||
|
[O, X, X, O],
|
||||||
|
[O, O, O, O],
|
||||||
|
]
|
||||||
|
case _:
|
||||||
|
return 8 * [4 * [O]]
|
||||||
|
|
||||||
|
|
||||||
|
def num_to_pixels(n, color=[255, 255, 255], bg_color=[0, 0, 0]):
|
||||||
|
digits = f"{n:02.0f}"
|
||||||
|
if len(digits) > 2:
|
||||||
|
digits = "XX"
|
||||||
|
|
||||||
|
return list(
|
||||||
|
chain.from_iterable(
|
||||||
|
chain.from_iterable(
|
||||||
|
zip(*[digit_to_pixels(i, color, bg_color) for i in digits])
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
40
oin/logger/__init__.py
Normal file
40
oin/logger/__init__.py
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
from datetime import date, datetime, timedelta, timezone
|
||||||
|
from threading import Timer
|
||||||
|
import psycopg
|
||||||
|
from psycopg_pool import ConnectionPool
|
||||||
|
|
||||||
|
|
||||||
|
class SenseLogger:
|
||||||
|
def __init__(self, sense, conninfo):
|
||||||
|
self.sense = sense
|
||||||
|
self.database_pool = ConnectionPool(conninfo)
|
||||||
|
|
||||||
|
self.timer = Timer(0, self.log)
|
||||||
|
self.timer.start()
|
||||||
|
|
||||||
|
def log(self):
|
||||||
|
self.timer = Timer(30, self.log)
|
||||||
|
self.timer.start()
|
||||||
|
|
||||||
|
dt = datetime.now()
|
||||||
|
|
||||||
|
temp = self.sense.temperature
|
||||||
|
pres = self.sense.pressure
|
||||||
|
humi = self.sense.humidity
|
||||||
|
|
||||||
|
print(dt)
|
||||||
|
INS = "INSERT INTO sensor_data (time, sensor, value) VALUES (%s, %s, %s);"
|
||||||
|
|
||||||
|
conn = self.database_pool.getconn()
|
||||||
|
try:
|
||||||
|
with conn.cursor() as cursor:
|
||||||
|
cursor.execute(INS, (dt, "temp", temp))
|
||||||
|
cursor.execute(INS, (dt, "pres", pres))
|
||||||
|
cursor.execute(INS, (dt, "humi", humi))
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
except:
|
||||||
|
conn.rollback()
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
self.database_pool.putconn(conn)
|
|
@ -51,8 +51,6 @@ class TempoAPI:
|
||||||
) as res:
|
) as res:
|
||||||
api_data = json.load(res)
|
api_data = json.load(res)
|
||||||
|
|
||||||
print(api_data.get("tempo_like_calendars").get("values"))
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
val.get("value")
|
val.get("value")
|
||||||
for val in api_data.get("tempo_like_calendars").get("values")
|
for val in api_data.get("tempo_like_calendars").get("values")
|
||||||
|
|
Loading…
Reference in a new issue