mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-11-04 09:17:29 +01:00
HPlus notficiation encoding weather improvments (#2012)
fix indent change add only new functions from master branch correct issue with reformated code Merge branch 'master' into HPlus_improve_notifications update code formatting with Android Studio remove bad update of .gitignore HPlusSupport rebuild indexation remove unecessary change for pull request Improve HPlus support - update unicode support - update notification function - add first weather notification Merge pull request 'update master from upstream repository' (#4) from Freeyourgadget/Gadgetbridge:master into master Reviewed-on: https://codeberg.org/Memiks/Gadgetbridge/pulls/4 Merge pull request 'update master from upstream repository' (#2) from Freeyourgadget/Gadgetbridge:master into master Reviewed-on: https://codeberg.org/Memiks/Gadgetbridge/pulls/2 use my own android sdk image Sign apk add signed apk remove .drone.yml from git add drone.io compilation Merge pull request 'update master from upstream repository' (#1) from Freeyourgadget/Gadgetbridge:master into master Reviewed-on: https://codeberg.org/Memiks/Gadgetbridge/pulls/1 Co-authored-by: Andreas Shimokawa <shimokawa@fsfe.org> Co-authored-by: Memiks <contact@memiks.fr> Reviewed-on: https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/2012
This commit is contained in:
parent
4c55c63a32
commit
70a140f358
@ -18,8 +18,8 @@
|
|||||||
package nodomain.freeyourgadget.gadgetbridge.devices.hplus;
|
package nodomain.freeyourgadget.gadgetbridge.devices.hplus;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @author João Paulo Barraca <jpbarraca@gmail.com>
|
* @author João Paulo Barraca <jpbarraca@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -88,6 +88,7 @@ public final class HPlusConstants {
|
|||||||
public static final byte CMD_SET_PREFS = 0x50;
|
public static final byte CMD_SET_PREFS = 0x50;
|
||||||
public static final byte CMD_SET_SIT_INTERVAL = 0x51;
|
public static final byte CMD_SET_SIT_INTERVAL = 0x51;
|
||||||
public static final byte CMD_SET_HEARTRATE_STATE = 0x32;
|
public static final byte CMD_SET_HEARTRATE_STATE = 0x32;
|
||||||
|
public static final byte CMD_SET_WEATHER_STATE = 0x5f;
|
||||||
|
|
||||||
//GET messages
|
//GET messages
|
||||||
public static final byte CMD_GET_VERSION = 0x17;
|
public static final byte CMD_GET_VERSION = 0x17;
|
||||||
@ -131,8 +132,10 @@ public final class HPlusConstants {
|
|||||||
public static final String PREF_HPLUS_SIT_START_TIME = "hplus_sit_start_time";
|
public static final String PREF_HPLUS_SIT_START_TIME = "hplus_sit_start_time";
|
||||||
public static final String PREF_HPLUS_SIT_END_TIME = "hplus_sit_end_time";
|
public static final String PREF_HPLUS_SIT_END_TIME = "hplus_sit_end_time";
|
||||||
public static final String PREF_HPLUS_UNICODE = "hplus_unicode";
|
public static final String PREF_HPLUS_UNICODE = "hplus_unicode";
|
||||||
|
public static final String PREF_HPLUS_DISPLAY_NOTIFICATION_ICON = "hplus_display_notification_icon";
|
||||||
|
public static final String PREF_HPLUS_NOTIFICATION_LINES = "hplus_notification_lines";
|
||||||
|
|
||||||
public static final Map<Character, byte[]> transliterateMap = new HashMap<Character, byte[]>(){
|
public static final Map<Character, byte[]> transliterateMap = new HashMap<Character, byte[]>() {
|
||||||
{
|
{
|
||||||
//These are missing
|
//These are missing
|
||||||
put('ó', new byte[]{(byte) 111});
|
put('ó', new byte[]{(byte) 111});
|
||||||
|
@ -18,8 +18,8 @@
|
|||||||
package nodomain.freeyourgadget.gadgetbridge.devices.hplus;
|
package nodomain.freeyourgadget.gadgetbridge.devices.hplus;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @author João Paulo Barraca <jpbarraca@gmail.com>
|
* @author João Paulo Barraca <jpbarraca@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
@ -38,6 +38,7 @@ import java.util.Collections;
|
|||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import de.greenrobot.dao.query.QueryBuilder;
|
import de.greenrobot.dao.query.QueryBuilder;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBException;
|
import nodomain.freeyourgadget.gadgetbridge.GBException;
|
||||||
@ -62,7 +63,7 @@ import static nodomain.freeyourgadget.gadgetbridge.GBApplication.getContext;
|
|||||||
|
|
||||||
public class HPlusCoordinator extends AbstractDeviceCoordinator {
|
public class HPlusCoordinator extends AbstractDeviceCoordinator {
|
||||||
protected static final Logger LOG = LoggerFactory.getLogger(HPlusCoordinator.class);
|
protected static final Logger LOG = LoggerFactory.getLogger(HPlusCoordinator.class);
|
||||||
protected static Prefs prefs = GBApplication.getPrefs();
|
protected static Prefs prefs = GBApplication.getPrefs();
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
@ -85,7 +86,7 @@ public class HPlusCoordinator extends AbstractDeviceCoordinator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getBondingStyle(){
|
public int getBondingStyle() {
|
||||||
return BONDING_STYLE_NONE;
|
return BONDING_STYLE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,9 +192,9 @@ public class HPlusCoordinator extends AbstractDeviceCoordinator {
|
|||||||
locale = new Locale(language);
|
locale = new Locale(language);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (locale.getLanguage().equals(new Locale("cn").getLanguage())){
|
if (locale.getLanguage().equals(new Locale("cn").getLanguage())) {
|
||||||
return HPlusConstants.ARG_LANGUAGE_CN;
|
return HPlusConstants.ARG_LANGUAGE_CN;
|
||||||
}else{
|
} else {
|
||||||
return HPlusConstants.ARG_LANGUAGE_EN;
|
return HPlusConstants.ARG_LANGUAGE_EN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -205,7 +206,7 @@ public class HPlusCoordinator extends AbstractDeviceCoordinator {
|
|||||||
|
|
||||||
if ("24h".equals(tmode)) {
|
if ("24h".equals(tmode)) {
|
||||||
return HPlusConstants.ARG_TIMEMODE_24H;
|
return HPlusConstants.ARG_TIMEMODE_24H;
|
||||||
}else{
|
} else {
|
||||||
return HPlusConstants.ARG_TIMEMODE_12H;
|
return HPlusConstants.ARG_TIMEMODE_12H;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -213,9 +214,9 @@ public class HPlusCoordinator extends AbstractDeviceCoordinator {
|
|||||||
public static byte getUnit(String address) {
|
public static byte getUnit(String address) {
|
||||||
String units = prefs.getString(SettingsActivity.PREF_MEASUREMENT_SYSTEM, getContext().getString(R.string.p_unit_metric));
|
String units = prefs.getString(SettingsActivity.PREF_MEASUREMENT_SYSTEM, getContext().getString(R.string.p_unit_metric));
|
||||||
|
|
||||||
if(units.equals(getContext().getString(R.string.p_unit_metric))){
|
if (units.equals(getContext().getString(R.string.p_unit_metric))) {
|
||||||
return HPlusConstants.ARG_UNIT_METRIC;
|
return HPlusConstants.ARG_UNIT_METRIC;
|
||||||
}else{
|
} else {
|
||||||
return HPlusConstants.ARG_UNIT_IMPERIAL;
|
return HPlusConstants.ARG_UNIT_IMPERIAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -260,9 +261,9 @@ public class HPlusCoordinator extends AbstractDeviceCoordinator {
|
|||||||
public static byte getAllDayHR(String address) {
|
public static byte getAllDayHR(String address) {
|
||||||
boolean value = (prefs.getBoolean(HPlusConstants.PREF_HPLUS_ALLDAYHR, true));
|
boolean value = (prefs.getBoolean(HPlusConstants.PREF_HPLUS_ALLDAYHR, true));
|
||||||
|
|
||||||
if(value){
|
if (value) {
|
||||||
return HPlusConstants.ARG_HEARTRATE_ALLDAY_ON;
|
return HPlusConstants.ARG_HEARTRATE_ALLDAY_ON;
|
||||||
}else{
|
} else {
|
||||||
return HPlusConstants.ARG_HEARTRATE_ALLDAY_OFF;
|
return HPlusConstants.ARG_HEARTRATE_ALLDAY_OFF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -293,16 +294,36 @@ public class HPlusCoordinator extends AbstractDeviceCoordinator {
|
|||||||
return prefs.getInt(HPlusConstants.PREF_HPLUS_SIT_END_TIME, 0);
|
return prefs.getInt(HPlusConstants.PREF_HPLUS_SIT_END_TIME, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setUnicodeSupport(String address, boolean state){
|
public static void setDisplayIncomingMessageIcon(String address, boolean state) {
|
||||||
|
SharedPreferences.Editor editor = prefs.getPreferences().edit();
|
||||||
|
editor.putBoolean(HPlusConstants.PREF_HPLUS_DISPLAY_NOTIFICATION_ICON + "_" + address, state);
|
||||||
|
editor.apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean getDisplayIncomingMessageIcon(String address) {
|
||||||
|
return (prefs.getBoolean(HPlusConstants.PREF_HPLUS_DISPLAY_NOTIFICATION_ICON + "_" + address, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setUnicodeSupport(String address, boolean state) {
|
||||||
SharedPreferences.Editor editor = prefs.getPreferences().edit();
|
SharedPreferences.Editor editor = prefs.getPreferences().edit();
|
||||||
editor.putBoolean(HPlusConstants.PREF_HPLUS_UNICODE + "_" + address, state);
|
editor.putBoolean(HPlusConstants.PREF_HPLUS_UNICODE + "_" + address, state);
|
||||||
editor.apply();
|
editor.apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean getUnicodeSupport(String address){
|
public static boolean getUnicodeSupport(String address) {
|
||||||
return (prefs.getBoolean(HPlusConstants.PREF_HPLUS_UNICODE + "_" + address, false));
|
return (prefs.getBoolean(HPlusConstants.PREF_HPLUS_UNICODE + "_" + address, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void setNotificationLinesNumber(String address, int lineNumber) {
|
||||||
|
SharedPreferences.Editor editor = prefs.getPreferences().edit();
|
||||||
|
editor.putInt(HPlusConstants.PREF_HPLUS_NOTIFICATION_LINES + "_" + address, lineNumber);
|
||||||
|
editor.apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getNotificationLinesNumber(String address) {
|
||||||
|
return (prefs.getInt(HPlusConstants.PREF_HPLUS_NOTIFICATION_LINES + "_" + address, 5));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int[] getSupportedDeviceSpecificSettings(GBDevice device) {
|
public int[] getSupportedDeviceSpecificSettings(GBDevice device) {
|
||||||
return new int[]{
|
return new int[]{
|
||||||
@ -312,3 +333,4 @@ public class HPlusCoordinator extends AbstractDeviceCoordinator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,197 @@
|
|||||||
|
/* Copyright (C) 2020 Lesur Frederic (memiks)
|
||||||
|
|
||||||
|
This file is part of Gadgetbridge.
|
||||||
|
|
||||||
|
Gadgetbridge is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Gadgetbridge is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
package nodomain.freeyourgadget.gadgetbridge.devices.hplus;
|
||||||
|
|
||||||
|
public class HPlusWeatherCode {
|
||||||
|
// Weather code from https://github.com/heweather/WeatherIcon
|
||||||
|
public static final int SUNNY = 100;
|
||||||
|
public static final int CLOUDY = 101;
|
||||||
|
public static final int FEW_CLOUDS = 102;
|
||||||
|
public static final int PARTLY_CLOUDY = 103;
|
||||||
|
public static final int OVERCAST = 104;
|
||||||
|
public static final int CLEAR = 150;
|
||||||
|
public static final int PARTLY_CLOUDY_NIGHT = 153;
|
||||||
|
public static final int OVERCAST_NIGHT = 154;
|
||||||
|
public static final int SHOWER_RAIN = 300;
|
||||||
|
public static final int HEAVY_SHOWER_RAIN = 301;
|
||||||
|
public static final int THUNDERSHOWER = 302;
|
||||||
|
public static final int HEAVY_THUNDERSTORM = 303;
|
||||||
|
public static final int THUNDERSHOWER_WITH_HAIL = 304;
|
||||||
|
public static final int LIGHT_RAIN = 305;
|
||||||
|
public static final int MODERATE_RAIN = 306;
|
||||||
|
public static final int HEAVY_RAIN = 307;
|
||||||
|
public static final int EXTREME_RAIN = 308;
|
||||||
|
public static final int DRIZZLE_RAIN = 309;
|
||||||
|
public static final int STORM = 310;
|
||||||
|
public static final int HEAVY_STORM = 311;
|
||||||
|
public static final int SEVERE_STORM = 312;
|
||||||
|
public static final int FREEZING_RAIN = 313;
|
||||||
|
public static final int LIGHT_TO_MODERATE_RAIN = 314;
|
||||||
|
public static final int MODERATE_TO_HEAVY_RAIN = 315;
|
||||||
|
public static final int HEAVY_RAIN_TO_STORM = 316;
|
||||||
|
public static final int STORM_TO_HEAVY_STORM = 317;
|
||||||
|
public static final int HEAVY_TO_SEVERE_STORM = 318;
|
||||||
|
public static final int RAIN = 399;
|
||||||
|
public static final int SHOWER_RAIN_NIGHT = 350;
|
||||||
|
public static final int HEAVY_SHOWER_RAIN_NIGHT = 351;
|
||||||
|
public static final int LIGHT_SNOW = 400;
|
||||||
|
public static final int MODERATE_SNOW = 401;
|
||||||
|
public static final int HEAVY_SNOW = 402;
|
||||||
|
public static final int SNOWSTORM = 403;
|
||||||
|
public static final int SLEET = 404;
|
||||||
|
public static final int RAIN_AND_SNOW = 405;
|
||||||
|
public static final int SHOWER_SNOW = 406;
|
||||||
|
public static final int SNOW_FLURRY = 407;
|
||||||
|
public static final int LIGHT_TO_MODERATE_SNOW = 408;
|
||||||
|
public static final int MODERATE_TO_HEAVY_SNOW = 409;
|
||||||
|
public static final int HEAVY_SNOW_TO_SNOWSTORM = 410;
|
||||||
|
public static final int SNOW = 499;
|
||||||
|
public static final int SHOWER_SNOW_NIGHT = 456;
|
||||||
|
public static final int SNOW_FLURRY_NIGHT = 457;
|
||||||
|
public static final int MIST = 500;
|
||||||
|
public static final int FOGGY = 501;
|
||||||
|
public static final int HAZE = 502;
|
||||||
|
public static final int SAND = 503;
|
||||||
|
public static final int DUST = 504;
|
||||||
|
public static final int DUSTSTORM = 507;
|
||||||
|
public static final int SANDSTORM = 508;
|
||||||
|
public static final int DENSE_FOG = 509;
|
||||||
|
public static final int STRONG_FOG = 510;
|
||||||
|
public static final int MODERATE_HAZE = 511;
|
||||||
|
public static final int HEAVY_HAZE = 512;
|
||||||
|
public static final int SEVERE_HAZE = 513;
|
||||||
|
public static final int HEAVY_FOG = 514;
|
||||||
|
public static final int EXTRA_HEAVY_FOG = 515;
|
||||||
|
public static final int HOT = 900;
|
||||||
|
public static final int COLD = 901;
|
||||||
|
public static final int UNKNOWN = 999;
|
||||||
|
|
||||||
|
public static final int mapOpenWeatherConditionToHPlusCondition(int openWeatherMapCondition) {
|
||||||
|
switch (openWeatherMapCondition) {
|
||||||
|
//Group 2xx: Thunderstorm
|
||||||
|
case 200: //thunderstorm with light rain: //11d
|
||||||
|
return HPlusWeatherCode.STORM;
|
||||||
|
case 201: //thunderstorm with rain: //11d
|
||||||
|
case 202: //thunderstorm with heavy rain: //11d
|
||||||
|
return HPlusWeatherCode.HEAVY_RAIN_TO_STORM;
|
||||||
|
case 210: //light thunderstorm:: //11d
|
||||||
|
case 211: //thunderstorm: //11d
|
||||||
|
case 230: //thunderstorm with light drizzle: //11d
|
||||||
|
case 231: //thunderstorm with drizzle: //11d
|
||||||
|
case 232: //thunderstorm with heavy drizzle: //11d
|
||||||
|
case 212: //heavy thunderstorm: //11d
|
||||||
|
case 221: //ragged thunderstorm: //11d
|
||||||
|
return HPlusWeatherCode.HEAVY_THUNDERSTORM;
|
||||||
|
//Group 3xx: Drizzle
|
||||||
|
case 300: //light intensity drizzle: //09d
|
||||||
|
case 301: //drizzle: //09d
|
||||||
|
case 302: //heavy intensity drizzle: //09d
|
||||||
|
case 310: //light intensity drizzle rain: //09d
|
||||||
|
case 311: //drizzle rain: //09d
|
||||||
|
case 312: //heavy intensity drizzle rain: //09d
|
||||||
|
case 313: //shower rain and drizzle: //09d
|
||||||
|
case 314: //heavy shower rain and drizzle: //09d
|
||||||
|
case 321: //shower drizzle: //09d
|
||||||
|
return HPlusWeatherCode.DRIZZLE_RAIN;
|
||||||
|
case 500: //light rain: //10d
|
||||||
|
return HPlusWeatherCode.LIGHT_RAIN;
|
||||||
|
case 501: //moderate rain: //10d
|
||||||
|
return HPlusWeatherCode.MODERATE_RAIN;
|
||||||
|
//Group 5xx: Rain
|
||||||
|
case 502: //heavy intensity rain: //10d
|
||||||
|
return HPlusWeatherCode.HEAVY_RAIN;
|
||||||
|
case 503: //very heavy rain: //10d
|
||||||
|
return HPlusWeatherCode.HEAVY_RAIN_TO_STORM;
|
||||||
|
case 504: //extreme rain: //10d
|
||||||
|
return HPlusWeatherCode.EXTREME_RAIN;
|
||||||
|
case 511: //freezing rain: //13d
|
||||||
|
return HPlusWeatherCode.FREEZING_RAIN;
|
||||||
|
case 520: //light intensity shower rain: //09d
|
||||||
|
case 521: //shower rain: //09d
|
||||||
|
return HPlusWeatherCode.SHOWER_RAIN;
|
||||||
|
case 522: //heavy intensity shower rain: //09d
|
||||||
|
case 531: //ragged shower rain: //09d
|
||||||
|
return HPlusWeatherCode.HEAVY_SHOWER_RAIN;
|
||||||
|
//Group 6xx: Snow
|
||||||
|
case 600: //light snow: //[[file:13d.png]]
|
||||||
|
return HPlusWeatherCode.LIGHT_SNOW;
|
||||||
|
case 601: //snow: //[[file:13d.png]]
|
||||||
|
return HPlusWeatherCode.SNOW;
|
||||||
|
case 620: //light shower snow: //[[file:13d.png]]
|
||||||
|
return HPlusWeatherCode.LIGHT_TO_MODERATE_SNOW;
|
||||||
|
case 602: //heavy snow: //[[file:13d.png]]
|
||||||
|
return HPlusWeatherCode.MODERATE_TO_HEAVY_SNOW;
|
||||||
|
case 611: //sleet: //[[file:13d.png]]
|
||||||
|
case 612: //shower sleet: //[[file:13d.png]]
|
||||||
|
return HPlusWeatherCode.SNOW_FLURRY;
|
||||||
|
case 621: //shower snow: //[[file:13d.png]]
|
||||||
|
case 622: //heavy shower snow: //[[file:13d.png]]
|
||||||
|
return HPlusWeatherCode.SHOWER_SNOW;
|
||||||
|
case 615: //light rain and snow: //[[file:13d.png]]
|
||||||
|
case 616: //rain and snow: //[[file:13d.png]]
|
||||||
|
return HPlusWeatherCode.RAIN_AND_SNOW;
|
||||||
|
//Group 7xx: Atmosphere
|
||||||
|
case 701: //mist: //[[file:50d.png]]
|
||||||
|
case 711: //smoke: //[[file:50d.png]]
|
||||||
|
case 721: //haze: //[[file:50d.png]]
|
||||||
|
case 731: //sandcase dust whirls: //[[file:50d.png]]
|
||||||
|
case 741: //fog: //[[file:50d.png]]
|
||||||
|
case 751: //sand: //[[file:50d.png]]
|
||||||
|
case 761: //dust: //[[file:50d.png]]
|
||||||
|
case 762: //volcanic ash: //[[file:50d.png]]
|
||||||
|
case 771: //squalls: //[[file:50d.png]]
|
||||||
|
case 781: //tornado: //[[file:50d.png]]
|
||||||
|
case 900: //tornado
|
||||||
|
return HPlusWeatherCode.SANDSTORM;
|
||||||
|
//Group 800: Clear
|
||||||
|
case 800: //clear sky: //[[file:01d.png]] [[file:01n.png]]
|
||||||
|
return HPlusWeatherCode.CLEAR;
|
||||||
|
//Group 80x: Clouds
|
||||||
|
case 801: //few clouds: //[[file:02d.png]] [[file:02n.png]]
|
||||||
|
return HPlusWeatherCode.FEW_CLOUDS;
|
||||||
|
case 802: //scattered clouds: //[[file:03d.png]] [[file:03d.png]]
|
||||||
|
case 803: //broken clouds: //[[file:04d.png]] [[file:03d.png]]
|
||||||
|
return HPlusWeatherCode.PARTLY_CLOUDY;
|
||||||
|
case 804: //overcast clouds: //[[file:04d.png]] [[file:04d.png]]
|
||||||
|
return HPlusWeatherCode.CLOUDY;
|
||||||
|
|
||||||
|
//Group 90x: Extreme
|
||||||
|
case 901: //tropical storm
|
||||||
|
case 903: //cold
|
||||||
|
case 904: //hot
|
||||||
|
case 905: //windy
|
||||||
|
case 906: //hail
|
||||||
|
//Group 9xx: Additional
|
||||||
|
case 951: //calm
|
||||||
|
case 952: //light breeze
|
||||||
|
case 953: //gentle breeze
|
||||||
|
case 954: //moderate breeze
|
||||||
|
case 955: //fresh breeze
|
||||||
|
case 956: //strong breeze
|
||||||
|
case 957: //high windcase near gale
|
||||||
|
case 958: //gale
|
||||||
|
case 959: //severe gale
|
||||||
|
case 960: //storm
|
||||||
|
case 961: //violent storm
|
||||||
|
case 902: //hurricane
|
||||||
|
case 962: //hurricane
|
||||||
|
return HPlusWeatherCode.SEVERE_HAZE;
|
||||||
|
default:
|
||||||
|
return HPlusWeatherCode.UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -17,11 +17,13 @@
|
|||||||
package nodomain.freeyourgadget.gadgetbridge.devices.hplus;
|
package nodomain.freeyourgadget.gadgetbridge.devices.hplus;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @author Frederic LESUR contact@memiks.fr;
|
* @author Frederic LESUR contact@memiks.fr;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||||
|
|
||||||
@ -34,7 +36,10 @@ public class SG2Coordinator extends HPlusCoordinator {
|
|||||||
@Override
|
@Override
|
||||||
public DeviceType getSupportedType(GBDeviceCandidate candidate) {
|
public DeviceType getSupportedType(GBDeviceCandidate candidate) {
|
||||||
String name = candidate.getDevice().getName();
|
String name = candidate.getDevice().getName();
|
||||||
if(name != null && name.startsWith("SG2")){
|
if (name != null && name.startsWith("SG2")) {
|
||||||
|
HPlusCoordinator.setNotificationLinesNumber(candidate.getDevice().getAddress(), 9);
|
||||||
|
HPlusCoordinator.setUnicodeSupport(candidate.getDevice().getAddress(), true);
|
||||||
|
HPlusCoordinator.setDisplayIncomingMessageIcon(candidate.getDevice().getAddress(), false);
|
||||||
return DeviceType.SG2;
|
return DeviceType.SG2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,4 +60,14 @@ public class SG2Coordinator extends HPlusCoordinator {
|
|||||||
public boolean supportsWeather() {
|
public boolean supportsWeather() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supportsSmartWakeup(GBDevice device) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBondingStyle() {
|
||||||
|
return BONDING_STYLE_ASK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,13 +17,15 @@
|
|||||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.hplus;
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.hplus;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @author João Paulo Barraca <jpbarraca@gmail.com>
|
* @author João Paulo Barraca <jpbarraca@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
|
||||||
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@ -34,7 +36,6 @@ import java.util.Comparator;
|
|||||||
import java.util.GregorianCalendar;
|
import java.util.GregorianCalendar;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBException;
|
import nodomain.freeyourgadget.gadgetbridge.GBException;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
||||||
@ -56,39 +57,26 @@ import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceIoThread;
|
|||||||
|
|
||||||
class HPlusHandlerThread extends GBDeviceIoThread {
|
class HPlusHandlerThread extends GBDeviceIoThread {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(HPlusHandlerThread.class);
|
private static final Logger LOG = LoggerFactory.getLogger(HPlusHandlerThread.class);
|
||||||
|
private final Object waitObject = new Object();
|
||||||
|
List<HPlusDataRecordDaySlot> mDaySlotRecords = new ArrayList<>();
|
||||||
private int CURRENT_DAY_SYNC_PERIOD = 24 * 60 * 60 * 365; //Never
|
private int CURRENT_DAY_SYNC_PERIOD = 24 * 60 * 60 * 365; //Never
|
||||||
private int CURRENT_DAY_SYNC_RETRY_PERIOD = 10;
|
private int CURRENT_DAY_SYNC_RETRY_PERIOD = 10;
|
||||||
|
|
||||||
private int SLEEP_SYNC_PERIOD = 12 * 60 * 60;
|
private int SLEEP_SYNC_PERIOD = 12 * 60 * 60;
|
||||||
private int SLEEP_SYNC_RETRY_PERIOD = 30;
|
private int SLEEP_SYNC_RETRY_PERIOD = 30;
|
||||||
|
|
||||||
private int DAY_SUMMARY_SYNC_PERIOD = 24 * 60 * 60;
|
private int DAY_SUMMARY_SYNC_PERIOD = 24 * 60 * 60;
|
||||||
private int DAY_SUMMARY_SYNC_RETRY_PERIOD = 30;
|
private int DAY_SUMMARY_SYNC_RETRY_PERIOD = 30;
|
||||||
|
|
||||||
private int HELLO_PERIOD = 60 * 2;
|
private int HELLO_PERIOD = 60 * 2;
|
||||||
|
|
||||||
private boolean mQuit = false;
|
private boolean mQuit = false;
|
||||||
private HPlusSupport mHPlusSupport;
|
private HPlusSupport mHPlusSupport;
|
||||||
|
|
||||||
private int mLastSlotReceived = -1;
|
private int mLastSlotReceived = -1;
|
||||||
private int mLastSlotRequested = 0;
|
private int mLastSlotRequested = 0;
|
||||||
|
|
||||||
private Calendar mLastSleepDayReceived = GregorianCalendar.getInstance();
|
private Calendar mLastSleepDayReceived = GregorianCalendar.getInstance();
|
||||||
private Calendar mGetDaySlotsTime = GregorianCalendar.getInstance();
|
private Calendar mGetDaySlotsTime = GregorianCalendar.getInstance();
|
||||||
private Calendar mGetSleepTime = GregorianCalendar.getInstance();
|
private Calendar mGetSleepTime = GregorianCalendar.getInstance();
|
||||||
private Calendar mGetDaySummaryTime = GregorianCalendar.getInstance();
|
private Calendar mGetDaySummaryTime = GregorianCalendar.getInstance();
|
||||||
|
|
||||||
private Calendar mHelloTime = GregorianCalendar.getInstance();
|
private Calendar mHelloTime = GregorianCalendar.getInstance();
|
||||||
|
|
||||||
private boolean mSlotsInitialSync = true;
|
private boolean mSlotsInitialSync = true;
|
||||||
|
|
||||||
private HPlusDataRecordRealtime prevRealTimeRecord = null;
|
private HPlusDataRecordRealtime prevRealTimeRecord = null;
|
||||||
|
|
||||||
private final Object waitObject = new Object();
|
|
||||||
|
|
||||||
List<HPlusDataRecordDaySlot> mDaySlotRecords = new ArrayList<>();
|
|
||||||
|
|
||||||
private HPlusDataRecordDaySlot mCurrentDaySlot = null;
|
private HPlusDataRecordDaySlot mCurrentDaySlot = null;
|
||||||
|
|
||||||
public HPlusHandlerThread(GBDevice gbDevice, Context context, HPlusSupport hplusSupport) {
|
public HPlusHandlerThread(GBDevice gbDevice, Context context, HPlusSupport hplusSupport) {
|
||||||
@ -188,7 +176,7 @@ class HPlusHandlerThread extends GBDeviceIoThread {
|
|||||||
builder.write(mHPlusSupport.ctrlCharacteristic, new byte[]{HPlusConstants.CMD_GET_CURR_DATA});
|
builder.write(mHPlusSupport.ctrlCharacteristic, new byte[]{HPlusConstants.CMD_GET_CURR_DATA});
|
||||||
|
|
||||||
mHPlusSupport.performConnected(builder.getTransaction());
|
mHPlusSupport.performConnected(builder.getTransaction());
|
||||||
} catch(Exception e) {
|
} catch (Exception e) {
|
||||||
LOG.warn("HPlus: Synchronization exception: " + e);
|
LOG.warn("HPlus: Synchronization exception: " + e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,7 +191,7 @@ class HPlusHandlerThread extends GBDeviceIoThread {
|
|||||||
builder.write(mHPlusSupport.ctrlCharacteristic, HPlusConstants.CMD_ACTION_HELLO);
|
builder.write(mHPlusSupport.ctrlCharacteristic, HPlusConstants.CMD_ACTION_HELLO);
|
||||||
mHPlusSupport.performConnected(builder.getTransaction());
|
mHPlusSupport.performConnected(builder.getTransaction());
|
||||||
|
|
||||||
} catch(Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
mHelloTime = GregorianCalendar.getInstance();
|
mHelloTime = GregorianCalendar.getInstance();
|
||||||
@ -213,6 +201,7 @@ class HPlusHandlerThread extends GBDeviceIoThread {
|
|||||||
waitObject.notify();
|
waitObject.notify();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process a message containing information regarding a day slot
|
* Process a message containing information regarding a day slot
|
||||||
* A slot summarizes 10 minutes of data
|
* A slot summarizes 10 minutes of data
|
||||||
@ -224,16 +213,16 @@ class HPlusHandlerThread extends GBDeviceIoThread {
|
|||||||
|
|
||||||
HPlusDataRecordDaySlot record;
|
HPlusDataRecordDaySlot record;
|
||||||
|
|
||||||
try{
|
try {
|
||||||
record = new HPlusDataRecordDaySlot(data, age);
|
record = new HPlusDataRecordDaySlot(data, age);
|
||||||
} catch(IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
LOG.info((e.getMessage()));
|
LOG.info((e.getMessage()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Calendar now = GregorianCalendar.getInstance();
|
Calendar now = GregorianCalendar.getInstance();
|
||||||
int nowSlot = now.get(Calendar.HOUR_OF_DAY) * 6 + (now.get(Calendar.MINUTE) / 10);
|
int nowSlot = now.get(Calendar.HOUR_OF_DAY) * 6 + (now.get(Calendar.MINUTE) / 10);
|
||||||
if (record.slot == nowSlot){
|
if (record.slot == nowSlot) {
|
||||||
if (mCurrentDaySlot != null && mCurrentDaySlot != record) {
|
if (mCurrentDaySlot != null && mCurrentDaySlot != record) {
|
||||||
mCurrentDaySlot.accumulate(record);
|
mCurrentDaySlot.accumulate(record);
|
||||||
mDaySlotRecords.add(mCurrentDaySlot);
|
mDaySlotRecords.add(mCurrentDaySlot);
|
||||||
@ -272,7 +261,7 @@ class HPlusHandlerThread extends GBDeviceIoThread {
|
|||||||
//Keep buffering
|
//Keep buffering
|
||||||
if (record.slot != 143)
|
if (record.slot != 143)
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
mGetDaySlotsTime = GregorianCalendar.getInstance();
|
mGetDaySlotsTime = GregorianCalendar.getInstance();
|
||||||
mGetDaySlotsTime.add(Calendar.DAY_OF_MONTH, 1);
|
mGetDaySlotsTime.add(Calendar.DAY_OF_MONTH, 1);
|
||||||
}
|
}
|
||||||
@ -372,9 +361,9 @@ class HPlusHandlerThread extends GBDeviceIoThread {
|
|||||||
public boolean processIncomingSleepData(byte[] data) {
|
public boolean processIncomingSleepData(byte[] data) {
|
||||||
HPlusDataRecordSleep record;
|
HPlusDataRecordSleep record;
|
||||||
|
|
||||||
try{
|
try {
|
||||||
record = new HPlusDataRecordSleep(data);
|
record = new HPlusDataRecordSleep(data);
|
||||||
} catch(IllegalArgumentException e){
|
} catch (IllegalArgumentException e) {
|
||||||
LOG.info((e.getMessage()));
|
LOG.info((e.getMessage()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -393,7 +382,7 @@ class HPlusHandlerThread extends GBDeviceIoThread {
|
|||||||
List<HPlusHealthActivityOverlay> overlayList = new ArrayList<>();
|
List<HPlusHealthActivityOverlay> overlayList = new ArrayList<>();
|
||||||
List<HPlusDataRecord.RecordInterval> intervals = record.getIntervals();
|
List<HPlusDataRecord.RecordInterval> intervals = record.getIntervals();
|
||||||
|
|
||||||
for(HPlusDataRecord.RecordInterval interval : intervals) {
|
for (HPlusDataRecord.RecordInterval interval : intervals) {
|
||||||
overlayList.add(new HPlusHealthActivityOverlay(interval.timestampFrom, interval.timestampTo, interval.activityKind, deviceId, userId, null));
|
overlayList.add(new HPlusHealthActivityOverlay(interval.timestampFrom, interval.timestampTo, interval.activityKind, deviceId, userId, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -428,7 +417,7 @@ class HPlusHandlerThread extends GBDeviceIoThread {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
record = new HPlusDataRecordRealtime(data, age);
|
record = new HPlusDataRecordRealtime(data, age);
|
||||||
} catch(IllegalArgumentException e){
|
} catch (IllegalArgumentException e) {
|
||||||
LOG.info((e.getMessage()));
|
LOG.info((e.getMessage()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -487,7 +476,7 @@ class HPlusHandlerThread extends GBDeviceIoThread {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
record = new HPlusDataRecordDaySummary(data);
|
record = new HPlusDataRecordDaySummary(data);
|
||||||
} catch(IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
LOG.info((e.getMessage()));
|
LOG.info((e.getMessage()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -527,6 +516,8 @@ class HPlusHandlerThread extends GBDeviceIoThread {
|
|||||||
public boolean processVersion(byte[] data) {
|
public boolean processVersion(byte[] data) {
|
||||||
int major, minor;
|
int major, minor;
|
||||||
|
|
||||||
|
LOG.info("Process Version Data: : '" + new String(data) + "'");
|
||||||
|
|
||||||
if (data.length >= 11) {
|
if (data.length >= 11) {
|
||||||
major = data[10] & 0xFF;
|
major = data[10] & 0xFF;
|
||||||
minor = data[9] & 0xFF;
|
minor = data[9] & 0xFF;
|
||||||
@ -555,7 +546,7 @@ class HPlusHandlerThread extends GBDeviceIoThread {
|
|||||||
TransactionBuilder builder = new TransactionBuilder("requestSleepStats");
|
TransactionBuilder builder = new TransactionBuilder("requestSleepStats");
|
||||||
builder.write(mHPlusSupport.ctrlCharacteristic, new byte[]{HPlusConstants.CMD_GET_SLEEP});
|
builder.write(mHPlusSupport.ctrlCharacteristic, new byte[]{HPlusConstants.CMD_GET_SLEEP});
|
||||||
mHPlusSupport.performConnected(builder.getTransaction());
|
mHPlusSupport.performConnected(builder.getTransaction());
|
||||||
} catch(Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -596,7 +587,7 @@ class HPlusHandlerThread extends GBDeviceIoThread {
|
|||||||
if (mLastSlotReceived == 143)
|
if (mLastSlotReceived == 143)
|
||||||
mLastSlotReceived = -1;
|
mLastSlotReceived = -1;
|
||||||
|
|
||||||
byte hour = (byte) ((mLastSlotReceived + 1)/ 6);
|
byte hour = (byte) ((mLastSlotReceived + 1) / 6);
|
||||||
byte minute = (byte) (((mLastSlotReceived + 1) % 6) * 10);
|
byte minute = (byte) (((mLastSlotReceived + 1) % 6) * 10);
|
||||||
|
|
||||||
byte nextHour = hour;
|
byte nextHour = hour;
|
||||||
@ -610,10 +601,11 @@ class HPlusHandlerThread extends GBDeviceIoThread {
|
|||||||
TransactionBuilder builder = new TransactionBuilder("getNextDaySlot");
|
TransactionBuilder builder = new TransactionBuilder("getNextDaySlot");
|
||||||
builder.write(mHPlusSupport.ctrlCharacteristic, msg);
|
builder.write(mHPlusSupport.ctrlCharacteristic, msg);
|
||||||
mHPlusSupport.performConnected(builder.getTransaction());
|
mHPlusSupport.performConnected(builder.getTransaction());
|
||||||
} catch(Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request a batch of data with the summary of the previous days
|
* Request a batch of data with the summary of the previous days
|
||||||
*/
|
*/
|
||||||
@ -622,7 +614,7 @@ class HPlusHandlerThread extends GBDeviceIoThread {
|
|||||||
TransactionBuilder builder = new TransactionBuilder("startSyncDaySummary");
|
TransactionBuilder builder = new TransactionBuilder("startSyncDaySummary");
|
||||||
builder.write(mHPlusSupport.ctrlCharacteristic, new byte[]{HPlusConstants.CMD_GET_DAY_DATA});
|
builder.write(mHPlusSupport.ctrlCharacteristic, new byte[]{HPlusConstants.CMD_GET_DAY_DATA});
|
||||||
mHPlusSupport.performConnected(builder.getTransaction());
|
mHPlusSupport.performConnected(builder.getTransaction());
|
||||||
} catch(Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
mGetDaySummaryTime = GregorianCalendar.getInstance();
|
mGetDaySummaryTime = GregorianCalendar.getInstance();
|
||||||
@ -631,6 +623,7 @@ class HPlusHandlerThread extends GBDeviceIoThread {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function to create a sample
|
* Helper function to create a sample
|
||||||
|
*
|
||||||
* @param dbHandler The database handler
|
* @param dbHandler The database handler
|
||||||
* @param timestamp The sample timestamp
|
* @param timestamp The sample timestamp
|
||||||
* @return The sample just created
|
* @return The sample just created
|
||||||
|
@ -18,8 +18,8 @@
|
|||||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.hplus;
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.hplus;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @author João Paulo Barraca <jpbarraca@gmail.com>
|
* @author João Paulo Barraca <jpbarraca@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import android.bluetooth.BluetoothGatt;
|
import android.bluetooth.BluetoothGatt;
|
||||||
import android.bluetooth.BluetoothGattCharacteristic;
|
import android.bluetooth.BluetoothGattCharacteristic;
|
||||||
@ -44,6 +44,7 @@ import nodomain.freeyourgadget.gadgetbridge.activities.SettingsActivity;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo;
|
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.hplus.HPlusConstants;
|
import nodomain.freeyourgadget.gadgetbridge.devices.hplus.HPlusConstants;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.hplus.HPlusCoordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.hplus.HPlusCoordinator;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.hplus.HPlusWeatherCode;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
|
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
|
||||||
@ -58,19 +59,15 @@ import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.deviceinfo.DeviceInfo;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.deviceinfo.DeviceInfo;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.pebble.webview.CurrentPosition;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.AlarmUtils;
|
import nodomain.freeyourgadget.gadgetbridge.util.AlarmUtils;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
|
|
||||||
|
|
||||||
|
|
||||||
public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(HPlusSupport.class);
|
private static final Logger LOG = LoggerFactory.getLogger(HPlusSupport.class);
|
||||||
|
private final GBDeviceEventBatteryInfo batteryCmd = new GBDeviceEventBatteryInfo();
|
||||||
public BluetoothGattCharacteristic ctrlCharacteristic = null;
|
public BluetoothGattCharacteristic ctrlCharacteristic = null;
|
||||||
public BluetoothGattCharacteristic measureCharacteristic = null;
|
public BluetoothGattCharacteristic measureCharacteristic = null;
|
||||||
|
|
||||||
private final GBDeviceEventBatteryInfo batteryCmd = new GBDeviceEventBatteryInfo();
|
|
||||||
|
|
||||||
private HPlusHandlerThread syncHelper;
|
private HPlusHandlerThread syncHelper;
|
||||||
private DeviceType deviceType = DeviceType.UNKNOWN;
|
private DeviceType deviceType = DeviceType.UNKNOWN;
|
||||||
|
|
||||||
@ -110,7 +107,7 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
|||||||
gbDevice.setState(GBDevice.State.INITIALIZED);
|
gbDevice.setState(GBDevice.State.INITIALIZED);
|
||||||
gbDevice.sendDeviceUpdateIntent(getContext());
|
gbDevice.sendDeviceUpdateIntent(getContext());
|
||||||
|
|
||||||
if(syncHelper == null) {
|
if (syncHelper == null) {
|
||||||
syncHelper = new HPlusHandlerThread(getDevice(), getContext(), this);
|
syncHelper = new HPlusHandlerThread(getDevice(), getContext(), this);
|
||||||
syncHelper.start();
|
syncHelper.start();
|
||||||
}
|
}
|
||||||
@ -417,7 +414,7 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
|||||||
setCurrentDate(builder);
|
setCurrentDate(builder);
|
||||||
setCurrentTime(builder);
|
setCurrentTime(builder);
|
||||||
builder.queue(getQueue());
|
builder.queue(getQueue());
|
||||||
}catch(IOException e){
|
} catch (IOException e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -450,7 +447,8 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
|||||||
builder.queue(getQueue());
|
builder.queue(getQueue());
|
||||||
|
|
||||||
GB.toast(getContext(), getContext().getString(R.string.user_feedback_all_alarms_disabled), Toast.LENGTH_SHORT, GB.INFO);
|
GB.toast(getContext(), getContext().getString(R.string.user_feedback_all_alarms_disabled), Toast.LENGTH_SHORT, GB.INFO);
|
||||||
}catch(Exception e){}
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -518,7 +516,7 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
|||||||
@Override
|
@Override
|
||||||
public void onFetchRecordedData(int dataTypes) {
|
public void onFetchRecordedData(int dataTypes) {
|
||||||
|
|
||||||
if (syncHelper == null){
|
if (syncHelper == null) {
|
||||||
syncHelper = new HPlusHandlerThread(gbDevice, getContext(), this);
|
syncHelper = new HPlusHandlerThread(gbDevice, getContext(), this);
|
||||||
syncHelper.start();
|
syncHelper.start();
|
||||||
}
|
}
|
||||||
@ -534,7 +532,7 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
|||||||
TransactionBuilder builder = performInitialized("Shutdown");
|
TransactionBuilder builder = performInitialized("Shutdown");
|
||||||
builder.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_SHUTDOWN, HPlusConstants.ARG_SHUTDOWN_EN});
|
builder.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_SHUTDOWN, HPlusConstants.ARG_SHUTDOWN_EN});
|
||||||
builder.queue(getQueue());
|
builder.queue(getQueue());
|
||||||
}catch(Exception e){
|
} catch (Exception e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -542,12 +540,12 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
|||||||
@Override
|
@Override
|
||||||
public void onHeartRateTest() {
|
public void onHeartRateTest() {
|
||||||
getQueue().clear();
|
getQueue().clear();
|
||||||
try{
|
try {
|
||||||
TransactionBuilder builder = performInitialized("HeartRateTest");
|
TransactionBuilder builder = performInitialized("HeartRateTest");
|
||||||
|
|
||||||
builder.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_SET_HEARTRATE_STATE, HPlusConstants.ARG_HEARTRATE_MEASURE_ON}); //Set Real Time... ?
|
builder.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_SET_HEARTRATE_STATE, HPlusConstants.ARG_HEARTRATE_MEASURE_ON}); //Set Real Time... ?
|
||||||
builder.queue(getQueue());
|
builder.queue(getQueue());
|
||||||
}catch(Exception e){
|
} catch (Exception e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -565,7 +563,7 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
|||||||
|
|
||||||
builder.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_SET_ALLDAY_HRM, state});
|
builder.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_SET_ALLDAY_HRM, state});
|
||||||
builder.queue(getQueue());
|
builder.queue(getQueue());
|
||||||
}catch(Exception e){
|
} catch (Exception e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -655,10 +653,53 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSendWeather(WeatherSpec weatherSpec) {
|
public void onSendWeather(WeatherSpec weatherSpec) {
|
||||||
|
try {
|
||||||
|
TransactionBuilder builder = performInitialized("sendWeather");
|
||||||
|
|
||||||
|
int windSpeed = (int) weatherSpec.windSpeed;
|
||||||
|
|
||||||
|
CurrentPosition currentPosition = new CurrentPosition();
|
||||||
|
|
||||||
|
int altitude = 0;
|
||||||
|
if (currentPosition.getLastKnownLocation() != null) {
|
||||||
|
altitude = (int) currentPosition.getLastKnownLocation().getAltitude();
|
||||||
|
}
|
||||||
|
|
||||||
|
int weatherCode = HPlusWeatherCode.mapOpenWeatherConditionToHPlusCondition(weatherSpec.currentConditionCode);
|
||||||
|
|
||||||
|
LOG.info("[WEATHER] currentConditionCode={} altitude={} temp={}", weatherCode, altitude, weatherSpec.currentTemp);
|
||||||
|
|
||||||
|
byte[] weatherInfo = new byte[]{(byte) HPlusConstants.CMD_SET_WEATHER_STATE,
|
||||||
|
(byte) ((weatherCode >> 8) & 255),
|
||||||
|
(byte) (weatherCode & 255),
|
||||||
|
(byte) weatherSpec.windDirection, (byte) 0, // weatherSpec.getWinPower(),
|
||||||
|
(byte) ((windSpeed >> 8) & 255),
|
||||||
|
(byte) (windSpeed & 255),
|
||||||
|
(byte) (weatherSpec.currentTemp - 17),
|
||||||
|
// base temperature information start at 17d celsius
|
||||||
|
(byte) (weatherSpec.todayMaxTemp - 17), // base temperature information start at 18d celsius
|
||||||
|
(byte) (weatherSpec.todayMinTemp - 17), // base temperature information start at 18d celsius
|
||||||
|
(byte) 0, // Life Index always 0
|
||||||
|
(byte) 0, // (byte) (weatherSpec.getPressure() & 255),
|
||||||
|
(byte) 0, // (byte) ((weatherSpec.getPressure() >> 8) & 255),
|
||||||
|
(byte) 0, // (byte) ((weatherSpec.getPressure() >> 16) & 255),
|
||||||
|
(byte) 0, // (byte) ((weatherSpec.getPressure() >> 24) & 255),
|
||||||
|
(byte) (byte) (altitude & 255),
|
||||||
|
(byte) (byte) ((altitude >> 8) & 255),
|
||||||
|
(byte) (byte) ((altitude >> 16) & 255),
|
||||||
|
(byte) (byte) ((altitude >> 24) & 255),
|
||||||
|
(byte) 0 // (byte)
|
||||||
|
};
|
||||||
|
|
||||||
|
builder.write(ctrlCharacteristic, weatherInfo);
|
||||||
|
builder.queue(getQueue());
|
||||||
|
} catch (IOException e) {
|
||||||
|
GB.toast(getContext(), "Error toggling Send Weather: " + e.getLocalizedMessage(), Toast.LENGTH_LONG,
|
||||||
|
GB.ERROR);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUnicodeSupport(boolean support){
|
public void setUnicodeSupport(boolean support) {
|
||||||
HPlusCoordinator.setUnicodeSupport(gbDevice.getAddress(), support);
|
HPlusCoordinator.setUnicodeSupport(gbDevice.getAddress(), support);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -673,13 +714,17 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
|||||||
|
|
||||||
//Show Call Icon
|
//Show Call Icon
|
||||||
builder.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_SET_INCOMING_CALL, HPlusConstants.ARG_INCOMING_CALL});
|
builder.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_SET_INCOMING_CALL, HPlusConstants.ARG_INCOMING_CALL});
|
||||||
|
builder.write(ctrlCharacteristic,
|
||||||
|
new byte[]{HPlusConstants.CMD_SET_INCOMING_CALL, HPlusConstants.ARG_INCOMING_CALL});
|
||||||
|
|
||||||
if(name != null) {
|
byte space = encodeStringToDevice(" ")[0];
|
||||||
|
|
||||||
|
if (name != null) {
|
||||||
byte[] msg = new byte[13];
|
byte[] msg = new byte[13];
|
||||||
|
|
||||||
//Show call name
|
// Show call name
|
||||||
for (int i = 0; i < msg.length; i++)
|
for (int i = 0; i < msg.length; i++)
|
||||||
msg[i] = ' ';
|
msg[i] = space;
|
||||||
|
|
||||||
byte[] nameBytes = encodeStringToDevice(name);
|
byte[] nameBytes = encodeStringToDevice(name);
|
||||||
for (int i = 0; i < nameBytes.length && i < (msg.length - 1); i++)
|
for (int i = 0; i < nameBytes.length && i < (msg.length - 1); i++)
|
||||||
@ -692,7 +737,7 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
|||||||
builder.write(ctrlCharacteristic, msg);
|
builder.write(ctrlCharacteristic, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(rawNumber != null) {
|
if (rawNumber != null) {
|
||||||
StringBuilder number = new StringBuilder();
|
StringBuilder number = new StringBuilder();
|
||||||
|
|
||||||
//Clean up number as the device only accepts digits
|
//Clean up number as the device only accepts digits
|
||||||
@ -706,7 +751,7 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
|||||||
|
|
||||||
//Show call number
|
//Show call number
|
||||||
for (int i = 0; i < msg.length; i++)
|
for (int i = 0; i < msg.length; i++)
|
||||||
msg[i] = ' ';
|
msg[i] = space;
|
||||||
|
|
||||||
for (int i = 0; i < number.length() && i < (msg.length - 1); i++)
|
for (int i = 0; i < number.length() && i < (msg.length - 1); i++)
|
||||||
msg[i + 1] = (byte) number.charAt(i);
|
msg[i + 1] = (byte) number.charAt(i);
|
||||||
@ -731,7 +776,8 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
|||||||
String message = "";
|
String message = "";
|
||||||
|
|
||||||
if (title != null && title.length() > 0) {
|
if (title != null && title.length() > 0) {
|
||||||
message = StringUtils.pad(StringUtils.truncate(title, 16), 16); //Limit title to top row
|
message += title + " : ";
|
||||||
|
//message = StringUtils.pad(StringUtils.truncate(title, 16), 16); // Limit title to top row
|
||||||
}
|
}
|
||||||
|
|
||||||
if (body != null) {
|
if (body != null) {
|
||||||
@ -742,22 +788,28 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
|||||||
|
|
||||||
int length = messageBytes.length / 17;
|
int length = messageBytes.length / 17;
|
||||||
|
|
||||||
length = length > 5 ? 5 : length;
|
int linesNumbers = HPlusCoordinator.getNotificationLinesNumber(this.gbDevice.getAddress());
|
||||||
|
length = length > linesNumbers ? linesNumbers : length;
|
||||||
|
LOG.info("msglength:" + messageBytes.length + " length:" + length + " linesNumbers:" + linesNumbers);
|
||||||
|
|
||||||
builder.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_SET_INCOMING_MESSAGE, HPlusConstants.ARG_INCOMING_MESSAGE});
|
if (HPlusCoordinator.getDisplayIncomingMessageIcon(this.gbDevice.getAddress()))
|
||||||
|
builder.write(ctrlCharacteristic,
|
||||||
|
new byte[]{HPlusConstants.CMD_SET_INCOMING_MESSAGE, HPlusConstants.ARG_INCOMING_MESSAGE});
|
||||||
|
|
||||||
int remaining = Math.min(255, (messageBytes.length % 17 > 0) ? length + 1 : length);
|
int remaining = Math.min(255, (messageBytes.length % 17 > 0) ? length + 1 : length);
|
||||||
|
|
||||||
byte[] msg = new byte[20];
|
byte[] msgSpace = new byte[20];
|
||||||
msg[0] = HPlusConstants.CMD_ACTION_DISPLAY_TEXT;
|
byte[] msg;
|
||||||
msg[1] = (byte) remaining;
|
|
||||||
|
|
||||||
for (int i = 2; i < msg.length; i++)
|
Arrays.fill(msgSpace, encodeStringToDevice(" ")[0]);
|
||||||
msg[i] = ' ';
|
|
||||||
|
msgSpace[0] = HPlusConstants.CMD_ACTION_DISPLAY_TEXT;
|
||||||
|
msgSpace[1] = (byte) remaining;
|
||||||
|
|
||||||
int message_index = 0;
|
int message_index = 0;
|
||||||
int i = 3;
|
int i = 3;
|
||||||
|
|
||||||
|
msg = msgSpace.clone();
|
||||||
for (int j = 0; j < messageBytes.length; j++) {
|
for (int j = 0; j < messageBytes.length; j++) {
|
||||||
msg[i++] = messageBytes[j];
|
msg[i++] = messageBytes[j];
|
||||||
|
|
||||||
@ -766,10 +818,7 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
|||||||
msg[2] = (byte) message_index;
|
msg[2] = (byte) message_index;
|
||||||
builder.write(ctrlCharacteristic, msg);
|
builder.write(ctrlCharacteristic, msg);
|
||||||
|
|
||||||
msg = msg.clone();
|
msg = msgSpace.clone();
|
||||||
for (i = 3; i < msg.length; i++)
|
|
||||||
msg[i] = ' ';
|
|
||||||
|
|
||||||
if (message_index < remaining)
|
if (message_index < remaining)
|
||||||
i = 3;
|
i = 3;
|
||||||
else
|
else
|
||||||
@ -809,6 +858,16 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
|||||||
boolean unicode = HPlusCoordinator.getUnicodeSupport(this.gbDevice.getAddress());
|
boolean unicode = HPlusCoordinator.getUnicodeSupport(this.gbDevice.getAddress());
|
||||||
LOG.info("Encode String: Unicode=" + unicode);
|
LOG.info("Encode String: Unicode=" + unicode);
|
||||||
|
|
||||||
|
if (unicode) {
|
||||||
|
try {
|
||||||
|
return s.getBytes("Unicode");
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
// Fallback. Result string may be strange, but better than nothing
|
||||||
|
LOG.error("Could not convert String to Bytes: " + e.getMessage());
|
||||||
|
return s.getBytes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < s.length(); i++) {
|
for (int i = 0; i < s.length(); i++) {
|
||||||
Character c = s.charAt(i);
|
Character c = s.charAt(i);
|
||||||
byte[] cs;
|
byte[] cs;
|
||||||
@ -817,10 +876,7 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
|||||||
cs = HPlusConstants.transliterateMap.get(c);
|
cs = HPlusConstants.transliterateMap.get(c);
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
if(unicode)
|
cs = c.toString().getBytes("GB2312");
|
||||||
cs = c.toString().getBytes("Unicode");
|
|
||||||
else
|
|
||||||
cs = c.toString().getBytes("GB2312");
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
} catch (UnsupportedEncodingException e) {
|
||||||
//Fallback. Result string may be strange, but better than nothing
|
//Fallback. Result string may be strange, but better than nothing
|
||||||
cs = c.toString().getBytes();
|
cs = c.toString().getBytes();
|
||||||
@ -828,8 +884,7 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final int j0 = (unicode && i != 0) ? 2 : 0;
|
for (int j = 0; j < cs.length; j++)
|
||||||
for (int j = j0; j < cs.length; j++)
|
|
||||||
outBytes.add(cs[j]);
|
outBytes.add(cs[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -856,7 +911,7 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
|||||||
case HPlusConstants.DATA_STATS:
|
case HPlusConstants.DATA_STATS:
|
||||||
boolean result = syncHelper.processRealtimeStats(data, HPlusCoordinator.getUserAge());
|
boolean result = syncHelper.processRealtimeStats(data, HPlusCoordinator.getUserAge());
|
||||||
if (result) {
|
if (result) {
|
||||||
processExtraInfo (data);
|
processExtraInfo(data);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
@ -878,7 +933,7 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processExtraInfo (byte[] data) {
|
private void processExtraInfo(byte[] data) {
|
||||||
try {
|
try {
|
||||||
HPlusDataRecordRealtime record = new HPlusDataRecordRealtime(data, HPlusCoordinator.getUserAge());
|
HPlusDataRecordRealtime record = new HPlusDataRecordRealtime(data, HPlusCoordinator.getUserAge());
|
||||||
|
|
||||||
@ -912,10 +967,10 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void handleBatteryInfo(byte data) {
|
private void handleBatteryInfo(byte data) {
|
||||||
if (batteryCmd.level != (short) data) {
|
if (batteryCmd.level != (short) data) {
|
||||||
batteryCmd.level = (short) data;
|
batteryCmd.level = (short) data;
|
||||||
handleGBDeviceEvent(batteryCmd);
|
handleGBDeviceEvent(batteryCmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user