Skip to content

Commit

Permalink
Ability to send a warning vibration before the shock alarm goes off
Browse files Browse the repository at this point in the history
  • Loading branch information
Arxari committed Sep 8, 2024
1 parent 03825bb commit 9dd5678
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 75 deletions.
16 changes: 9 additions & 7 deletions static/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -119,26 +119,28 @@ select:focus {
}

.setup-button.glow {
animation: glow 1.5s ease-in-out infinite alternate;
box-shadow:
0 0 5px #ff5c82,
0 0 10px #ff5c82,
0 0 15px #ff5c82;
animation: glow 2s ease-in-out infinite;
}

@keyframes glow {
from {
0% {
box-shadow:
0 0 5px #ff5c82,
0 0 10px #ff5c82,
0 0 15px #ff5c82;
}
to {
50% {
box-shadow:
0 0 10px #ff5c82,
0 0 20px #ff5c82,
0 0 30px #ff5c82;
}
100% {
box-shadow:
0 0 5px #ff5c82,
0 0 10px #ff5c82,
0 0 15px #ff5c82;
}
}

@media screen and (min-width: 768px) {
Expand Down
92 changes: 53 additions & 39 deletions templates/add_alarm.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,50 +3,64 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Add Alarm</title>
<title>Add New Alarm - OpenShockClock</title>
<link
rel="stylesheet"
href="{{ url_for('static', filename='styles.css') }}"
/>
</head>
<body>
<div class="container">
<h1>Add New Alarm</h1>
<form method="post">
<div>
<label for="name">Alarm Name:</label>
<input type="text" name="name" id="name" required />
</div>
<div>
<label for="intensity">Intensity (0-100):</label>
<input
type="number"
name="intensity"
id="intensity"
min="0"
max="100"
required
/>
</div>
<div>
<label for="duration">Duration (seconds):</label>
<input
type="number"
name="duration"
id="duration"
min="0.3"
max="30"
step="0.1"
required
/>
</div>
<div>
<label for="time">Time (HH:MM):</label>
<input type="time" name="time" id="time" required />
</div>
<button type="submit">Save Alarm</button>
</form>
<a href="{{ url_for('index') }}">Back to Home</a>
</div>
<h1>Add New Alarm</h1>
<form method="POST">
<div class="form-group">
<label for="name">Alarm Name:</label>
<input type="text" id="name" name="name" required />
</div>

<div class="form-group">
<label for="intensity">Intensity (0-100):</label>
<input
type="number"
id="intensity"
name="intensity"
min="0"
max="100"
required
/>
</div>

<div class="form-group">
<label for="duration">Duration (seconds):</label>
<input
type="number"
id="duration"
name="duration"
min="0.1"
step="0.1"
required
/>
</div>

<div class="form-group">
<label for="time">Time (HH:MM):</label>
<input type="time" id="time" name="time" required />
</div>

<div class="form-group">
<input
type="checkbox"
id="vibrate_before"
name="vibrate_before"
/>
<label for="vibrate_before"
>Vibrate for 5 seconds at intensity 100, 1 minute before
alarm</label
>
</div>

<button type="submit">Save Alarm</button>
</form>

<a href="{{ url_for('index') }}">Back to Home</a>
</body>
</html>
26 changes: 23 additions & 3 deletions templates/edit_alarm.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Edit Alarm</title>
<title>Edit Alarm - OpenShockClock</title>
<link
rel="stylesheet"
href="{{ url_for('static', filename='styles.css') }}"
Expand All @@ -12,7 +12,10 @@
<body>
<div class="container">
<h1>Edit Alarm</h1>
<form method="POST">
<form
action="{{ url_for('edit_alarm', alarm_name=alarm_name) }}"
method="post"
>
<div class="form-group">
<label for="name">Alarm Name:</label>
<input
Expand Down Expand Up @@ -57,9 +60,26 @@ <h1>Edit Alarm</h1>
required
/>
</div>
<div class="form-group">
<label>
<input
type="checkbox"
id="vibrate_before"
name="vibrate_before"
{%
if
vibrate_before
%}checked{%
endif
%}
/>
Vibrate for 5 seconds at intensity 100, 1 minute before
alarm
</label>
</div>
<button type="submit">Update Alarm</button>
</form>
<a href="{{ url_for('index') }}">Back to Home</a>
<a href="{{ url_for('index') }}" class="button">Back to Home</a>
</div>
</body>
</html>
25 changes: 14 additions & 11 deletions templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -83,22 +83,26 @@ <h3>{{ name }}</h3>
</div>
<p>Intensity: {{ alarm[1] }}</p>
<p>Duration: {{ alarm[2] / 1000 }} seconds</p>
<p>
Vibration: {% if alarm[3] %}On{% else %}Off{% endif %}
</p>
<p>Time Until Shock: <span class="countdown"></span></p>
</div>
{% endfor %}
</div>

<div class="buttons">
<a href="{{ url_for('add_alarm') }}"
><button>Add Alarm</button></a
<button
onclick="window.location.href='{{ url_for('add_alarm') }}'"
>
<a href="{{ url_for('setup') }}">
<button
class="setup-button {% if not env_file_exists %}glow{% endif %}"
>
Setup API and Shocker ID
</button>
</a>
Add Alarm
</button>
<button
onclick="window.location.href='{{ url_for('setup') }}'"
class="setup-button {% if not env_file_exists %}glow{% endif %}"
>
Setup API and Shocker ID
</button>
</div>
</div>

Expand All @@ -120,12 +124,11 @@ <h3>{{ name }}</h3>
const seconds = Math.floor(
(timeDiff % (1000 * 60)) / 1000,
);

alarm.querySelector(".countdown").textContent =
`${hours}h ${minutes}m ${seconds}s`;
} else {
alarm.querySelector(".countdown").textContent =
"Shock!";
"Alarm triggered";
}
});
}
Expand Down
41 changes: 26 additions & 15 deletions webui.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,12 @@ def load_user_config(username):
alarm_time = datetime.strptime(config[section]['time'], '%Y-%m-%d %H:%M:%S')
intensity = int(config[section]['intensity'])
duration = int(config[section]['duration'])
alarms[section] = (alarm_time, intensity, duration)
vibrate_before = config[section].getboolean('vibrate_before', fallback=False)
alarms[section] = (alarm_time, intensity, duration, vibrate_before)
logging.debug(f"Loaded alarms for user {username}: {alarms}")
return alarms

def save_alarm_to_user_config(username, alarm_name, alarm_time, intensity, duration):
def save_alarm_to_user_config(username, alarm_name, alarm_time, intensity, duration, vibrate_before):
"""Saves an alarm to the user's config.txt file."""
user_config_file = os.path.join(USER_DIR, username, 'config.txt')
config = configparser.ConfigParser()
Expand All @@ -47,12 +48,13 @@ def save_alarm_to_user_config(username, alarm_name, alarm_time, intensity, durat
config[alarm_name] = {
'time': alarm_time.strftime('%Y-%m-%d %H:%M:%S'),
'intensity': str(intensity),
'duration': str(duration)
'duration': str(duration),
'vibrate_before': str(vibrate_before)
}

with open(user_config_file, 'w') as configfile:
config.write(configfile)
logging.debug(f"Saved alarm for user {username}: {alarm_name} at {alarm_time}")
logging.debug(f"Saved alarm for user {username}: {alarm_name} at {alarm_time}, vibrate_before: {vibrate_before}")

def load_user_env(username):
"""Loads the API key and Shock ID from the user's .env file."""
Expand All @@ -79,8 +81,8 @@ def save_user_env(username, api_key, shock_id):
config.write(configfile)
logging.debug(f"Saved env for user {username}: API Key: {'*' * len(api_key)}, Shock ID: {shock_id}")

def trigger_shock(api_key, shock_id, intensity, duration):
"""Sends a shock command to the OpenShock API."""
def trigger_shock(api_key, shock_id, intensity, duration, shock_type='Shock'):
"""Sends a shock or vibrate command to the OpenShock API."""
url = 'https://api.shocklink.net/2/shockers/control'
headers = {
'accept': 'application/json',
Expand All @@ -91,7 +93,7 @@ def trigger_shock(api_key, shock_id, intensity, duration):
payload = {
'shocks': [{
'id': shock_id,
'type': 'Shock',
'type': shock_type,
'intensity': intensity,
'duration': duration,
'exclusive': True
Expand All @@ -102,9 +104,9 @@ def trigger_shock(api_key, shock_id, intensity, duration):
try:
response = requests.post(url=url, headers=headers, json=payload)
response.raise_for_status()
logging.info(f"Shock triggered successfully: Intensity {intensity}, Duration {duration}")
logging.info(f"{shock_type} triggered successfully: Intensity {intensity}, Duration {duration}")
except requests.RequestException as e:
logging.error(f"Failed to send shock. Error: {str(e)}")
logging.error(f"Failed to send {shock_type}. Error: {str(e)}")

def update_alarms(username):
"""Updates the alarms for the next day and checks if they need to be triggered."""
Expand All @@ -119,14 +121,18 @@ def update_alarms(username):
continue

now = datetime.now()
for name, (alarm_time, intensity, duration) in list(alarms.items()):
for name, (alarm_time, intensity, duration, vibrate_before) in list(alarms.items()):
if vibrate_before and now >= alarm_time - timedelta(minutes=1) and now < alarm_time:
logging.info(f"Triggering vibration for alarm {name} for user {username}")
trigger_shock(api_key, shock_id, 100, 5000, 'Vibrate')

if now >= alarm_time:
logging.info(f"Triggering alarm {name} for user {username}")
trigger_shock(api_key, shock_id, intensity, duration)

next_alarm_time = alarm_time + timedelta(days=1)
alarms[name] = (next_alarm_time, intensity, duration)
save_alarm_to_user_config(username, name, next_alarm_time, intensity, duration)
alarms[name] = (next_alarm_time, intensity, duration, vibrate_before)
save_alarm_to_user_config(username, name, next_alarm_time, intensity, duration, vibrate_before)
logging.info(f"Updated alarm {name} for user {username} to next day: {next_alarm_time}")

time.sleep(60)
Expand Down Expand Up @@ -175,14 +181,15 @@ def add_alarm():
intensity = int(request.form['intensity'])
duration = int(float(request.form['duration']) * 1000)
time_str = request.form['time']
vibrate_before = 'vibrate_before' in request.form
alarm_time = datetime.strptime(time_str, "%H:%M").replace(
year=datetime.now().year,
month=datetime.now().month,
day=datetime.now().day
)
if alarm_time < datetime.now():
alarm_time += timedelta(days=1)
save_alarm_to_user_config(username, name, alarm_time, intensity, duration)
save_alarm_to_user_config(username, name, alarm_time, intensity, duration, vibrate_before)

start_user_alarm_thread(username)

Expand Down Expand Up @@ -213,6 +220,7 @@ def edit_alarm(alarm_name):
intensity = int(request.form['intensity'])
duration = int(float(request.form['duration']) * 1000)
time_str = request.form['time']
vibrate_before = 'vibrate_before' in request.form
alarm_time = datetime.strptime(time_str, "%H:%M").replace(
year=datetime.now().year,
month=datetime.now().month,
Expand All @@ -226,7 +234,8 @@ def edit_alarm(alarm_name):
config[new_name] = {
'time': alarm_time.strftime('%Y-%m-%d %H:%M:%S'),
'intensity': str(intensity),
'duration': str(duration)
'duration': str(duration),
'vibrate_before': str(vibrate_before)
}

with open(user_config_file, 'w') as configfile:
Expand All @@ -238,11 +247,13 @@ def edit_alarm(alarm_name):
alarm_time = datetime.strptime(config[alarm_name]['time'], '%Y-%m-%d %H:%M:%S')
intensity = config[alarm_name].getint('intensity')
duration = config[alarm_name].getint('duration')
vibrate_before = config[alarm_name].getboolean('vibrate_before', fallback=False)

return render_template('edit_alarm.html', alarm_name=alarm_name,
time=alarm_time.strftime("%H:%M"),
intensity=intensity,
duration=duration/1000)
duration=duration/1000,
vibrate_before=vibrate_before)

@app.route('/delete/<alarm_name>')
def delete_alarm(alarm_name):
Expand Down

0 comments on commit 9dd5678

Please sign in to comment.