diff --git a/README.md b/README.md
index d593bf9..a4d8eb4 100644
--- a/README.md
+++ b/README.md
@@ -13,6 +13,6 @@ Discuss it on [Discord](https://discord.gg/u9vq7QE) or at [Home Assistant commun
#### Last release build status
[](https://codemagic.io/apps/5da8bdab9f20ef798f7c2c65/5db1862025dc3f0b0288a57a/latest_build)
-#### Special thanks to
-- [Crewski](https://github.com/Crewski) for his [HANotify](https://github.com/Crewski/HANotify)
-- [Home Assistant](https://github.com/home-assistant) for some support and [Home Assistant](https://www.home-assistant.io/)
\ No newline at end of file
+#### Projects used
+- [HANotify](https://github.com/Crewski/HANotify) by [Crewski](https://github.com/Crewski)
+- [hassalarm](https://github.com/Johboh/hassalarm) by [Johboh](https://github.com/Johboh)
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 01a8a2b..f695715 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -62,7 +62,12 @@
-
+
+
+
+
+
+
= 23) {
+ alarmManager = context.getSystemService(AlarmManager.class);
+ } else {
+ alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
+ }
+
+ final AlarmManager.AlarmClockInfo alarmClockInfo = alarmManager.getNextAlarmClock();
+
+ SharedPreferences prefs = context.getSharedPreferences("FlutterSharedPreferences", Context.MODE_PRIVATE);
+ String webhookId = prefs.getString("flutter.app-webhook-id", null);
+ if (webhookId != null) {
+ try {
+ String requestUrl = prefs.getString("flutter.hassio-res-protocol", "") +
+ "://" +
+ prefs.getString("flutter.hassio-domain", "") +
+ ":" +
+ prefs.getString("flutter.hassio-port", "") + "/api/webhook/" + webhookId;
+ JSONObject dataToSend = new JSONObject();
+ if (URLUtil.isValidUrl(requestUrl)) {
+ final String state;
+ final long triggerTimestamp;
+ if (alarmClockInfo != null) {
+ triggerTimestamp = alarmClockInfo.getTriggerTime();
+ final Calendar calendar = Calendar.getInstance();
+ calendar.setTimeInMillis(triggerTimestamp);
+ state = DATE_FORMAT_LEGACY.format(calendar.getTime());
+ } else {
+ state = "";
+ }
+ Log.d(TAG, "Setting time to " + state);
+ dataToSend.put("type", "update_sensor_states");
+ JSONArray dataArray = new JSONArray();
+ JSONObject sensorData = new JSONObject();
+ sensorData.put("unique_id", "next_alarm");
+ sensorData.put("type", "sensor");
+ sensorData.put("state", state); //TEST DATA
+ dataArray.put(0, sensorData);
+ dataToSend.put("data", dataArray);
+
+ String stringRequest = dataToSend.toString();
+ SendTask sendTask = new SendTask();
+ sendTask.execute(requestUrl, stringRequest);
+ } else {
+ Log.w(TAG, "Invalid HA url");
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Error setting next alarm", e);
+ }
+ } else {
+ Log.w(TAG, "Webhook id not found");
+ }
+ }
+}
\ No newline at end of file
diff --git a/android/app/src/main/java/com/keyboardcrumbs/hassclient/NotificationActionReceiver.java b/android/app/src/main/java/com/keyboardcrumbs/hassclient/NotificationActionReceiver.java
index bc04126..ef23b80 100644
--- a/android/app/src/main/java/com/keyboardcrumbs/hassclient/NotificationActionReceiver.java
+++ b/android/app/src/main/java/com/keyboardcrumbs/hassclient/NotificationActionReceiver.java
@@ -1,7 +1,7 @@
package com.keyboardcrumbs.hassclient;
+import android.app.AlarmManager;
import android.content.Context;
-import androidx.annotation.NonNull;
import android.util.Log;
import android.content.BroadcastReceiver;
import android.content.Intent;
@@ -19,6 +19,10 @@ public class NotificationActionReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
+ if (intent == null) {
+ return;
+ }
+
String rawActionData = intent.getStringExtra("actionData");
if (intent.hasExtra("tag")) {
String notificationTag = intent.getStringExtra("tag");
diff --git a/lib/managers/app_settings.dart b/lib/managers/app_settings.dart
index 181b761..5d0e9d6 100644
--- a/lib/managers/app_settings.dart
+++ b/lib/managers/app_settings.dart
@@ -28,6 +28,7 @@ class AppSettings {
String webhookId;
double haVersion;
bool scrollBadges;
+ bool nextAlarmSensorCreated = false;
DisplayMode displayMode;
AppTheme appTheme;
final int defaultLocationUpdateIntervalMinutes = 20;
@@ -61,6 +62,7 @@ class AppSettings {
locationUpdateInterval = Duration(minutes: prefs.getInt("location-interval") ??
defaultLocationUpdateIntervalMinutes);
locationTrackingEnabled = prefs.getBool("location-enabled") ?? false;
+ nextAlarmSensorCreated = prefs.getBool("next-alarm-sensor-created") ?? false;
longLivedToken = Hive.box(DEFAULT_HIVE_BOX).get(AUTH_TOKEN_KEY);
oauthUrl = "$httpWebHost/auth/authorize?client_id=${Uri.encodeComponent(
'https://ha-client.app')}&redirect_uri=${Uri
diff --git a/lib/managers/mobile_app_integration_manager.class.dart b/lib/managers/mobile_app_integration_manager.class.dart
index a1b0c0f..372139a 100644
--- a/lib/managers/mobile_app_integration_manager.class.dart
+++ b/lib/managers/mobile_app_integration_manager.class.dart
@@ -62,12 +62,13 @@ class MobileAppIntegrationManager {
includeAuthHeader: true,
data: json.encode(registrationData)
).then((response) {
- Logger.d("Processing registration responce...");
+ Logger.d("Processing registration response...");
var responseObject = json.decode(response);
AppSettings().webhookId = responseObject["webhook_id"];
AppSettings().save({
'app-webhook-id': responseObject["webhook_id"]
- }).then((prefs) {
+ }).then((_) {
+ _createNextAlarmSensor(true);
completer.complete();
eventBus.fire(ShowPopupEvent(
popup: Popup(
@@ -112,6 +113,7 @@ class MobileAppIntegrationManager {
_askToRegisterApp();
} else {
Logger.d('App registration works fine');
+ _createNextAlarmSensor(false);
}
completer.complete();
}).catchError((e) {
@@ -131,6 +133,42 @@ class MobileAppIntegrationManager {
return completer.future;
}
+ static _createNextAlarmSensor(bool force) {
+ if (AppSettings().nextAlarmSensorCreated && !force) {
+ Logger.d("Next alarm sensor was previously created");
+ return;
+ }
+ Logger.d("Creating next alarm sensor...");
+ ConnectionManager().sendHTTPPost(
+ endPoint: "/api/webhook/${AppSettings().webhookId}",
+ includeAuthHeader: false,
+ data: json.encode(
+ {
+ "data": {
+ "device_class": "timestamp",
+ "icon": "mdi:alarm",
+ "name": "Next Alarm",
+ "state": "",
+ "type": "sensor",
+ "unique_id": "next_alarm"
+ },
+ "type": "register_sensor"
+ }
+ )
+ ).then((_){
+ AppSettings().nextAlarmSensorCreated = true;
+ AppSettings().save({
+ 'next-alarm-sensor-created': true
+ });
+ }).catchError((e) {
+ if (e is http.Response) {
+ Logger.e("Error creating next alarm sensor: ${e.statusCode}: ${e.body}");
+ } else {
+ Logger.e("Error creating next alarm sensor: ${e?.toString()}");
+ }
+ });
+ }
+
static void _showError() {
eventBus.fire(ShowPopupEvent(
popup: Popup(