Initial commit: Alfred Mobile - AI Assistant Android App
- OAuth authentication via Authentik - WebSocket connection to OpenClaw gateway - Configurable gateway URL with first-run setup - User preferences sync across devices - Multi-user support with custom assistant names - ElevenLabs TTS integration (local + remote) - FCM push notifications for alarms - Voice input via Google Speech API - No hardcoded secrets or internal IPs in tracked files
This commit is contained in:
319
ALARMS.md
Normal file
319
ALARMS.md
Normal file
@@ -0,0 +1,319 @@
|
||||
# Alarm System
|
||||
|
||||
**Critical alarms with repeating sound until dismissed**
|
||||
|
||||
## Overview
|
||||
|
||||
The Alfred mobile app now supports alarms - notifications that play a sound on repeat and require explicit dismissal. Unlike regular notifications that auto-dismiss, alarms are designed for time-critical events you cannot miss.
|
||||
|
||||
## Features
|
||||
|
||||
### 🔔 Repeating Sound
|
||||
- Uses system alarm ringtone (same sound as your device's alarm clock)
|
||||
- Loops continuously until dismissed
|
||||
- Full volume (respects system alarm volume)
|
||||
|
||||
### 📳 Repeating Vibration
|
||||
- Vibration pattern: 500ms on, 500ms off, repeating
|
||||
- Loops continuously until dismissed
|
||||
- Can be disabled with `--no-vibrate` flag
|
||||
|
||||
### 🔒 Persistent Notification
|
||||
- System notification stays visible until dismissed
|
||||
- Cannot auto-dismiss (requires user action)
|
||||
- Marked with ⏰ icon and "ALARM" prefix
|
||||
|
||||
### ✅ Manual Dismissal
|
||||
- Say "dismiss alarm" or "dismiss alert" in chat
|
||||
- Alarm stops immediately
|
||||
- Notification clears
|
||||
|
||||
## Usage
|
||||
|
||||
### Scheduled Alarms
|
||||
|
||||
```bash
|
||||
# Morning medication at 8am
|
||||
mobile-notify alarm "08:00" "Take morning medication" --title "Health"
|
||||
|
||||
# Doctor appointment tomorrow
|
||||
mobile-notify alarm "tomorrow 14:30" "Doctor appointment in 10 minutes"
|
||||
|
||||
# Critical meeting
|
||||
mobile-notify alarm "2026-02-10 09:00" "Team standup starts now!"
|
||||
```
|
||||
|
||||
### Instant Alarms
|
||||
|
||||
For immediate alarms (rare), use the `--alarm` flag with `alert`:
|
||||
|
||||
```bash
|
||||
mobile-notify alert "Emergency alert!" --alarm --title "URGENT"
|
||||
```
|
||||
|
||||
### From Alfred
|
||||
|
||||
When you ask Alfred to set a reminder, I'll ask if you want a notification or alarm if it's not clear:
|
||||
|
||||
**User:** "Remind me to take my medication at 8am tomorrow"
|
||||
|
||||
**Alfred:** "Would you like a regular notification, or an alarm (repeating sound until dismissed)?"
|
||||
|
||||
**User:** "Alarm please, I can't miss this"
|
||||
|
||||
**Alfred:** ✅ *Sets alarm*
|
||||
|
||||
```bash
|
||||
exec(['mobile-notify', 'alarm', 'tomorrow 08:00', 'Take morning medication', '--title', 'Health'])
|
||||
```
|
||||
|
||||
## When to Use Alarms vs Notifications
|
||||
|
||||
### Use Alarms For:
|
||||
- ✅ Medication reminders
|
||||
- ✅ Critical appointments (doctor, dentist, etc.)
|
||||
- ✅ Important meetings you can't miss
|
||||
- ✅ Wake-up alarms
|
||||
- ✅ Time-sensitive tasks
|
||||
- ✅ Emergency alerts
|
||||
|
||||
### Use Notifications For:
|
||||
- ✅ General reminders
|
||||
- ✅ Informational alerts
|
||||
- ✅ Task completion notices
|
||||
- ✅ Non-urgent events
|
||||
- ✅ Daily routines
|
||||
|
||||
## Dismissing Alarms
|
||||
|
||||
### In-App Dismissal
|
||||
|
||||
Type or say any of these:
|
||||
- "dismiss alarm"
|
||||
- "dismiss alert"
|
||||
- "dismiss the alarm"
|
||||
- "stop alarm"
|
||||
- "stop the alarm"
|
||||
|
||||
The app automatically detects these phrases and dismisses all active alarms.
|
||||
|
||||
### Notification Dismissal
|
||||
|
||||
Currently, you can only dismiss alarms via the app (by saying "dismiss alarm"). Future updates will add a dismiss button in the notification itself.
|
||||
|
||||
## Technical Details
|
||||
|
||||
### AlarmManager Component
|
||||
|
||||
Located at `app/src/main/java/com/openclaw/alfred/alarm/AlarmManager.kt`
|
||||
|
||||
**Key methods:**
|
||||
- `startAlarm()` - Begin alarm with repeating sound/vibration
|
||||
- `dismissAlarm()` - Stop specific alarm
|
||||
- `dismissAll()` - Stop all active alarms
|
||||
- `destroy()` - Cleanup on app close
|
||||
|
||||
**Sound playback:**
|
||||
- Uses `MediaPlayer` with alarm audio attributes
|
||||
- Loops via `isLooping = true`
|
||||
- Uses `RingtoneManager.TYPE_ALARM` sound
|
||||
|
||||
**Vibration:**
|
||||
- Uses `VibrationEffect.createWaveform()` with repeating pattern
|
||||
- Pattern: [0ms delay, 500ms vibrate, 500ms pause, repeat]
|
||||
- Requires `android.permission.VIBRATE`
|
||||
|
||||
### CLI Tool Updates
|
||||
|
||||
**New command:**
|
||||
```bash
|
||||
mobile-notify alarm "TIME" "MESSAGE" [options]
|
||||
```
|
||||
|
||||
**New flag:**
|
||||
```bash
|
||||
mobile-notify alert "MESSAGE" --alarm [options]
|
||||
```
|
||||
|
||||
### Event Format
|
||||
|
||||
WebSocket events for alarms:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "event",
|
||||
"event": "mobile.notification",
|
||||
"payload": {
|
||||
"notificationType": "alarm",
|
||||
"title": "Health",
|
||||
"message": "Take morning medication",
|
||||
"priority": "default",
|
||||
"sound": true,
|
||||
"vibrate": true,
|
||||
"timestamp": 1706918400000
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### UI Behavior
|
||||
|
||||
**When alarm is received:**
|
||||
|
||||
1. **Foreground:**
|
||||
- Alarm sound starts looping
|
||||
- Vibration starts looping
|
||||
- Message added to chat: "🔔 ALARM: [message] (Say 'dismiss alarm' to stop)"
|
||||
- Persistent notification shown
|
||||
|
||||
2. **Background:**
|
||||
- Alarm sound starts looping
|
||||
- Vibration starts looping
|
||||
- Persistent notification shown
|
||||
- User must open app to dismiss
|
||||
|
||||
## Examples
|
||||
|
||||
### Medication Reminder
|
||||
|
||||
```bash
|
||||
# Set alarm for 8am daily medication
|
||||
mobile-notify alarm "08:00" "Take your morning medication" --title "Health"
|
||||
```
|
||||
|
||||
**Result:**
|
||||
- At 8:00 AM, alarm sound plays on repeat
|
||||
- Persistent notification: "⏰ ALARM: Health - Take your morning medication"
|
||||
- User must say "dismiss alarm" to stop
|
||||
|
||||
### Important Meeting
|
||||
|
||||
```bash
|
||||
# Alarm 5 minutes before critical meeting
|
||||
mobile-notify alarm "14:55" "Sprint planning starts in 5 minutes" --title "Calendar"
|
||||
```
|
||||
|
||||
### Wake-Up Alarm
|
||||
|
||||
```bash
|
||||
# Wake up alarm for tomorrow
|
||||
mobile-notify alarm "tomorrow 07:00" "Good morning! Time to wake up" --title "Wake Up"
|
||||
```
|
||||
|
||||
### Emergency Alert
|
||||
|
||||
```bash
|
||||
# Immediate emergency alarm
|
||||
mobile-notify alert "Server is down! Check immediately!" --alarm --title "EMERGENCY" --priority high
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### Custom Alarm Sound
|
||||
|
||||
Currently uses the system's default alarm sound. To customize in the future, modify `AlarmManager.kt`:
|
||||
|
||||
```kotlin
|
||||
val alarmUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM)
|
||||
// Replace with: Uri.parse("android.resource://" + context.packageName + "/" + R.raw.custom_alarm)
|
||||
```
|
||||
|
||||
### Volume
|
||||
|
||||
Alarms respect the system's alarm volume setting (not media volume). Users control volume via:
|
||||
- Volume buttons (when on alarm screen)
|
||||
- Settings → Sound → Alarm volume
|
||||
|
||||
### Vibration Pattern
|
||||
|
||||
Default pattern: 500ms on, 500ms off
|
||||
|
||||
To customize, edit `AlarmManager.kt`:
|
||||
|
||||
```kotlin
|
||||
val pattern = longArrayOf(0, 500, 500) // [delay, vibrate, pause]
|
||||
```
|
||||
|
||||
## Permissions
|
||||
|
||||
Required permissions (already declared in `AndroidManifest.xml`):
|
||||
|
||||
- `android.permission.VIBRATE` - For alarm vibration
|
||||
- `android.permission.POST_NOTIFICATIONS` - For showing notifications (Android 13+)
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Alarm sound not playing
|
||||
|
||||
**Possible causes:**
|
||||
- Alarm volume is muted (check Settings → Sound)
|
||||
- Do Not Disturb mode is enabled
|
||||
- Device is in silent mode
|
||||
|
||||
**Solution:**
|
||||
- Check system alarm volume
|
||||
- Disable Do Not Disturb
|
||||
- Ensure alarm volume is not muted
|
||||
|
||||
### Alarm not stopping
|
||||
|
||||
**Symptom:** Alarm keeps playing after saying "dismiss alarm"
|
||||
|
||||
**Solution:**
|
||||
- Make sure text is sent (not just voice input canceled)
|
||||
- Try typing "dismiss alarm" manually
|
||||
- Force-close and reopen app if stuck
|
||||
|
||||
### Vibration not working
|
||||
|
||||
**Possible causes:**
|
||||
- Device doesn't support vibration (emulators)
|
||||
- Vibration disabled in settings
|
||||
|
||||
**Solution:**
|
||||
- Test on physical device
|
||||
- Check Settings → Accessibility → Vibration
|
||||
|
||||
### Notification not showing
|
||||
|
||||
**Possible causes:**
|
||||
- Notification permissions denied (Android 13+)
|
||||
- App notifications disabled in system settings
|
||||
|
||||
**Solution:**
|
||||
- Settings → Apps → Alfred → Notifications → Allow
|
||||
- Grant notification permission when prompted
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
Planned improvements:
|
||||
|
||||
- [ ] **Dismiss button in notification** - Tap to dismiss without opening app
|
||||
- [ ] **Snooze functionality** - Delay alarm by X minutes
|
||||
- [ ] **Custom alarm sounds** - Choose from device sounds or upload custom
|
||||
- [ ] **Escalating volume** - Start quiet, gradually increase
|
||||
- [ ] **Smart silence** - Auto-stop after X minutes (safety)
|
||||
- [ ] **Multiple alarms** - Track and dismiss individually
|
||||
- [ ] **Alarm history** - See past alarms and when dismissed
|
||||
- [ ] **Quick alarm presets** - Common alarms with one tap
|
||||
|
||||
## Best Practices
|
||||
|
||||
### For Users
|
||||
|
||||
1. **Use alarms sparingly** - Reserve for truly important events
|
||||
2. **Dismiss promptly** - Don't let alarms loop unnecessarily
|
||||
3. **Test first** - Try a test alarm to ensure sound/vibration work
|
||||
4. **Check volume** - Verify alarm volume is audible before critical alarms
|
||||
5. **Battery considerations** - Alarms drain battery if left running
|
||||
|
||||
### For Alfred
|
||||
|
||||
1. **Ask when uncertain** - If user doesn't specify, ask "notification or alarm?"
|
||||
2. **Default to notifications** - Only use alarms when appropriate
|
||||
3. **Be explicit** - Tell user it's an alarm ("I've set an alarm...")
|
||||
4. **Mention dismissal** - Remind user how to dismiss ("Say 'dismiss alarm' to stop")
|
||||
5. **Confirm critical alarms** - "I've set an alarm for your medication at 8am tomorrow. It will repeat until you dismiss it."
|
||||
|
||||
## Version
|
||||
|
||||
1.0.0 - Initial alarm system (February 2026)
|
||||
Reference in New Issue
Block a user