I have the following Java class that I want to port (in concept) to python.
The idea is that you have an alarm Thread that sleeps for x seconds (until the next morning) unless a new wakeup time is set, at which point the sleeping Thread is interrupted, the new time remaining is set and it sleeps for that time. If it completes the sleep, it triggers the alarm sound and wait for a new wakeup time to be set
I want to port this to Python but I just spent a few hours googling and while there are 1001 ways to manage threads and sleeping in Python, I cannot find how to sleep() for x seconds but also send an interrupt.
To be clear, I don't need someone to write the whole class for me, just a simple example of sleep and interrupt is enough so that I understand the way it is done in Python.
package com.njitram.bedroomtunes.server.alarm;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import com.njitram.bedroomtunes.log.Logger;
public class AlarmThread extends Thread {
private Calendar wakeupTime;
private Alarm alarm;
/*
* Constructor to disable the alarm
*/
public AlarmThread(Alarm alarm) {
this(null, alarm);
}
public AlarmThread(Calendar wakeupTime, Alarm alarm) {
this.alarm = alarm;
if(wakeupTime == null) {
disable();
} else {
setNewWakeUpTime(wakeupTime);
}
this.start();
}
public void setNewWakeUpTime(Calendar wakeupTime) {
Logger.log("New Wake time set for AlarmThread: " + new SimpleDateFormat("dd-MM-yyyy HH:mm:ss").format(wakeupTime.getTime()));
this.wakeupTime = wakeupTime;
// If the thread was already started, it will be sleeping. Wake it up and recalculate how long it needs to sleep. Interrupting will achieve this.
this.interrupt();
}
public void disable() {
setNewWakeUpTime(getDisabledTime());
}
private Calendar getDisabledTime() {
// The idea is to disable the alarm. If the alarm eventually goes off in the year 3000, I deserve to wake up...
Calendar wakeupTime = Calendar.getInstance();
wakeupTime.set(Calendar.YEAR, 3000);
return wakeupTime;
}
@Override
public void run() {
while(true) {
try {
long sleepTime = getSleepTime();
Logger.log("Sleeping for "+sleepTime);
// Sleep until it is time for the alarm to go off. This can be interrupted if a new wakeUpTime is set
Thread.sleep(sleepTime);
// After sleeping, wake up
wakeUp();
// Wait for the new time to be set and the alarm to send an interrupt to continue the thread
synchronized(this) {
wait();
}
} catch (InterruptedException e) {
Logger.log("Interrupted");
/* The thread can be interrupted when a new wake-up time has been set */
}
}
}
private long getSleepTime() {
return wakeupTime.getTimeInMillis() - Calendar.getInstance().getTimeInMillis();
}
private void wakeUp() {
alarm.wakeUp();
}
}
The APScheduler package seems to provide the functionality you are looking for. The user guide should have information on all the functions you need to set and remove schedules.
Note that this works differently to your sleeping method by using scheduling instead - though I advise against 'busy sleeping' anyway as it wastes CPU cycles