mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2025-01-10 17:11:56 +01:00
parent
820a5b9800
commit
8d24dfa7e4
@ -231,6 +231,14 @@ public class HuaweiTLV {
|
|||||||
return ByteBuffer.wrap(getBytes(tag)).getInt();
|
return ByteBuffer.wrap(getBytes(tag)).getInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Integer getInteger(int tag, Integer defaultResult) {
|
||||||
|
try {
|
||||||
|
return getInteger(tag);
|
||||||
|
} catch (HuaweiPacket.MissingTagException e) {
|
||||||
|
return defaultResult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Short getShort(int tag) throws HuaweiPacket.MissingTagException {
|
public Short getShort(int tag) throws HuaweiPacket.MissingTagException {
|
||||||
return ByteBuffer.wrap(getBytes(tag)).getShort();
|
return ByteBuffer.wrap(getBytes(tag)).getShort();
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ import java.io.IOException;
|
|||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.time.LocalTime;
|
import java.time.LocalTime;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -57,6 +58,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.MusicControl;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.FileUpload;
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.FileUpload;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Watchface;
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Watchface;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Weather;
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Weather;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.Request;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.Request;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.GetPhoneInfoRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.GetPhoneInfoRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendFileUploadComplete;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendFileUploadComplete;
|
||||||
@ -523,15 +525,7 @@ public class AsynchronousResponse {
|
|||||||
|
|
||||||
private void handleWeatherCheck(HuaweiPacket response) {
|
private void handleWeatherCheck(HuaweiPacket response) {
|
||||||
if (response.serviceId == Weather.id && response.commandId == 0x04) {
|
if (response.serviceId == Weather.id && response.commandId == 0x04) {
|
||||||
// Send back ok
|
support.huaweiWeatherManager.handleAsyncMessage(response);
|
||||||
try {
|
|
||||||
SendWeatherDeviceRequest sendWeatherDeviceRequest = new SendWeatherDeviceRequest(this.support);
|
|
||||||
sendWeatherDeviceRequest.doPerform();
|
|
||||||
} catch (IOException e) {
|
|
||||||
LOG.error("Could not send weather device request", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: send back weather?
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,8 +16,6 @@
|
|||||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei;
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei;
|
||||||
|
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants.HUAWEI_MAGIC;
|
|
||||||
|
|
||||||
import android.bluetooth.BluetoothGattCharacteristic;
|
import android.bluetooth.BluetoothGattCharacteristic;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
@ -32,7 +30,6 @@ import androidx.annotation.NonNull;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -105,20 +102,12 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.Send
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendDeviceReportThreshold;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendDeviceReportThreshold;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendExtendedAccountRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendExtendedAccountRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendFitnessUserInfoRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendFitnessUserInfoRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendGpsAndTimeToDeviceRequest;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendGpsDataRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendGpsDataRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendFileUploadInfo;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendFileUploadInfo;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendRunPaceConfigRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendRunPaceConfigRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendSetContactsRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendSetContactsRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendWeatherCurrentRequest;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendNotifyHeartRateCapabilityRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendNotifyHeartRateCapabilityRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendNotifyRestHeartRateCapabilityRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendNotifyRestHeartRateCapabilityRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendWeatherExtendedSupportRequest;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendWeatherForecastRequest;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendWeatherStartRequest;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendWeatherSunMoonSupportRequest;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendWeatherSupportRequest;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendWeatherUnitRequest;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SetAutomaticHeartrateRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SetAutomaticHeartrateRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SetAutomaticSpoRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SetAutomaticSpoRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SetDisconnectNotification;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SetDisconnectNotification;
|
||||||
@ -220,6 +209,8 @@ public class HuaweiSupportProvider {
|
|||||||
|
|
||||||
protected HuaweiAppManager huaweiAppManager = new HuaweiAppManager(this);
|
protected HuaweiAppManager huaweiAppManager = new HuaweiAppManager(this);
|
||||||
|
|
||||||
|
protected HuaweiWeatherManager huaweiWeatherManager = new HuaweiWeatherManager(this);
|
||||||
|
|
||||||
public HuaweiCoordinatorSupplier getCoordinator() {
|
public HuaweiCoordinatorSupplier getCoordinator() {
|
||||||
return ((HuaweiCoordinatorSupplier) this.gbDevice.getDeviceCoordinator());
|
return ((HuaweiCoordinatorSupplier) this.gbDevice.getDeviceCoordinator());
|
||||||
}
|
}
|
||||||
@ -1791,131 +1782,11 @@ public class HuaweiSupportProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Weather.WeatherIcon openWeatherMapConditionCodeToHuaweiIcon(int conditionCode) {
|
public Weather.WeatherIcon openWeatherMapConditionCodeToHuaweiIcon(int conditionCode) {
|
||||||
// More exact first, groups after
|
return huaweiWeatherManager.openWeatherMapConditionCodeToHuaweiIcon(conditionCode);
|
||||||
switch (conditionCode) {
|
|
||||||
case 500:
|
|
||||||
return Weather.WeatherIcon.LIGHT_RAIN;
|
|
||||||
case 501:
|
|
||||||
return Weather.WeatherIcon.RAIN;
|
|
||||||
case 502:
|
|
||||||
return Weather.WeatherIcon.HEAVY_RAIN;
|
|
||||||
case 503:
|
|
||||||
return Weather.WeatherIcon.RAIN_STORM;
|
|
||||||
case 504:
|
|
||||||
return Weather.WeatherIcon.SEVERE_RAIN_STORMS;
|
|
||||||
case 511:
|
|
||||||
return Weather.WeatherIcon.FREEZING_RAIN;
|
|
||||||
case 600:
|
|
||||||
return Weather.WeatherIcon.LIGHT_SNOW;
|
|
||||||
case 601:
|
|
||||||
return Weather.WeatherIcon.SNOW;
|
|
||||||
case 602:
|
|
||||||
return Weather.WeatherIcon.HEAVY_SNOW;
|
|
||||||
case 611:
|
|
||||||
return Weather.WeatherIcon.SLEET;
|
|
||||||
case 701:
|
|
||||||
case 741:
|
|
||||||
return Weather.WeatherIcon.FOG;
|
|
||||||
case 721:
|
|
||||||
return Weather.WeatherIcon.HAZY;
|
|
||||||
case 751:
|
|
||||||
return Weather.WeatherIcon.SAND;
|
|
||||||
case 761:
|
|
||||||
return Weather.WeatherIcon.DUST;
|
|
||||||
case 800:
|
|
||||||
return Weather.WeatherIcon.SUNNY;
|
|
||||||
case 801:
|
|
||||||
case 802:
|
|
||||||
return Weather.WeatherIcon.CLOUDY;
|
|
||||||
case 803:
|
|
||||||
case 804:
|
|
||||||
return Weather.WeatherIcon.OVERCAST;
|
|
||||||
}
|
|
||||||
if (conditionCode >= 200 && conditionCode < 300)
|
|
||||||
return Weather.WeatherIcon.THUNDERSTORMS;
|
|
||||||
if (conditionCode >= 300 && conditionCode < 400)
|
|
||||||
return Weather.WeatherIcon.LIGHT_RAIN;
|
|
||||||
if (conditionCode >= 500 && conditionCode < 600)
|
|
||||||
return Weather.WeatherIcon.RAIN;
|
|
||||||
if (conditionCode >= 600 && conditionCode < 700)
|
|
||||||
return Weather.WeatherIcon.SNOW;
|
|
||||||
return Weather.WeatherIcon.UNKNOWN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onSendWeather(ArrayList<WeatherSpec> weatherSpecs) {
|
public void onSendWeather(ArrayList<WeatherSpec> weatherSpecs) {
|
||||||
// Initialize weather settings and send weather
|
huaweiWeatherManager.sendWeather(weatherSpecs.get(0));
|
||||||
if (!getHuaweiCoordinator().supportsWeather()) {
|
|
||||||
LOG.error("onSendWeather called while weather is not supported.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
WeatherSpec weatherSpec = weatherSpecs.get(0);
|
|
||||||
|
|
||||||
Weather.Settings weatherSettings = new Weather.Settings();
|
|
||||||
weatherSettings.uvIndexSupported = getHuaweiCoordinator().supportsWeatherUvIndex();
|
|
||||||
|
|
||||||
SendWeatherStartRequest weatherStartRequest = new SendWeatherStartRequest(this, weatherSettings);
|
|
||||||
try {
|
|
||||||
weatherStartRequest.doPerform();
|
|
||||||
} catch (IOException e) {
|
|
||||||
// TODO: Use translatable string
|
|
||||||
GB.toast(context, "Failed to send start weather", Toast.LENGTH_SHORT, GB.ERROR, e);
|
|
||||||
LOG.error("Failed to send start weather", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
Request firstRequest = null;
|
|
||||||
Request lastRequest = null;
|
|
||||||
|
|
||||||
if (getHuaweiCoordinator().supportsWeatherUnit()) {
|
|
||||||
SendWeatherUnitRequest weatherUnitRequest = new SendWeatherUnitRequest(this);
|
|
||||||
firstRequest = weatherUnitRequest;
|
|
||||||
lastRequest = weatherUnitRequest;
|
|
||||||
}
|
|
||||||
|
|
||||||
SendWeatherSupportRequest weatherSupportRequest = new SendWeatherSupportRequest(this, weatherSettings);
|
|
||||||
if (firstRequest == null) {
|
|
||||||
firstRequest = weatherSupportRequest;
|
|
||||||
} else {
|
|
||||||
lastRequest.nextRequest(weatherSupportRequest);
|
|
||||||
}
|
|
||||||
lastRequest = weatherSupportRequest;
|
|
||||||
|
|
||||||
|
|
||||||
if (getHuaweiCoordinator().supportsWeatherExtended()) {
|
|
||||||
SendWeatherExtendedSupportRequest weatherExtendedSupportRequest = new SendWeatherExtendedSupportRequest(this, weatherSettings);
|
|
||||||
lastRequest.nextRequest(weatherExtendedSupportRequest);
|
|
||||||
lastRequest = weatherExtendedSupportRequest;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getHuaweiCoordinator().supportsWeatherMoonRiseSet()) {
|
|
||||||
SendWeatherSunMoonSupportRequest weatherSunMoonSupportRequest = new SendWeatherSunMoonSupportRequest(this, weatherSettings);
|
|
||||||
lastRequest.nextRequest(weatherSunMoonSupportRequest);
|
|
||||||
lastRequest = weatherSunMoonSupportRequest;
|
|
||||||
}
|
|
||||||
|
|
||||||
// End of initialization and start of actually sending weather
|
|
||||||
|
|
||||||
SendWeatherCurrentRequest sendWeatherCurrentRequest = new SendWeatherCurrentRequest(this, weatherSettings, weatherSpec);
|
|
||||||
lastRequest.nextRequest(sendWeatherCurrentRequest);
|
|
||||||
lastRequest = sendWeatherCurrentRequest;
|
|
||||||
|
|
||||||
SendGpsAndTimeToDeviceRequest sendGpsAndTimeToDeviceRequest = new SendGpsAndTimeToDeviceRequest(this);
|
|
||||||
lastRequest.nextRequest(sendGpsAndTimeToDeviceRequest);
|
|
||||||
lastRequest = sendGpsAndTimeToDeviceRequest;
|
|
||||||
|
|
||||||
if (getHuaweiCoordinator().supportsWeatherForecasts()) {
|
|
||||||
SendWeatherForecastRequest sendWeatherForecastRequest = new SendWeatherForecastRequest(this, weatherSettings, weatherSpec);
|
|
||||||
lastRequest.nextRequest(sendWeatherForecastRequest);
|
|
||||||
lastRequest = sendWeatherForecastRequest;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
firstRequest.doPerform();
|
|
||||||
} catch (IOException e) {
|
|
||||||
// TODO: Use translatable string
|
|
||||||
GB.toast(context, "Failed to send weather", Toast.LENGTH_SHORT, GB.ERROR, e);
|
|
||||||
LOG.error("Failed to send weather", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onSetGpsLocation(Location location) {
|
public void onSetGpsLocation(Location location) {
|
||||||
|
@ -0,0 +1,292 @@
|
|||||||
|
/* Copyright (C) 2024 Martin.JM
|
||||||
|
|
||||||
|
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 <https://www.gnu.org/licenses/>. */
|
||||||
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei;
|
||||||
|
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Weather;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.Request;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendGpsAndTimeToDeviceRequest;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendWeatherCurrentRequest;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendWeatherDeviceRequest;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendWeatherExtendedSupportRequest;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendWeatherForecastRequest;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendWeatherStartRequest;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendWeatherSunMoonSupportRequest;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendWeatherSupportRequest;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendWeatherUnitRequest;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||||
|
|
||||||
|
public class HuaweiWeatherManager {
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(HuaweiWeatherManager.class);
|
||||||
|
|
||||||
|
private final HuaweiSupportProvider supportProvider;
|
||||||
|
private boolean syncInProgress;
|
||||||
|
|
||||||
|
public HuaweiWeatherManager(HuaweiSupportProvider supportProvider) {
|
||||||
|
this.supportProvider = supportProvider;
|
||||||
|
this.syncInProgress = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Weather.WeatherIcon openWeatherMapConditionCodeToHuaweiIcon(int conditionCode) {
|
||||||
|
// More exact first, groups after
|
||||||
|
switch (conditionCode) {
|
||||||
|
case 500:
|
||||||
|
return Weather.WeatherIcon.LIGHT_RAIN;
|
||||||
|
case 501:
|
||||||
|
return Weather.WeatherIcon.RAIN;
|
||||||
|
case 502:
|
||||||
|
return Weather.WeatherIcon.HEAVY_RAIN;
|
||||||
|
case 503:
|
||||||
|
return Weather.WeatherIcon.RAIN_STORM;
|
||||||
|
case 504:
|
||||||
|
return Weather.WeatherIcon.SEVERE_RAIN_STORMS;
|
||||||
|
case 511:
|
||||||
|
return Weather.WeatherIcon.FREEZING_RAIN;
|
||||||
|
case 600:
|
||||||
|
return Weather.WeatherIcon.LIGHT_SNOW;
|
||||||
|
case 601:
|
||||||
|
return Weather.WeatherIcon.SNOW;
|
||||||
|
case 602:
|
||||||
|
return Weather.WeatherIcon.HEAVY_SNOW;
|
||||||
|
case 611:
|
||||||
|
return Weather.WeatherIcon.SLEET;
|
||||||
|
case 701:
|
||||||
|
case 741:
|
||||||
|
return Weather.WeatherIcon.FOG;
|
||||||
|
case 721:
|
||||||
|
return Weather.WeatherIcon.HAZY;
|
||||||
|
case 751:
|
||||||
|
return Weather.WeatherIcon.SAND;
|
||||||
|
case 761:
|
||||||
|
return Weather.WeatherIcon.DUST;
|
||||||
|
case 800:
|
||||||
|
return Weather.WeatherIcon.SUNNY;
|
||||||
|
case 801:
|
||||||
|
case 802:
|
||||||
|
return Weather.WeatherIcon.CLOUDY;
|
||||||
|
case 803:
|
||||||
|
case 804:
|
||||||
|
return Weather.WeatherIcon.OVERCAST;
|
||||||
|
}
|
||||||
|
if (conditionCode >= 200 && conditionCode < 300)
|
||||||
|
return Weather.WeatherIcon.THUNDERSTORMS;
|
||||||
|
if (conditionCode >= 300 && conditionCode < 400)
|
||||||
|
return Weather.WeatherIcon.LIGHT_RAIN;
|
||||||
|
if (conditionCode >= 500 && conditionCode < 600)
|
||||||
|
return Weather.WeatherIcon.RAIN;
|
||||||
|
if (conditionCode >= 600 && conditionCode < 700)
|
||||||
|
return Weather.WeatherIcon.SNOW;
|
||||||
|
return Weather.WeatherIcon.UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleException(Request.ResponseParseException e) {
|
||||||
|
LOG.error("Error in weather sending", e);
|
||||||
|
|
||||||
|
synchronized (this) {
|
||||||
|
// Allow a new sync to start again
|
||||||
|
this.syncInProgress = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is to reset the syncInProgress flag when an error occurs
|
||||||
|
private final Request.RequestCallback errorHandler = new Request.RequestCallback() {
|
||||||
|
@Override
|
||||||
|
public void handleException(Request.ResponseParseException e) {
|
||||||
|
HuaweiWeatherManager.this.handleException(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// This is to reset the syncInProgress flag when everything goes well, or an error occurs
|
||||||
|
// Only for the last request in the chain
|
||||||
|
private final Request.RequestCallback lastHandler = new Request.RequestCallback() {
|
||||||
|
@Override
|
||||||
|
public void call() {
|
||||||
|
synchronized (this) {
|
||||||
|
HuaweiWeatherManager.this.syncInProgress = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleException(Request.ResponseParseException e) {
|
||||||
|
HuaweiWeatherManager.this.handleException(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private boolean timeOutOfDateInterval(int check, Date start, Date end) {
|
||||||
|
return check * 1000L <= start.getTime() || check * 1000L > end.getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Some erroneous data will stop the watch from showing any weather data at all, this attempts
|
||||||
|
* to remove such data.
|
||||||
|
*/
|
||||||
|
private void fixupWeather(WeatherSpec weatherSpec) {
|
||||||
|
// Ignore sun/moon data if they are not in the correct day
|
||||||
|
// If this is wrong the watch does not display any weather data at all
|
||||||
|
Date currentDay = DateTimeUtils.dayStart(DateTimeUtils.todayUTC());
|
||||||
|
Date nextDay = DateTimeUtils.shiftByDays(currentDay, 1);
|
||||||
|
|
||||||
|
if (timeOutOfDateInterval(weatherSpec.sunRise, currentDay, nextDay)) {
|
||||||
|
LOG.warn("Sun rise for today out of bounds: {}", DateTimeUtils.parseTimeStamp(weatherSpec.sunRise));
|
||||||
|
weatherSpec.sunRise = 0;
|
||||||
|
}
|
||||||
|
if (timeOutOfDateInterval(weatherSpec.sunSet, currentDay, nextDay)) {
|
||||||
|
LOG.warn("Sun set for today out of bounds: {}", DateTimeUtils.parseTimeStamp(weatherSpec.sunSet));
|
||||||
|
weatherSpec.sunSet = 0;
|
||||||
|
}
|
||||||
|
if (timeOutOfDateInterval(weatherSpec.moonRise, currentDay, nextDay)) {
|
||||||
|
LOG.warn("Moon rise for today out of bounds: {}", DateTimeUtils.parseTimeStamp(weatherSpec.moonRise));
|
||||||
|
weatherSpec.moonRise = 0;
|
||||||
|
}
|
||||||
|
if (timeOutOfDateInterval(weatherSpec.moonSet, currentDay, nextDay)) {
|
||||||
|
LOG.warn("Moon set for today out of bounds: {}", DateTimeUtils.parseTimeStamp(weatherSpec.moonSet));
|
||||||
|
weatherSpec.moonSet = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (WeatherSpec.Daily point : weatherSpec.forecasts) {
|
||||||
|
currentDay = nextDay;
|
||||||
|
nextDay = DateTimeUtils.shiftByDays(currentDay, 1);
|
||||||
|
|
||||||
|
if (timeOutOfDateInterval(point.sunRise, currentDay, nextDay)) {
|
||||||
|
LOG.warn("Sun rise for {} out of bounds: {}", currentDay, DateTimeUtils.parseTimeStamp(point.sunRise));
|
||||||
|
point.sunRise = 0;
|
||||||
|
}
|
||||||
|
if (timeOutOfDateInterval(point.sunSet, currentDay, nextDay)) {
|
||||||
|
LOG.warn("Sun set for {} out of bounds: {}", currentDay, DateTimeUtils.parseTimeStamp(point.sunSet));
|
||||||
|
point.sunSet = 0;
|
||||||
|
}
|
||||||
|
if (timeOutOfDateInterval(point.moonRise, currentDay, nextDay)) {
|
||||||
|
LOG.warn("Moon rise for {} out of bounds: {}", currentDay, DateTimeUtils.parseTimeStamp(point.moonRise));
|
||||||
|
point.moonRise = 0;
|
||||||
|
}
|
||||||
|
if (timeOutOfDateInterval(point.moonSet, currentDay, nextDay)) {
|
||||||
|
LOG.warn("Moon set for {} out of bounds: {}", currentDay, DateTimeUtils.parseTimeStamp(point.moonSet));
|
||||||
|
point.moonSet = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendWeather(WeatherSpec weatherSpec) {
|
||||||
|
// Initialize weather settings and send weather
|
||||||
|
if (!supportProvider.getHuaweiCoordinator().supportsWeather()) {
|
||||||
|
LOG.error("onSendWeather called while weather is not supported.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do not allow sending weather if it's still going
|
||||||
|
synchronized (this) {
|
||||||
|
if (syncInProgress) {
|
||||||
|
LOG.warn("Weather sync already in progress, ignoring next one");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
syncInProgress = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
fixupWeather(weatherSpec);
|
||||||
|
|
||||||
|
Weather.Settings weatherSettings = new Weather.Settings();
|
||||||
|
weatherSettings.uvIndexSupported = supportProvider.getHuaweiCoordinator().supportsWeatherUvIndex();
|
||||||
|
|
||||||
|
SendWeatherStartRequest weatherStartRequest = new SendWeatherStartRequest(supportProvider, weatherSettings);
|
||||||
|
weatherStartRequest.setFinalizeReq(errorHandler);
|
||||||
|
weatherStartRequest.setupTimeoutUntilNext(1000);
|
||||||
|
Request lastRequest = weatherStartRequest;
|
||||||
|
|
||||||
|
if (supportProvider.getHuaweiCoordinator().supportsWeatherUnit()) {
|
||||||
|
SendWeatherUnitRequest weatherUnitRequest = new SendWeatherUnitRequest(supportProvider);
|
||||||
|
weatherUnitRequest.setFinalizeReq(errorHandler);
|
||||||
|
lastRequest.nextRequest(weatherUnitRequest);
|
||||||
|
lastRequest = weatherUnitRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
SendWeatherSupportRequest weatherSupportRequest = new SendWeatherSupportRequest(supportProvider, weatherSettings);
|
||||||
|
weatherSupportRequest.setFinalizeReq(errorHandler);
|
||||||
|
lastRequest.nextRequest(weatherSupportRequest);
|
||||||
|
lastRequest = weatherSupportRequest;
|
||||||
|
|
||||||
|
if (supportProvider.getHuaweiCoordinator().supportsWeatherExtended()) {
|
||||||
|
SendWeatherExtendedSupportRequest weatherExtendedSupportRequest = new SendWeatherExtendedSupportRequest(supportProvider, weatherSettings);
|
||||||
|
weatherExtendedSupportRequest.setFinalizeReq(errorHandler);
|
||||||
|
lastRequest.nextRequest(weatherExtendedSupportRequest);
|
||||||
|
lastRequest = weatherExtendedSupportRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (supportProvider.getHuaweiCoordinator().supportsWeatherMoonRiseSet()) {
|
||||||
|
SendWeatherSunMoonSupportRequest weatherSunMoonSupportRequest = new SendWeatherSunMoonSupportRequest(supportProvider, weatherSettings);
|
||||||
|
weatherSunMoonSupportRequest.setFinalizeReq(errorHandler);
|
||||||
|
lastRequest.nextRequest(weatherSunMoonSupportRequest);
|
||||||
|
lastRequest = weatherSunMoonSupportRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
// End of initialization and start of actually sending weather
|
||||||
|
|
||||||
|
SendWeatherCurrentRequest sendWeatherCurrentRequest = new SendWeatherCurrentRequest(supportProvider, weatherSettings, weatherSpec);
|
||||||
|
sendWeatherCurrentRequest.setFinalizeReq(errorHandler);
|
||||||
|
lastRequest.nextRequest(sendWeatherCurrentRequest);
|
||||||
|
lastRequest = sendWeatherCurrentRequest;
|
||||||
|
|
||||||
|
SendGpsAndTimeToDeviceRequest sendGpsAndTimeToDeviceRequest = new SendGpsAndTimeToDeviceRequest(supportProvider);
|
||||||
|
sendGpsAndTimeToDeviceRequest.setFinalizeReq(errorHandler);
|
||||||
|
lastRequest.nextRequest(sendGpsAndTimeToDeviceRequest);
|
||||||
|
lastRequest = sendGpsAndTimeToDeviceRequest;
|
||||||
|
|
||||||
|
if (supportProvider.getHuaweiCoordinator().supportsWeatherForecasts()) {
|
||||||
|
SendWeatherForecastRequest sendWeatherForecastRequest = new SendWeatherForecastRequest(supportProvider, weatherSettings, weatherSpec);
|
||||||
|
sendWeatherForecastRequest.setFinalizeReq(errorHandler);
|
||||||
|
lastRequest.nextRequest(sendWeatherForecastRequest);
|
||||||
|
lastRequest = sendWeatherForecastRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastRequest.setFinalizeReq(lastHandler);
|
||||||
|
|
||||||
|
try {
|
||||||
|
weatherStartRequest.doPerform();
|
||||||
|
} catch (IOException e) {
|
||||||
|
// TODO: Use translatable string
|
||||||
|
GB.toast(supportProvider.getContext(), "Failed to send weather", Toast.LENGTH_SHORT, GB.ERROR, e);
|
||||||
|
LOG.error("Failed to send weather", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleAsyncMessage(HuaweiPacket response) {
|
||||||
|
if (response.getTlv().getInteger(0x7f, -1) == 0x000186AA) {
|
||||||
|
// Send weather
|
||||||
|
final ArrayList<WeatherSpec> specs = new ArrayList<>(nodomain.freeyourgadget.gadgetbridge.model.Weather.getInstance().getWeatherSpecs());
|
||||||
|
this.sendWeather(specs.get(0));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send back ok
|
||||||
|
try {
|
||||||
|
SendWeatherDeviceRequest sendWeatherDeviceRequest = new SendWeatherDeviceRequest(supportProvider);
|
||||||
|
sendWeatherDeviceRequest.doPerform();
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.error("Could not send weather device request", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -29,6 +29,7 @@ public class SendWeatherDeviceRequest extends Request {
|
|||||||
super(support);
|
super(support);
|
||||||
this.serviceId = Weather.id;
|
this.serviceId = Weather.id;
|
||||||
this.commandId = 0x04;
|
this.commandId = 0x04;
|
||||||
|
this.addToResponse = false; // Handled in async response
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
Reference in New Issue
Block a user