Files
raspi-iot-ryhmatyo/init.py
Aaro Varis 437c106789 aa
2026-01-15 10:56:32 +02:00

142 lines
5.0 KiB
Python

from time import time
from astral import LocationInfo
from astral.sun import sun
from datetime import date
from grove.gpio import GPIO
from grove.display.jhd1802 import JHD1802
city = LocationInfo("Seinäjoki", "Finland", "Europe/Helsinki", 62.7900, 22.8400)
s = sun(city.observer, date=date.today())
print(f"City: {city.name}, {city.region}")
print(f"Timezone: {city.timezone}")
print(f"Latitude: {city.latitude:.6f}; Longitude: {city.longitude:.6f}")
def isSunUp() -> bool:
from datetime import datetime
now = datetime.now(city.tzinfo)
return s["sunrise"] <= now <= s["sunset"]
# sunset and sunrise
class AlarmClock:
ledGpio: GPIO
buttonGpio: GPIO
relayGpio: GPIO
lastKnownButtonState: bool = False
lcd: JHD1802
lastButtonPressTime: float = 0.0
lastButtonStateChangeTime: float = 0.0
debounceDelay: float = 0.05 # 50ms debounce delay
longPressThreshold: float = 2.0 # 2 seconds for long press
buttonPressStartTime: float = 0.0
configMode: str = "normal" # modes: normal, set_hour, set_minute
alarmHour: int = 7
alarmMinute: int = 0
def __init__(self, pins: dict = {}):
self.ledGpio = GPIO(pins.get("led", 5), GPIO.OUT)
self.buttonGpio = GPIO(pins.get("button", 6), GPIO.IN)
self.relayGpio = GPIO(pins.get("relay", 16), GPIO.OUT)
self.lcd = JHD1802()
self.setLcdText("AlarmClock Init")
def start(self):
print("AlarmClock started")
while True:
self.loop()
def setRelayState(self, state: bool):
self.relayGpio.write(1 if state else 0)
def loop(self):
currentButtonState = not self.buttonGpio.read()
currentTime = time()
# Only process button state change if debounce delay has passed
if currentButtonState != self.lastKnownButtonState:
if (currentTime - self.lastButtonStateChangeTime) >= self.debounceDelay:
self.lastKnownButtonState = currentButtonState
self.lastButtonStateChangeTime = currentTime
self.onButtonPress("button", currentButtonState)
# Check for long press while button is held
if currentButtonState and self.buttonPressStartTime > 0:
pressDuration = currentTime - self.buttonPressStartTime
if pressDuration >= self.longPressThreshold:
self.onLongPress()
self.buttonPressStartTime = 0.0 # Reset to prevent repeated triggers
def setLcdTime(self, hours: int, minutes: int):
self.lcd.clear()
# write the time on spanning both rows of the LCD
timeString = f"{hours:02}:{minutes:02}"
self.lcd.write(timeString)
def onButtonPress(self, button: str, state: bool):
print(f"Button '{button}' pressed state: {state}")
currentTime = time()
if button == "button":
if state: # Button pressed down
self.buttonPressStartTime = currentTime
else: # Button released
if self.buttonPressStartTime > 0:
pressDuration = currentTime - self.buttonPressStartTime
self.buttonPressStartTime = 0.0
# Only handle as short press if it wasn't a long press
if pressDuration < self.longPressThreshold:
self.onShortPress()
def onShortPress(self):
"""Handle short button press based on current mode"""
if self.configMode == "normal":
# Normal mode: toggle relay
self.setRelayState(not self.relayGpio.read())
self.setLcdText(f"Relay: {'ON' if self.relayGpio.read() else 'OFF'}")
elif self.configMode == "set_hour":
# Increment hour
self.alarmHour = (self.alarmHour + 1) % 24
self.setLcdText(f"Set Hour: {self.alarmHour:02d}")
elif self.configMode == "set_minute":
# Increment minute
self.alarmMinute = (self.alarmMinute + 1) % 60
self.setLcdText(f"Set Min: {self.alarmMinute:02d}")
def onLongPress(self):
"""Handle long button press - cycle through configuration modes"""
if self.configMode == "normal":
self.configMode = "set_hour"
self.setLcdText(f"Set Hour: {self.alarmHour:02d}")
print(f"Entering hour setting mode")
elif self.configMode == "set_hour":
self.configMode = "set_minute"
self.setLcdText(f"Set Min: {self.alarmMinute:02d}")
print(f"Switching to minute setting mode")
elif self.configMode == "set_minute":
self.configMode = "normal"
self.setLcdText(f"Saved: {self.alarmHour:02d}:{self.alarmMinute:02d}")
print(f"Alarm time saved: {self.alarmHour:02d}:{self.alarmMinute:02d}")
def setLcdText(self, text: str):
self.lcd.clear()
self.lcd.write(text)
print(f"LCD: {text}")
pins = {
"button": 6,
"led": 5,
"buzzer": 12,
}
alarm_clock = AlarmClock(pins)
alarm_clock.start()