Initial commit
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
# main.py
|
||||
|
||||
import logging
|
||||
import time
|
||||
import traceback
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
import schedule
|
||||
from icmplib import ping as _ping
|
||||
|
||||
from tools.weather_logger import set_up_logger
|
||||
|
||||
set_up_logger()
|
||||
|
||||
from constants import MONTH_NAMES, WEEK_DAYS
|
||||
from display import Display
|
||||
from environment import Weather
|
||||
from tools.mqtt import MQTT
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.info("Setting up components...")
|
||||
|
||||
weather = Weather()
|
||||
display = Display()
|
||||
mqtt = MQTT()
|
||||
|
||||
|
||||
def is_network_up(retries: int = 2, timeout: int = 2) -> bool:
|
||||
"""Checks if the internet is accessible by pinging Cloudflare."""
|
||||
try:
|
||||
host = _ping("1.1.1.1", count=retries, timeout=timeout, privileged=False)
|
||||
return host.is_alive
|
||||
except Exception as e:
|
||||
logger.warning(f"Ping failed: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def date_string(date: datetime) -> tuple[str, str]:
|
||||
"""Formats the date and time strings for the display."""
|
||||
date_line = (
|
||||
f"{WEEK_DAYS[date.weekday()]}, {date.day} {MONTH_NAMES[date.month]} {date.year}"
|
||||
)
|
||||
time_line = f"{date.hour:02d}:{date.minute:02d}"
|
||||
return date_line, time_line
|
||||
|
||||
|
||||
def update(first: bool = False) -> None:
|
||||
start_timestamp = time.time()
|
||||
logger.debug("Running scheduled update")
|
||||
date = datetime.now() if first else datetime.now() + timedelta(seconds=20)
|
||||
logger.debug(f"Target display time: {date}")
|
||||
|
||||
weather_data = weather.get(date)
|
||||
mqtt.send(weather_data)
|
||||
|
||||
str_date = date_string(date)
|
||||
|
||||
logger.debug("Constructing the Image...")
|
||||
image = display.image.make_image(str_date, weather_data, is_network_up(timeout=1))
|
||||
|
||||
logger.debug("Refreshing the E-ink display...")
|
||||
display.refresh(image, date, first)
|
||||
|
||||
logger.debug(
|
||||
f"Update completed in {round(time.time() - start_timestamp, 2)} seconds"
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
logger.info("Checking network connection...")
|
||||
is_network_up()
|
||||
|
||||
try:
|
||||
logger.info("Starting weather station")
|
||||
update(first=True)
|
||||
schedule.every().minute.at(":40").do(update)
|
||||
logger.info("Schedule started")
|
||||
|
||||
while True:
|
||||
schedule.run_pending()
|
||||
time.sleep(1)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
logger.info("Manual exit requested (Ctrl+C). Shutting down...")
|
||||
except Exception as e:
|
||||
logger.error(f"Schedule failed - ERROR: {e}")
|
||||
logger.error(traceback.format_exc())
|
||||
finally:
|
||||
try:
|
||||
Display.exit()
|
||||
logger.info("E-ink display safely shut down.")
|
||||
except Exception as display_error:
|
||||
logger.error(
|
||||
f"Failed to shutdown the E-ink Display cleanly: {display_error}"
|
||||
)
|
||||
exit()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user