mirror of
https://git.wetfence.xyz/RandyTheSilly/Trigalarm.git
synced 2026-08-27 22:26:25 -04:00
Add alarm reset button to phone-side settings
This commit is contained in:
@@ -13,6 +13,7 @@ Perhaps the most unique, Trigalarm features optional [Pavlok](https://pavlok.com
|
||||
|
||||
## Tips & Tricks
|
||||
- When you successfully disarm the alarm, you are prompted with the options to either exit and keep the same alarm time for tomorrow, or to select a new time. If choosing the latter, whatever time you select will assume you mean tomorrow. This avoids situations where you wake up at 6 on a Friday, set an alarm intended for 9 on Saturday, and end up with your wrist buzzing in three hours!
|
||||
- If you are stuck waiting for an awareness alarm or there is a bug that schedules an alarm incorrectly, there is a "Reset Alarm" button in the phone-side settings that will set your alarm to 00:00.
|
||||
|
||||
## Some Neat Stuff
|
||||
- The vibration pattern is randomized. It derives the length of the three pulses from the angles in the generated triangle. Neat!
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
},
|
||||
"messageKeys": [
|
||||
"PKJS_READY",
|
||||
"PKJS_ALARM_RESET",
|
||||
"PKJS_PAVLOK_ENABLE",
|
||||
"PKJS_PAVLOK_ZAP_MIN",
|
||||
"PKJS_PAVLOK_ZAP_STEP",
|
||||
|
||||
+59
-49
@@ -182,54 +182,6 @@ static void push_status_window(StatusWindowPurpose purpose) {
|
||||
window_stack_push(s_status_window, true);
|
||||
}
|
||||
|
||||
////////////////////// PKJS //////////////////////
|
||||
|
||||
static void apply_uint8_from_tuple(DictionaryIterator *iter, uint32_t key, void *dest) {
|
||||
Tuple *t = dict_find(iter, key);
|
||||
if (!t)
|
||||
return;
|
||||
*(uint8_t *)dest = t->value->uint8;
|
||||
}
|
||||
|
||||
static void inbox_received_handler(DictionaryIterator *iter, void *context) {
|
||||
Tuple *ready_tuple = dict_find(iter, MESSAGE_KEY_PKJS_READY);
|
||||
if (ready_tuple) {
|
||||
return;
|
||||
}
|
||||
apply_uint8_from_tuple(iter, MESSAGE_KEY_PKJS_PAVLOK_ENABLE, &settings.PavlokEnabled);
|
||||
apply_uint8_from_tuple(iter, MESSAGE_KEY_PKJS_PAVLOK_ZAP_INTERVAL, &settings.PavlokIntervalSeconds);
|
||||
apply_uint8_from_tuple(iter, MESSAGE_KEY_PKJS_PAVLOK_ZAP_MIN, &settings.PavlokMin);
|
||||
apply_uint8_from_tuple(iter, MESSAGE_KEY_PKJS_PAVLOK_ZAP_STEP, &settings.PavlokStep);
|
||||
apply_uint8_from_tuple(iter, MESSAGE_KEY_PKJS_PAVLOK_ZAP_MAX, &settings.PavlokMax);
|
||||
apply_uint8_from_tuple(iter, MESSAGE_KEY_PKJS_AWARENESS_TIME_GAP, &settings.AwarenessTimeGapMinutes);
|
||||
apply_uint8_from_tuple(iter, MESSAGE_KEY_PKJS_AWARENESS_TIME_LIMIT, &settings.AwarenessTimeLimitSeconds);
|
||||
if (settings.PavlokStep == 0) {
|
||||
// match min and max values if disabling step mode, as the max is used for force exit/overwrite punishments
|
||||
settings.PavlokMax = settings.PavlokMin;
|
||||
} else if (settings.PavlokMax <= settings.PavlokMin) {
|
||||
// disable step mode if max is not higher than min
|
||||
settings.PavlokStep = 0;
|
||||
}
|
||||
persist_write_data(STORAGE_KEY_SETTINGS, &settings, sizeof(settings));
|
||||
}
|
||||
|
||||
static void send_zap(uint8_t intensity) {
|
||||
if (!settings.PavlokEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
DictionaryIterator *out;
|
||||
AppMessageResult result = app_message_outbox_begin(&out);
|
||||
if (result != APP_MSG_OK) {
|
||||
return;
|
||||
}
|
||||
dict_write_uint8(out, MESSAGE_KEY_PKJS_PAVLOK_ZAP, intensity);
|
||||
result = app_message_outbox_send();
|
||||
if (result != APP_MSG_OK) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////// MISC //////////////////////
|
||||
|
||||
static time_t compute_alarm_time(uint8_t hour, uint8_t minute) {
|
||||
@@ -317,6 +269,64 @@ static void add_bar_layers_to_window(Layer *window_layer, bool small_top) {
|
||||
layer_add_child(window_layer, s_bottom_bar_layer);
|
||||
}
|
||||
|
||||
////////////////////// PKJS //////////////////////
|
||||
|
||||
static void apply_uint8_from_tuple(DictionaryIterator *iter, uint32_t key, void *dest) {
|
||||
Tuple *t = dict_find(iter, key);
|
||||
if (!t)
|
||||
return;
|
||||
*(uint8_t *)dest = t->value->uint8;
|
||||
}
|
||||
|
||||
static void inbox_received_handler(DictionaryIterator *iter, void *context) {
|
||||
Tuple *ready_tuple = dict_find(iter, MESSAGE_KEY_PKJS_READY);
|
||||
if (ready_tuple) {
|
||||
return;
|
||||
}
|
||||
|
||||
// handle alarm reset requests
|
||||
if (dict_find(iter, MESSAGE_KEY_PKJS_ALARM_RESET)) {
|
||||
the_time.HourWIP = 0;
|
||||
the_time.MinuteWIP = 0;
|
||||
s_alarm_reason = WAKE_MAIN_ALARM;
|
||||
schedule_alarm(WAKE_MAIN_ALARM);
|
||||
return;
|
||||
}
|
||||
|
||||
apply_uint8_from_tuple(iter, MESSAGE_KEY_PKJS_PAVLOK_ENABLE, &settings.PavlokEnabled);
|
||||
apply_uint8_from_tuple(iter, MESSAGE_KEY_PKJS_PAVLOK_ZAP_INTERVAL, &settings.PavlokIntervalSeconds);
|
||||
apply_uint8_from_tuple(iter, MESSAGE_KEY_PKJS_PAVLOK_ZAP_MIN, &settings.PavlokMin);
|
||||
apply_uint8_from_tuple(iter, MESSAGE_KEY_PKJS_PAVLOK_ZAP_STEP, &settings.PavlokStep);
|
||||
apply_uint8_from_tuple(iter, MESSAGE_KEY_PKJS_PAVLOK_ZAP_MAX, &settings.PavlokMax);
|
||||
apply_uint8_from_tuple(iter, MESSAGE_KEY_PKJS_AWARENESS_TIME_GAP, &settings.AwarenessTimeGapMinutes);
|
||||
apply_uint8_from_tuple(iter, MESSAGE_KEY_PKJS_AWARENESS_TIME_LIMIT, &settings.AwarenessTimeLimitSeconds);
|
||||
if (settings.PavlokStep == 0) {
|
||||
// match min and max values if disabling step mode, as the max is used for force exit/overwrite punishments
|
||||
settings.PavlokMax = settings.PavlokMin;
|
||||
} else if (settings.PavlokMax <= settings.PavlokMin) {
|
||||
// disable step mode if max is not higher than min
|
||||
settings.PavlokStep = 0;
|
||||
}
|
||||
persist_write_data(STORAGE_KEY_SETTINGS, &settings, sizeof(settings));
|
||||
}
|
||||
|
||||
static void send_zap(uint8_t intensity) {
|
||||
if (!settings.PavlokEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
DictionaryIterator *out;
|
||||
AppMessageResult result = app_message_outbox_begin(&out);
|
||||
if (result != APP_MSG_OK) {
|
||||
return;
|
||||
}
|
||||
dict_write_uint8(out, MESSAGE_KEY_PKJS_PAVLOK_ZAP, intensity);
|
||||
result = app_message_outbox_send();
|
||||
if (result != APP_MSG_OK) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////// ALARM //////////////////////
|
||||
|
||||
static void main_alarm_seconds_handler(struct tm *tick_time, TimeUnits units_changed) {
|
||||
@@ -1047,7 +1057,7 @@ static void init() {
|
||||
|
||||
// initialize pkjs
|
||||
app_message_register_inbox_received(inbox_received_handler);
|
||||
app_message_open(64, 64); // TODO tighten sizes
|
||||
app_message_open(128, 128); // TODO tighten sizes
|
||||
|
||||
// load settings from persist (or set defaults if not present)
|
||||
if (persist_exists(STORAGE_KEY_SETTINGS)) {
|
||||
|
||||
+5
-1
@@ -29,7 +29,6 @@ module.exports = [
|
||||
{
|
||||
"id": "pavlok_test_beep",
|
||||
"type": "button",
|
||||
"messageKey": "PKJS_PAVLOK_TEST_BEEP",
|
||||
"defaultValue": "Test API Key w/Beep"
|
||||
},
|
||||
{
|
||||
@@ -108,6 +107,11 @@ module.exports = [
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "alarm_reset",
|
||||
"type": "button",
|
||||
"defaultValue": "Reset Alarm"
|
||||
},
|
||||
{
|
||||
"type": "submit",
|
||||
"defaultValue": "Save Settings"
|
||||
|
||||
@@ -39,11 +39,17 @@ module.exports = function (minified) {
|
||||
xhr.send(data);
|
||||
}
|
||||
|
||||
function sendResetSignal() {
|
||||
window.location = 'pebblejs://close#' +
|
||||
encodeURIComponent(JSON.stringify({ resetAlarm: 1 }));
|
||||
}
|
||||
|
||||
clayConfig.on(clayConfig.EVENTS.AFTER_BUILD, function () {
|
||||
var pavlokIntegrationToggle = clayConfig.getItemById('pavlok_enable');
|
||||
togglePavlokIntegration.call(pavlokIntegrationToggle);
|
||||
pavlokIntegrationToggle.on('change', togglePavlokIntegration);
|
||||
|
||||
clayConfig.getItemById('pavlok_test_beep').on('click', sendTestBeep);
|
||||
clayConfig.getItemById('alarm_reset').on('click', sendResetSignal);
|
||||
});
|
||||
};
|
||||
|
||||
+31
-1
@@ -2,7 +2,37 @@ var Clay = require('@rebble/clay');
|
||||
var clayConfig = require('./config');
|
||||
var customClay = require('./customClay');
|
||||
|
||||
new Clay(clayConfig, customClay);
|
||||
var clay = new Clay(clayConfig, customClay, { autoHandleEvents: false });
|
||||
|
||||
Pebble.addEventListener('showConfiguration', function () {
|
||||
Pebble.openURL(clay.generateUrl());
|
||||
});
|
||||
|
||||
// custom listener so messages can be sent from customClay.js
|
||||
Pebble.addEventListener('webviewclosed', function(e) {
|
||||
if (e && !e.response) {
|
||||
return;
|
||||
}
|
||||
|
||||
var data;
|
||||
try {
|
||||
data = JSON.parse(e.response.match(/^\{/) ? e.response : decodeURIComponent(e.response));
|
||||
} catch (err) {
|
||||
return;
|
||||
}
|
||||
if (data.resetAlarm) {
|
||||
Pebble.sendAppMessage({ PKJS_ALARM_RESET: 1 });
|
||||
return;
|
||||
}
|
||||
|
||||
var dict = clay.getSettings(e.response);
|
||||
Pebble.sendAppMessage(dict, function(e) {
|
||||
console.log('Sent config data to Pebble');
|
||||
}, function(e) {
|
||||
console.log('Failed to send config data!');
|
||||
console.log(JSON.stringify(e));
|
||||
});
|
||||
});
|
||||
|
||||
Pebble.addEventListener("ready", function () {
|
||||
Pebble.sendAppMessage({ PKJS_READY: 1 });
|
||||
|
||||
Reference in New Issue
Block a user