Resloves #570 Next Android alarm as sensor

This commit is contained in:
estevez-dev 2020-06-22 22:30:51 +03:00
parent d09afc37b5
commit 7683d18e81
6 changed files with 145 additions and 7 deletions

View File

@ -13,6 +13,6 @@ Discuss it on [Discord](https://discord.gg/u9vq7QE) or at [Home Assistant commun
#### Last release build status #### Last release build status
[![Codemagic build status](https://api.codemagic.io/apps/5da8bdab9f20ef798f7c2c65/5db1862025dc3f0b0288a57a/status_badge.svg)](https://codemagic.io/apps/5da8bdab9f20ef798f7c2c65/5db1862025dc3f0b0288a57a/latest_build) [![Codemagic build status](https://api.codemagic.io/apps/5da8bdab9f20ef798f7c2c65/5db1862025dc3f0b0288a57a/status_badge.svg)](https://codemagic.io/apps/5da8bdab9f20ef798f7c2c65/5db1862025dc3f0b0288a57a/latest_build)
#### Special thanks to #### Projects used
- [Crewski](https://github.com/Crewski) for his [HANotify](https://github.com/Crewski/HANotify) - [HANotify](https://github.com/Crewski/HANotify) by [Crewski](https://github.com/Crewski)
- [Home Assistant](https://github.com/home-assistant) for some support and [Home Assistant](https://www.home-assistant.io/) - [hassalarm](https://github.com/Johboh/hassalarm) by [Johboh](https://github.com/Johboh)

View File

@ -62,7 +62,12 @@
<action android:name="android.intent.action.INPUT_METHOD_CHANGED" /> <action android:name="android.intent.action.INPUT_METHOD_CHANGED" />
</intent-filter> </intent-filter>
</receiver> </receiver>
<receiver android:name=".NextAlarmBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.app.action.NEXT_ALARM_CLOCK_CHANGED" />
</intent-filter>
</receiver>
<service <service
android:name="io.flutter.plugins.androidalarmmanager.AlarmService" android:name="io.flutter.plugins.androidalarmmanager.AlarmService"
android:permission="android.permission.BIND_JOB_SERVICE" android:permission="android.permission.BIND_JOB_SERVICE"

View File

@ -0,0 +1,89 @@
package com.keyboardcrumbs.hassclient;
import android.app.AlarmManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.webkit.URLUtil;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;
import org.json.JSONArray;
import org.json.JSONObject;
import android.content.SharedPreferences;
public class NextAlarmBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "NextAlarmReceiver";
private static final SimpleDateFormat DATE_FORMAT_LEGACY = new SimpleDateFormat("yyyy-MM-dd HH:mm:00", Locale.ENGLISH);
@Override
public void onReceive(Context context, Intent intent) {
if (intent == null) {
return;
}
final boolean isBootIntent = Intent.ACTION_BOOT_COMPLETED.equalsIgnoreCase(intent.getAction());
final boolean isNextAlarmIntent = AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED.equalsIgnoreCase(intent.getAction());
if (!isBootIntent && !isNextAlarmIntent) {
return;
}
final AlarmManager alarmManager;
if (android.os.Build.VERSION.SDK_INT >= 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");
}
}
}

View File

@ -1,7 +1,7 @@
package com.keyboardcrumbs.hassclient; package com.keyboardcrumbs.hassclient;
import android.app.AlarmManager;
import android.content.Context; import android.content.Context;
import androidx.annotation.NonNull;
import android.util.Log; import android.util.Log;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Intent; import android.content.Intent;
@ -19,6 +19,10 @@ public class NotificationActionReceiver extends BroadcastReceiver {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
if (intent == null) {
return;
}
String rawActionData = intent.getStringExtra("actionData"); String rawActionData = intent.getStringExtra("actionData");
if (intent.hasExtra("tag")) { if (intent.hasExtra("tag")) {
String notificationTag = intent.getStringExtra("tag"); String notificationTag = intent.getStringExtra("tag");

View File

@ -28,6 +28,7 @@ class AppSettings {
String webhookId; String webhookId;
double haVersion; double haVersion;
bool scrollBadges; bool scrollBadges;
bool nextAlarmSensorCreated = false;
DisplayMode displayMode; DisplayMode displayMode;
AppTheme appTheme; AppTheme appTheme;
final int defaultLocationUpdateIntervalMinutes = 20; final int defaultLocationUpdateIntervalMinutes = 20;
@ -61,6 +62,7 @@ class AppSettings {
locationUpdateInterval = Duration(minutes: prefs.getInt("location-interval") ?? locationUpdateInterval = Duration(minutes: prefs.getInt("location-interval") ??
defaultLocationUpdateIntervalMinutes); defaultLocationUpdateIntervalMinutes);
locationTrackingEnabled = prefs.getBool("location-enabled") ?? false; locationTrackingEnabled = prefs.getBool("location-enabled") ?? false;
nextAlarmSensorCreated = prefs.getBool("next-alarm-sensor-created") ?? false;
longLivedToken = Hive.box(DEFAULT_HIVE_BOX).get(AUTH_TOKEN_KEY); longLivedToken = Hive.box(DEFAULT_HIVE_BOX).get(AUTH_TOKEN_KEY);
oauthUrl = "$httpWebHost/auth/authorize?client_id=${Uri.encodeComponent( oauthUrl = "$httpWebHost/auth/authorize?client_id=${Uri.encodeComponent(
'https://ha-client.app')}&redirect_uri=${Uri 'https://ha-client.app')}&redirect_uri=${Uri

View File

@ -62,12 +62,13 @@ class MobileAppIntegrationManager {
includeAuthHeader: true, includeAuthHeader: true,
data: json.encode(registrationData) data: json.encode(registrationData)
).then((response) { ).then((response) {
Logger.d("Processing registration responce..."); Logger.d("Processing registration response...");
var responseObject = json.decode(response); var responseObject = json.decode(response);
AppSettings().webhookId = responseObject["webhook_id"]; AppSettings().webhookId = responseObject["webhook_id"];
AppSettings().save({ AppSettings().save({
'app-webhook-id': responseObject["webhook_id"] 'app-webhook-id': responseObject["webhook_id"]
}).then((prefs) { }).then((_) {
_createNextAlarmSensor(true);
completer.complete(); completer.complete();
eventBus.fire(ShowPopupEvent( eventBus.fire(ShowPopupEvent(
popup: Popup( popup: Popup(
@ -112,6 +113,7 @@ class MobileAppIntegrationManager {
_askToRegisterApp(); _askToRegisterApp();
} else { } else {
Logger.d('App registration works fine'); Logger.d('App registration works fine');
_createNextAlarmSensor(false);
} }
completer.complete(); completer.complete();
}).catchError((e) { }).catchError((e) {
@ -131,6 +133,42 @@ class MobileAppIntegrationManager {
return completer.future; 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() { static void _showError() {
eventBus.fire(ShowPopupEvent( eventBus.fire(ShowPopupEvent(
popup: Popup( popup: Popup(