mirror of
https://github.com/house-of-abbey/GarminHomeAssistant.git
synced 2025-04-30 12:42:27 +00:00
Added update to telemetry on completion of an activity (#151)
@Someone0nEarth Note we could also add this to the widget version as the changes are small and probably have a limited effect on the memory footprint.
This commit is contained in:
@ -23,6 +23,7 @@ using Toybox.Lang;
|
||||
using Toybox.Application.Properties;
|
||||
using Toybox.Background;
|
||||
using Toybox.System;
|
||||
using Toybox.Activity;
|
||||
|
||||
(:background)
|
||||
class BackgroundServiceDelegate extends System.ServiceDelegate {
|
||||
@ -37,99 +38,77 @@ class BackgroundServiceDelegate extends System.ServiceDelegate {
|
||||
Background.exit(null);
|
||||
}
|
||||
|
||||
function onActivityCompleted(activity as { :sport as Activity.Sport, :subSport as Activity.SubSport }) as Void {
|
||||
if (!System.getDeviceSettings().phoneConnected) {
|
||||
// System.println("BackgroundServiceDelegate onActivityCompleted(): No Phone connection, skipping API call.");
|
||||
} else if (!System.getDeviceSettings().connectionAvailable) {
|
||||
// System.println("BackgroundServiceDelegate onActivityCompleted(): No Internet connection, skipping API call.");
|
||||
} else {
|
||||
// Ensure we're logging completion, i.e. ignore 'activity' parameter
|
||||
// System.println("BackgroundServiceDelegate onActivityCompleted(): Event triggered");
|
||||
doUpdate(-1, -1);
|
||||
}
|
||||
}
|
||||
|
||||
function onTemporalEvent() as Void {
|
||||
if (!System.getDeviceSettings().phoneConnected) {
|
||||
// System.println("BackgroundServiceDelegate onTemporalEvent(): No Phone connection, skipping API call.");
|
||||
} else if (!System.getDeviceSettings().connectionAvailable) {
|
||||
// System.println("BackgroundServiceDelegate onTemporalEvent(): No Internet connection, skipping API call.");
|
||||
} else {
|
||||
// System.println("BackgroundServiceDelegate onTemporalEvent(): Making API call.");
|
||||
var position = Position.getInfo();
|
||||
// System.println("BackgroundServiceDelegate onTemporalEvent(): gps: " + position.position.toDegrees());
|
||||
// System.println("BackgroundServiceDelegate onTemporalEvent(): speed: " + position.speed);
|
||||
// System.println("BackgroundServiceDelegate onTemporalEvent(): course: " + position.heading + "rad (" + (position.heading * 180 / Math.PI) + "°)");
|
||||
// System.println("BackgroundServiceDelegate onTemporalEvent(): altitude: " + position.altitude);
|
||||
// System.println("BackgroundServiceDelegate onTemporalEvent(): battery: " + System.getSystemStats().battery);
|
||||
// System.println("BackgroundServiceDelegate onTemporalEvent(): charging: " + System.getSystemStats().charging);
|
||||
// System.println("BackgroundServiceDelegate onTemporalEvent(): activity: " + Activity.getProfileInfo().name);
|
||||
|
||||
// Don't use Settings.* here as the object lasts < 30 secs and is recreated each time the background service is run
|
||||
|
||||
if (position.accuracy != Position.QUALITY_NOT_AVAILABLE && position.accuracy != Position.QUALITY_LAST_KNOWN) {
|
||||
var accuracy = 0;
|
||||
switch (position.accuracy) {
|
||||
case Position.QUALITY_POOR:
|
||||
accuracy = 500;
|
||||
break;
|
||||
case Position.QUALITY_USABLE:
|
||||
accuracy = 100;
|
||||
break;
|
||||
case Position.QUALITY_GOOD:
|
||||
accuracy = 10;
|
||||
break;
|
||||
}
|
||||
Communications.makeWebRequest(
|
||||
(Properties.getValue("api_url") as Lang.String) + "/webhook/" + (Properties.getValue("webhook_id") as Lang.String),
|
||||
{
|
||||
"type" => "update_location",
|
||||
"data" => {
|
||||
"gps" => position.position.toDegrees(),
|
||||
"gps_accuracy" => accuracy,
|
||||
"speed" => Math.round(position.speed),
|
||||
"course" => Math.round(position.heading * 180 / Math.PI),
|
||||
"altitude" => Math.round(position.altitude),
|
||||
}
|
||||
},
|
||||
{
|
||||
:method => Communications.HTTP_REQUEST_METHOD_POST,
|
||||
:headers => {
|
||||
"Content-Type" => Communications.REQUEST_CONTENT_TYPE_JSON
|
||||
},
|
||||
:responseType => Communications.HTTP_RESPONSE_CONTENT_TYPE_JSON
|
||||
},
|
||||
method(:onReturnBatteryUpdate)
|
||||
);
|
||||
var activity = Activity.getProfileInfo().sport;
|
||||
var sub_activity = Activity.getProfileInfo().subSport;
|
||||
// We need to check if we are actually tracking any activity as the enumerated type does not include "No Sport".
|
||||
if ((Activity.getActivityInfo() != null) and
|
||||
((Activity.getActivityInfo().elapsedTime == null) or
|
||||
(Activity.getActivityInfo().elapsedTime == 0))) {
|
||||
// Indicate no activity with -1, not part of Garmin's activity codes.
|
||||
// https://developer.garmin.com/connect-iq/api-docs/Toybox/Activity.html#Sport-module
|
||||
activity = -1;
|
||||
sub_activity = -1;
|
||||
}
|
||||
var data = [
|
||||
{
|
||||
"state" => System.getSystemStats().battery,
|
||||
"type" => "sensor",
|
||||
"unique_id" => "battery_level"
|
||||
},
|
||||
{
|
||||
"state" => System.getSystemStats().charging,
|
||||
"type" => "binary_sensor",
|
||||
"unique_id" => "battery_is_charging"
|
||||
}
|
||||
];
|
||||
if ((Activity has :getActivityInfo) and (Activity has :getProfileInfo)) {
|
||||
var activity = Activity.getProfileInfo().sport;
|
||||
var sub_activity = Activity.getProfileInfo().subSport;
|
||||
// We need to check if we are actually tracking any activity as the enumerated type does not include "No Sport".
|
||||
if ((Activity.getActivityInfo() != null) and
|
||||
((Activity.getActivityInfo().elapsedTime == null) or
|
||||
(Activity.getActivityInfo().elapsedTime == 0))) {
|
||||
// Indicate no activity with -1, not part of Garmin's activity codes.
|
||||
// https://developer.garmin.com/connect-iq/api-docs/Toybox/Activity.html#Sport-module
|
||||
activity = -1;
|
||||
sub_activity = -1;
|
||||
}
|
||||
data.add({
|
||||
"state" => activity,
|
||||
"type" => "sensor",
|
||||
"unique_id" => "activity"
|
||||
});
|
||||
data.add({
|
||||
"state" => sub_activity,
|
||||
"type" => "sensor",
|
||||
"unique_id" => "sub_activity"
|
||||
});
|
||||
// System.println("BackgroundServiceDelegate onTemporalEvent(): Event triggered, activity = " + activity + " sub_activity = " + sub_activity);
|
||||
doUpdate(activity, sub_activity);
|
||||
}
|
||||
}
|
||||
|
||||
private function doUpdate(activity as Lang.Number, sub_activity as Lang.Number) {
|
||||
// System.println("BackgroundServiceDelegate onTemporalEvent(): Making API call.");
|
||||
var position = Position.getInfo();
|
||||
// System.println("BackgroundServiceDelegate onTemporalEvent(): gps: " + position.position.toDegrees());
|
||||
// System.println("BackgroundServiceDelegate onTemporalEvent(): speed: " + position.speed);
|
||||
// System.println("BackgroundServiceDelegate onTemporalEvent(): course: " + position.heading + "rad (" + (position.heading * 180 / Math.PI) + "°)");
|
||||
// System.println("BackgroundServiceDelegate onTemporalEvent(): altitude: " + position.altitude);
|
||||
// System.println("BackgroundServiceDelegate onTemporalEvent(): battery: " + System.getSystemStats().battery);
|
||||
// System.println("BackgroundServiceDelegate onTemporalEvent(): charging: " + System.getSystemStats().charging);
|
||||
// System.println("BackgroundServiceDelegate onTemporalEvent(): activity: " + Activity.getProfileInfo().name);
|
||||
|
||||
// Don't use Settings.* here as the object lasts < 30 secs and is recreated each time the background service is run
|
||||
|
||||
if (position.accuracy != Position.QUALITY_NOT_AVAILABLE && position.accuracy != Position.QUALITY_LAST_KNOWN) {
|
||||
var accuracy = 0;
|
||||
switch (position.accuracy) {
|
||||
case Position.QUALITY_POOR:
|
||||
accuracy = 500;
|
||||
break;
|
||||
case Position.QUALITY_USABLE:
|
||||
accuracy = 100;
|
||||
break;
|
||||
case Position.QUALITY_GOOD:
|
||||
accuracy = 10;
|
||||
break;
|
||||
}
|
||||
Communications.makeWebRequest(
|
||||
(Properties.getValue("api_url") as Lang.String) + "/webhook/" + (Properties.getValue("webhook_id") as Lang.String),
|
||||
{
|
||||
"type" => "update_sensor_states",
|
||||
"data" => data
|
||||
"type" => "update_location",
|
||||
"data" => {
|
||||
"gps" => position.position.toDegrees(),
|
||||
"gps_accuracy" => accuracy,
|
||||
"speed" => Math.round(position.speed),
|
||||
"course" => Math.round(position.heading * 180 / Math.PI),
|
||||
"altitude" => Math.round(position.altitude),
|
||||
}
|
||||
},
|
||||
{
|
||||
:method => Communications.HTTP_REQUEST_METHOD_POST,
|
||||
@ -141,6 +120,45 @@ class BackgroundServiceDelegate extends System.ServiceDelegate {
|
||||
method(:onReturnBatteryUpdate)
|
||||
);
|
||||
}
|
||||
var data = [
|
||||
{
|
||||
"state" => System.getSystemStats().battery,
|
||||
"type" => "sensor",
|
||||
"unique_id" => "battery_level"
|
||||
},
|
||||
{
|
||||
"state" => System.getSystemStats().charging,
|
||||
"type" => "binary_sensor",
|
||||
"unique_id" => "battery_is_charging"
|
||||
}
|
||||
];
|
||||
if ((Activity has :getActivityInfo) and (Activity has :getProfileInfo)) {
|
||||
data.add({
|
||||
"state" => activity,
|
||||
"type" => "sensor",
|
||||
"unique_id" => "activity"
|
||||
});
|
||||
data.add({
|
||||
"state" => sub_activity,
|
||||
"type" => "sensor",
|
||||
"unique_id" => "sub_activity"
|
||||
});
|
||||
}
|
||||
Communications.makeWebRequest(
|
||||
(Properties.getValue("api_url") as Lang.String) + "/webhook/" + (Properties.getValue("webhook_id") as Lang.String),
|
||||
{
|
||||
"type" => "update_sensor_states",
|
||||
"data" => data
|
||||
},
|
||||
{
|
||||
:method => Communications.HTTP_REQUEST_METHOD_POST,
|
||||
:headers => {
|
||||
"Content-Type" => Communications.REQUEST_CONTENT_TYPE_JSON
|
||||
},
|
||||
:responseType => Communications.HTTP_RESPONSE_CONTENT_TYPE_JSON
|
||||
},
|
||||
method(:onReturnBatteryUpdate)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -95,9 +95,11 @@ class Settings {
|
||||
if ((Background.getTemporalEventRegisteredTime() == null) or
|
||||
(Background.getTemporalEventRegisteredTime() != (mBatteryRefreshRate * 60))) {
|
||||
Background.registerForTemporalEvent(new Time.Duration(mBatteryRefreshRate * 60)); // Convert to seconds
|
||||
Background.registerForActivityCompletedEvent();
|
||||
}
|
||||
} else if (Background.getTemporalEventRegisteredTime() != null) {
|
||||
Background.deleteTemporalEvent();
|
||||
Background.deleteActivityCompletedEvent();
|
||||
}
|
||||
} else {
|
||||
// Explicitly disable the background event which persists when the application closes.
|
||||
@ -182,6 +184,7 @@ class Settings {
|
||||
Properties.setValue("enable_battery_level", mIsSensorsLevelEnabled);
|
||||
if (mHasService and (Background.getTemporalEventRegisteredTime() != null)) {
|
||||
Background.deleteTemporalEvent();
|
||||
Background.deleteActivityCompletedEvent();
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user