mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2025-01-10 17:11:56 +01:00
Add weather support for Huawei
This commit is contained in:
parent
3af5a412fe
commit
b2b176b65c
@ -144,7 +144,7 @@ public abstract class HuaweiBRCoordinator extends AbstractBLClassicDeviceCoordin
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsWeather() {
|
public boolean supportsWeather() {
|
||||||
return false;
|
return huaweiCoordinator.supportsWeather();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -336,6 +336,30 @@ public class HuaweiCoordinator {
|
|||||||
return supportsCommandForService(0x0c, 0x01);
|
return supportsCommandForService(0x0c, 0x01);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean supportsWeather() {
|
||||||
|
return supportsCommandForService(0x0f, 0x01);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsWeatherUnit() {
|
||||||
|
return supportsCommandForService(0x0f, 0x05);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsWeatherExtended() {
|
||||||
|
return supportsCommandForService(0x0f, 0x05);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsWeatherForecasts() {
|
||||||
|
return supportsCommandForService(0x0f, 0x08);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsWeatherMoonRiseSet() {
|
||||||
|
return supportsCommandForService(0x0f, 0x0a);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsWeatherTides() {
|
||||||
|
return supportsCommandForService(0x0f, 0x0b);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean supportsWorkouts() {
|
public boolean supportsWorkouts() {
|
||||||
return supportsCommandForService(0x17, 0x01);
|
return supportsCommandForService(0x17, 0x01);
|
||||||
}
|
}
|
||||||
|
@ -144,7 +144,7 @@ public abstract class HuaweiLECoordinator extends AbstractBLEDeviceCoordinator i
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsWeather() {
|
public boolean supportsWeather() {
|
||||||
return false;
|
return huaweiCoordinator.supportsWeather();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -32,6 +32,7 @@ import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Alarms;
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Alarms;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.AccountRelated;
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.AccountRelated;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Calls;
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Calls;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Weather;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Workout;
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Workout;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.DeviceConfig;
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.DeviceConfig;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.FindPhone;
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.FindPhone;
|
||||||
@ -475,6 +476,20 @@ public class HuaweiPacket {
|
|||||||
return new FindPhone.Response(paramsProvider).fromPacket(this);
|
return new FindPhone.Response(paramsProvider).fromPacket(this);
|
||||||
this.isEncrypted = this.attemptDecrypt(); // Helps with debugging
|
this.isEncrypted = this.attemptDecrypt(); // Helps with debugging
|
||||||
return this;
|
return this;
|
||||||
|
case Weather.id:
|
||||||
|
switch (this.commandId) {
|
||||||
|
case Weather.WeatherSupport.id:
|
||||||
|
return new Weather.WeatherSupport.Response(paramsProvider).fromPacket(this);
|
||||||
|
case Weather.WeatherExtendedSupport.id:
|
||||||
|
return new Weather.WeatherExtendedSupport.Response(paramsProvider).fromPacket(this);
|
||||||
|
case Weather.WeatherStart.id:
|
||||||
|
return new Weather.WeatherStart.Response(paramsProvider).fromPacket(this);
|
||||||
|
case Weather.WeatherSunMoonSupport.id:
|
||||||
|
return new Weather.WeatherSunMoonSupport.Response(paramsProvider).fromPacket(this);
|
||||||
|
default:
|
||||||
|
this.isEncrypted = this.attemptDecrypt(); // Helps with debugging
|
||||||
|
return this;
|
||||||
|
}
|
||||||
case Workout.id:
|
case Workout.id:
|
||||||
switch (this.commandId) {
|
switch (this.commandId) {
|
||||||
case Workout.WorkoutCount.id:
|
case Workout.WorkoutCount.id:
|
||||||
|
@ -0,0 +1,275 @@
|
|||||||
|
/* 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.devices.huawei.packets;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiTLV;
|
||||||
|
|
||||||
|
public class Weather {
|
||||||
|
public static final byte id = 0x0f;
|
||||||
|
|
||||||
|
public static class Settings {
|
||||||
|
// WeatherSupport
|
||||||
|
public boolean weatherSupported = false;
|
||||||
|
public boolean windSupported = false;
|
||||||
|
public boolean pm25Supported = false;
|
||||||
|
public boolean temperatureSupported = false;
|
||||||
|
public boolean locationNameSupported = false;
|
||||||
|
public boolean currentTemperatureSupported = false;
|
||||||
|
public boolean unitSupported = false;
|
||||||
|
public boolean airQualityIndexSupported = false;
|
||||||
|
|
||||||
|
// WeatherExtendedSupport
|
||||||
|
public boolean timeSupported = false;
|
||||||
|
public boolean sourceSupported = false;
|
||||||
|
public boolean weatherIconSupported = false;
|
||||||
|
|
||||||
|
// WeatherSunMoonSupport
|
||||||
|
public boolean sunRiseSetSupported = false;
|
||||||
|
public boolean moonPhaseSupported = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class CurrentWeatherRequest extends HuaweiPacket {
|
||||||
|
public static final byte id = 0x01;
|
||||||
|
|
||||||
|
public CurrentWeatherRequest(
|
||||||
|
ParamsProvider paramsProvider,
|
||||||
|
Settings settings,
|
||||||
|
Byte windDirection,
|
||||||
|
Byte windSpeed,
|
||||||
|
Byte lowestTemperature,
|
||||||
|
Byte highestTemperature,
|
||||||
|
Short pm25, // TODO: might be float?
|
||||||
|
String locationName,
|
||||||
|
Byte currentTemperature,
|
||||||
|
Byte temperatureUnit,
|
||||||
|
Short airQualityIndex,
|
||||||
|
Integer observationTime,
|
||||||
|
String sourceName
|
||||||
|
) {
|
||||||
|
super(paramsProvider);
|
||||||
|
|
||||||
|
this.serviceId = Weather.id;
|
||||||
|
this.commandId = id;
|
||||||
|
this.tlv = new HuaweiTLV();
|
||||||
|
|
||||||
|
if (lowestTemperature != null && highestTemperature != null && settings.temperatureSupported) {
|
||||||
|
this.tlv.put(0x85, new HuaweiTLV()
|
||||||
|
.put(0x06, lowestTemperature)
|
||||||
|
.put(0x07, highestTemperature)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (windDirection != null && windSpeed != null && settings.windSupported)
|
||||||
|
this.tlv.put(0x03, (short) ((((short) windDirection) << 8) | ((short) windSpeed)));
|
||||||
|
if (pm25 != null && settings.pm25Supported)
|
||||||
|
this.tlv.put(0x04, pm25);
|
||||||
|
if (locationName != null && settings.locationNameSupported)
|
||||||
|
this.tlv.put(0x08, locationName);
|
||||||
|
if (currentTemperature != null && settings.currentTemperatureSupported)
|
||||||
|
this.tlv.put(0x09, currentTemperature);
|
||||||
|
if (temperatureUnit != null && settings.unitSupported)
|
||||||
|
this.tlv.put(0x0a, temperatureUnit);
|
||||||
|
if (airQualityIndex != null && settings.airQualityIndexSupported)
|
||||||
|
this.tlv.put(0x0b, airQualityIndex);
|
||||||
|
if (observationTime != null && settings.timeSupported)
|
||||||
|
this.tlv.put(0x0c, observationTime);
|
||||||
|
if (sourceName != null && settings.sourceSupported)
|
||||||
|
this.tlv.put(0x0e, sourceName);
|
||||||
|
this.tlv.put(0x0f, (byte) 0);
|
||||||
|
|
||||||
|
this.isEncrypted = true;
|
||||||
|
this.complete = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class WeatherSupport {
|
||||||
|
public static final byte id = 0x02;
|
||||||
|
|
||||||
|
public static class Request extends HuaweiPacket {
|
||||||
|
public Request(ParamsProvider paramsProvider) {
|
||||||
|
super(paramsProvider);
|
||||||
|
|
||||||
|
this.serviceId = Weather.id;
|
||||||
|
this.commandId = id;
|
||||||
|
this.tlv = new HuaweiTLV().put(0x01);
|
||||||
|
this.isEncrypted = true;
|
||||||
|
this.complete = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Response extends HuaweiPacket {
|
||||||
|
public byte supportedBitmap = 0;
|
||||||
|
|
||||||
|
public boolean weatherSupported = false;
|
||||||
|
public boolean windSupported = false;
|
||||||
|
public boolean pm25Supported = false;
|
||||||
|
public boolean temperatureSupported = false;
|
||||||
|
public boolean locationNameSupported = false;
|
||||||
|
public boolean currentTemperatureSupported = false;
|
||||||
|
public boolean unitSupported = false;
|
||||||
|
public boolean airQualityIndexSupported = false;
|
||||||
|
|
||||||
|
public Response(ParamsProvider paramsProvider) {
|
||||||
|
super(paramsProvider);
|
||||||
|
this.serviceId = Weather.id;
|
||||||
|
this.commandId = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void parseTlv() throws ParseException {
|
||||||
|
if (!this.tlv.contains(0x01))
|
||||||
|
throw new MissingTagException(0x01);
|
||||||
|
this.supportedBitmap = this.tlv.getByte(0x01);
|
||||||
|
|
||||||
|
this.weatherSupported = (this.supportedBitmap & 0x01) != 0;
|
||||||
|
this.windSupported = (this.supportedBitmap & 0x02) != 0;
|
||||||
|
this.pm25Supported = (this.supportedBitmap & 0x04) != 0;
|
||||||
|
this.temperatureSupported = (this.supportedBitmap & 0x08) != 0;
|
||||||
|
this.locationNameSupported = (this.supportedBitmap & 0x10) != 0;
|
||||||
|
this.currentTemperatureSupported = (this.supportedBitmap & 0x20) != 0;
|
||||||
|
this.unitSupported = (this.supportedBitmap & 0x40) != 0;
|
||||||
|
this.airQualityIndexSupported = (this.supportedBitmap & 0x80) != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class WeatherUnitRequest extends HuaweiPacket {
|
||||||
|
public static final byte id = 0x05;
|
||||||
|
|
||||||
|
public WeatherUnitRequest(ParamsProvider paramsProvider) {
|
||||||
|
super(paramsProvider);
|
||||||
|
|
||||||
|
this.serviceId = Weather.id;
|
||||||
|
this.commandId = id;
|
||||||
|
this.tlv = new HuaweiTLV().put(0x01, (byte) 0); // TODO: find out what unit is what
|
||||||
|
this.isEncrypted = true;
|
||||||
|
this.complete = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class WeatherExtendedSupport {
|
||||||
|
public static final byte id = 0x06;
|
||||||
|
|
||||||
|
public static class Request extends HuaweiPacket {
|
||||||
|
public Request(ParamsProvider paramsProvider) {
|
||||||
|
super(paramsProvider);
|
||||||
|
|
||||||
|
this.serviceId = Weather.id;
|
||||||
|
this.commandId = id;
|
||||||
|
this.tlv = new HuaweiTLV().put(0x01);
|
||||||
|
this.isEncrypted = true;
|
||||||
|
this.complete = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Response extends HuaweiPacket {
|
||||||
|
public short supportedBitmap = 0;
|
||||||
|
|
||||||
|
public boolean timeSupported = false;
|
||||||
|
public boolean sourceSupported = false;
|
||||||
|
public boolean weatherIconSupported = false;
|
||||||
|
|
||||||
|
public Response(ParamsProvider paramsProvider) {
|
||||||
|
super(paramsProvider);
|
||||||
|
this.serviceId = Weather.id;
|
||||||
|
this.commandId = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void parseTlv() throws ParseException {
|
||||||
|
if (!this.tlv.contains(0x01))
|
||||||
|
throw new MissingTagException(0x01);
|
||||||
|
this.supportedBitmap = this.tlv.getShort(0x01);
|
||||||
|
|
||||||
|
this.timeSupported = (this.supportedBitmap & 0x01) != 0;
|
||||||
|
this.sourceSupported = (this.supportedBitmap & 0x02) != 0;
|
||||||
|
this.weatherIconSupported = (this.supportedBitmap & 0x04) != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class WeatherStart {
|
||||||
|
public static final byte id = 0x09;
|
||||||
|
|
||||||
|
public static class Request extends HuaweiPacket {
|
||||||
|
|
||||||
|
public Request(ParamsProvider paramsProvider) {
|
||||||
|
super(paramsProvider);
|
||||||
|
|
||||||
|
this.serviceId = Weather.id;
|
||||||
|
this.commandId = id;
|
||||||
|
this.tlv = new HuaweiTLV().put(0x01, (byte) 0x03); // TODO: find out what this means
|
||||||
|
this.isEncrypted = true;
|
||||||
|
this.complete = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Response extends HuaweiPacket {
|
||||||
|
public boolean success = false;
|
||||||
|
|
||||||
|
public Response(ParamsProvider paramsProvider) {
|
||||||
|
super(paramsProvider);
|
||||||
|
this.serviceId = Weather.id;
|
||||||
|
this.commandId = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void parseTlv() throws ParseException {
|
||||||
|
this.success = this.tlv.getInteger(0x7f) == 0x000186A0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class WeatherSunMoonSupport {
|
||||||
|
public static final byte id = 0x0a;
|
||||||
|
|
||||||
|
public static class Request extends HuaweiPacket {
|
||||||
|
public Request(ParamsProvider paramsProvider) {
|
||||||
|
super(paramsProvider);
|
||||||
|
|
||||||
|
this.serviceId = Weather.id;
|
||||||
|
this.commandId = id;
|
||||||
|
this.tlv = new HuaweiTLV().put(0x01);
|
||||||
|
this.isEncrypted = true;
|
||||||
|
this.complete = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Response extends HuaweiPacket {
|
||||||
|
public byte supportedBitmap = 0;
|
||||||
|
|
||||||
|
public boolean sunRiseSetSupported = false;
|
||||||
|
public boolean moonPhaseSupported = false;
|
||||||
|
|
||||||
|
public Response(ParamsProvider paramsProvider) {
|
||||||
|
super(paramsProvider);
|
||||||
|
this.serviceId = Weather.id;
|
||||||
|
this.commandId = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void parseTlv() throws ParseException {
|
||||||
|
if (!this.tlv.contains(0x01))
|
||||||
|
throw new MissingTagException(0x01);
|
||||||
|
this.supportedBitmap = this.tlv.getByte(0x01);
|
||||||
|
|
||||||
|
this.sunRiseSetSupported = (this.supportedBitmap & 0x01) != 0;
|
||||||
|
this.moonPhaseSupported = (this.supportedBitmap & 0x02) != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -47,9 +47,11 @@ import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.DeviceConfig;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.FindPhone;
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.FindPhone;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Menstrual;
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Menstrual;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.MusicControl;
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.MusicControl;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Weather;
|
||||||
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.SendMenstrualModifyTimeRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendMenstrualModifyTimeRequest;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendWeatherDeviceRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SetMusicStatusRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SetMusicStatusRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||||
|
|
||||||
@ -95,6 +97,7 @@ public class AsynchronousResponse {
|
|||||||
handleCallControls(response);
|
handleCallControls(response);
|
||||||
handlePhoneInfo(response);
|
handlePhoneInfo(response);
|
||||||
handleMenstrualModifyTime(response);
|
handleMenstrualModifyTime(response);
|
||||||
|
handleWeatherCheck(response);
|
||||||
} catch (Request.ResponseParseException e) {
|
} catch (Request.ResponseParseException e) {
|
||||||
LOG.error("Response parse exception", e);
|
LOG.error("Response parse exception", e);
|
||||||
}
|
}
|
||||||
@ -378,4 +381,18 @@ public class AsynchronousResponse {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void handleWeatherCheck(HuaweiPacket response) {
|
||||||
|
if (response.serviceId == Weather.id && response.commandId == 0x04) {
|
||||||
|
// Send back ok
|
||||||
|
try {
|
||||||
|
SendWeatherDeviceRequest sendWeatherDeviceRequest = new SendWeatherDeviceRequest(this.support);
|
||||||
|
sendWeatherDeviceRequest.doPerform();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace(); // TODO: Change
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: send back weather?
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
|
import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec;
|
import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btbr.AbstractBTBRDeviceSupport;
|
import nodomain.freeyourgadget.gadgetbridge.service.btbr.AbstractBTBRDeviceSupport;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btbr.TransactionBuilder;
|
import nodomain.freeyourgadget.gadgetbridge.service.btbr.TransactionBuilder;
|
||||||
|
|
||||||
@ -117,4 +118,9 @@ public class HuaweiBRSupport extends AbstractBTBRDeviceSupport {
|
|||||||
if (!start)
|
if (!start)
|
||||||
supportProvider.onStopFindPhone();
|
supportProvider.onStopFindPhone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSendWeather(WeatherSpec weatherSpec) {
|
||||||
|
supportProvider.onSendWeather(weatherSpec);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
|
import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec;
|
import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.GattService;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.GattService;
|
||||||
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;
|
||||||
@ -125,4 +126,9 @@ public class HuaweiLESupport extends AbstractBTLEDeviceSupport {
|
|||||||
if (!start)
|
if (!start)
|
||||||
supportProvider.onStopFindPhone();
|
supportProvider.onStopFindPhone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSendWeather(WeatherSpec weatherSpec) {
|
||||||
|
supportProvider.onSendWeather(weatherSpec);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiCoordinatorSupp
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiCrypto;
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiCrypto;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket;
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiSampleProvider;
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiSampleProvider;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Weather;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Workout;
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Workout;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst;
|
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.BaseActivitySummary;
|
import nodomain.freeyourgadget.gadgetbridge.entities.BaseActivitySummary;
|
||||||
@ -73,11 +74,18 @@ import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec;
|
import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.RecordedDataTypes;
|
import nodomain.freeyourgadget.gadgetbridge.model.RecordedDataTypes;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.GetEventAlarmList;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.GetEventAlarmList;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.GetNotificationConstraintsRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.GetNotificationConstraintsRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.GetSmartAlarmList;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.GetSmartAlarmList;
|
||||||
|
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.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;
|
||||||
@ -156,6 +164,8 @@ public class HuaweiSupportProvider {
|
|||||||
private MusicStateSpec musicStateSpec = null;
|
private MusicStateSpec musicStateSpec = null;
|
||||||
private MusicSpec musicSpec = null;
|
private MusicSpec musicSpec = null;
|
||||||
|
|
||||||
|
private Weather.Settings weatherSettings = null;
|
||||||
|
|
||||||
private final HuaweiPacket.ParamsProvider paramsProvider = new HuaweiPacket.ParamsProvider();
|
private final HuaweiPacket.ParamsProvider paramsProvider = new HuaweiPacket.ParamsProvider();
|
||||||
|
|
||||||
protected ResponseManager responseManager = new ResponseManager(this);
|
protected ResponseManager responseManager = new ResponseManager(this);
|
||||||
@ -1637,4 +1647,75 @@ public class HuaweiSupportProvider {
|
|||||||
LOG.error("Failed to set language settings request", e);
|
LOG.error("Failed to set language settings request", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onSendWeather(WeatherSpec weatherSpec) {
|
||||||
|
if (weatherSettings != null && weatherSettings.weatherSupported) {
|
||||||
|
try {
|
||||||
|
SendWeatherCurrentRequest sendWeatherCurrentRequest = new SendWeatherCurrentRequest(
|
||||||
|
this,
|
||||||
|
weatherSettings,
|
||||||
|
weatherSpec
|
||||||
|
);
|
||||||
|
sendWeatherCurrentRequest.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);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Initialize weather settings
|
||||||
|
if (!getHuaweiCoordinator().supportsWeather()) {
|
||||||
|
// TODO: exception?
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.weatherSettings = new Weather.Settings();
|
||||||
|
|
||||||
|
RequestCallback requestCallback = new RequestCallback(this) {
|
||||||
|
@Override
|
||||||
|
public void call() {
|
||||||
|
this.support.weatherSettings.weatherSupported = true;
|
||||||
|
this.support.onSendWeather(weatherSpec);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
SendWeatherStartRequest weatherStartRequest = new SendWeatherStartRequest(this);
|
||||||
|
weatherStartRequest.setFinalizeReq(requestCallback);
|
||||||
|
Request lastRequest = weatherStartRequest;
|
||||||
|
|
||||||
|
if (getHuaweiCoordinator().supportsWeatherUnit()) {
|
||||||
|
SendWeatherUnitRequest weatherUnitRequest = new SendWeatherUnitRequest(this);
|
||||||
|
weatherUnitRequest.setFinalizeReq(requestCallback);
|
||||||
|
lastRequest.nextRequest(weatherUnitRequest);
|
||||||
|
lastRequest = weatherUnitRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
SendWeatherSupportRequest weatherSupportRequest = new SendWeatherSupportRequest(this, weatherSettings);
|
||||||
|
weatherSupportRequest.setFinalizeReq(requestCallback);
|
||||||
|
lastRequest.nextRequest(weatherSupportRequest);
|
||||||
|
lastRequest = weatherSupportRequest;
|
||||||
|
|
||||||
|
if (getHuaweiCoordinator().supportsWeatherExtended()) {
|
||||||
|
SendWeatherExtendedSupportRequest weatherExtendedSupportRequest = new SendWeatherExtendedSupportRequest(this, weatherSettings);
|
||||||
|
weatherExtendedSupportRequest.setFinalizeReq(requestCallback);
|
||||||
|
lastRequest.nextRequest(weatherExtendedSupportRequest);
|
||||||
|
lastRequest = weatherExtendedSupportRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getHuaweiCoordinator().supportsWeatherMoonRiseSet()) {
|
||||||
|
SendWeatherSunMoonSupportRequest weatherSunMoonSupportRequest = new SendWeatherSunMoonSupportRequest(this, weatherSettings);
|
||||||
|
weatherSunMoonSupportRequest.setFinalizeReq(requestCallback);
|
||||||
|
lastRequest.nextRequest(weatherSunMoonSupportRequest);
|
||||||
|
// lastRequest = weatherSunMoonSupportRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
weatherStartRequest.doPerform();
|
||||||
|
} catch (IOException e) {
|
||||||
|
// TODO: Use translatable string
|
||||||
|
GB.toast(context, "Failed to send initialize weather requests", Toast.LENGTH_SHORT, GB.ERROR, e);
|
||||||
|
LOG.error("Failed to send initialize weather requests", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,67 @@
|
|||||||
|
/* 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.requests;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
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.HuaweiSupportProvider;
|
||||||
|
|
||||||
|
public class SendWeatherCurrentRequest extends Request {
|
||||||
|
Weather.Settings settings;
|
||||||
|
WeatherSpec weatherSpec;
|
||||||
|
|
||||||
|
public SendWeatherCurrentRequest(HuaweiSupportProvider support, Weather.Settings settings, WeatherSpec weatherSpec) {
|
||||||
|
super(support);
|
||||||
|
this.serviceId = Weather.id;
|
||||||
|
this.commandId = Weather.CurrentWeatherRequest.id;
|
||||||
|
this.settings = settings;
|
||||||
|
this.weatherSpec = weatherSpec;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<byte[]> createRequest() throws RequestCreationException {
|
||||||
|
try {
|
||||||
|
// TODO: support multiple units
|
||||||
|
Short pm25 = null;
|
||||||
|
Short aqi = null;
|
||||||
|
if (weatherSpec.airQuality != null) {
|
||||||
|
pm25 = (short) weatherSpec.airQuality.pm25; // TODO: does this work?
|
||||||
|
aqi = (short) weatherSpec.airQuality.aqi;
|
||||||
|
}
|
||||||
|
return new Weather.CurrentWeatherRequest(
|
||||||
|
this.paramsProvider,
|
||||||
|
settings,
|
||||||
|
(byte) weatherSpec.windDirection,
|
||||||
|
(byte) weatherSpec.windSpeed,
|
||||||
|
(byte) (weatherSpec.todayMinTemp - 273),
|
||||||
|
(byte) (weatherSpec.todayMaxTemp - 273),
|
||||||
|
pm25,
|
||||||
|
weatherSpec.location,
|
||||||
|
(byte) (weatherSpec.currentTemp - 273),
|
||||||
|
(byte) 0,
|
||||||
|
aqi,
|
||||||
|
weatherSpec.timestamp,
|
||||||
|
"Gadgetbridge"
|
||||||
|
).serialize();
|
||||||
|
} catch (HuaweiPacket.CryptoException e) {
|
||||||
|
throw new RequestCreationException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
/* 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.requests;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiTLV;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Weather;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.HuaweiSupportProvider;
|
||||||
|
|
||||||
|
public class SendWeatherDeviceRequest extends Request {
|
||||||
|
WeatherSpec weatherSpec;
|
||||||
|
|
||||||
|
public SendWeatherDeviceRequest(HuaweiSupportProvider support) {
|
||||||
|
super(support);
|
||||||
|
this.serviceId = Weather.id;
|
||||||
|
this.commandId = 0x04;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<byte[]> createRequest() throws RequestCreationException {
|
||||||
|
try {
|
||||||
|
// TODO: move this to the weather packet class
|
||||||
|
HuaweiPacket response = new HuaweiPacket(supportProvider.getParamsProvider());
|
||||||
|
response.serviceId = this.serviceId;
|
||||||
|
response.commandId = this.commandId;
|
||||||
|
response.setTlv(new HuaweiTLV().put(0x01, 0x186a0));
|
||||||
|
response.setEncryption(false);
|
||||||
|
return response.serialize();
|
||||||
|
} catch (HuaweiPacket.CryptoException e) {
|
||||||
|
throw new RequestCreationException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
/* 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.requests;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Weather;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.HuaweiSupportProvider;
|
||||||
|
|
||||||
|
public class SendWeatherExtendedSupportRequest extends Request {
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(SendWeatherExtendedSupportRequest.class);
|
||||||
|
|
||||||
|
private Weather.Settings settings;
|
||||||
|
|
||||||
|
public SendWeatherExtendedSupportRequest(HuaweiSupportProvider support, Weather.Settings settings) {
|
||||||
|
super(support);
|
||||||
|
this.serviceId = Weather.id;
|
||||||
|
this.commandId = Weather.WeatherExtendedSupport.id;
|
||||||
|
this.settings = settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<byte[]> createRequest() throws RequestCreationException {
|
||||||
|
try {
|
||||||
|
return new Weather.WeatherExtendedSupport.Request(this.paramsProvider).serialize();
|
||||||
|
} catch (HuaweiPacket.CryptoException e) {
|
||||||
|
throw new RequestCreationException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void processResponse() throws ResponseParseException {
|
||||||
|
if (receivedPacket instanceof Weather.WeatherExtendedSupport.Response) {
|
||||||
|
this.settings.timeSupported = ((Weather.WeatherExtendedSupport.Response) receivedPacket).timeSupported;
|
||||||
|
this.settings.sourceSupported = ((Weather.WeatherExtendedSupport.Response) receivedPacket).sourceSupported;
|
||||||
|
this.settings.weatherIconSupported = ((Weather.WeatherExtendedSupport.Response) receivedPacket).weatherIconSupported;
|
||||||
|
} else {
|
||||||
|
LOG.error("WeatherExtendedSupport response is not of type WeatherExtendedSupport response");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
/* 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.requests;
|
||||||
|
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Weather;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.HuaweiSupportProvider;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||||
|
|
||||||
|
public class SendWeatherStartRequest extends Request {
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(SendWeatherStartRequest.class);
|
||||||
|
|
||||||
|
public int response = -1;
|
||||||
|
|
||||||
|
public SendWeatherStartRequest(HuaweiSupportProvider support) {
|
||||||
|
super(support);
|
||||||
|
this.serviceId = Weather.id;
|
||||||
|
this.commandId = Weather.WeatherStart.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<byte[]> createRequest() throws RequestCreationException {
|
||||||
|
try {
|
||||||
|
return new Weather.WeatherStart.Request(this.paramsProvider).serialize();
|
||||||
|
} catch (HuaweiPacket.CryptoException e) {
|
||||||
|
throw new RequestCreationException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void processResponse() throws ResponseParseException {
|
||||||
|
if (receivedPacket instanceof Weather.WeatherStart.Response) {
|
||||||
|
if (!((Weather.WeatherStart.Response) receivedPacket).success) {
|
||||||
|
this.stopChain();
|
||||||
|
GB.toast(supportProvider.getContext(), "Received non-ok status for WeatherStart response", Toast.LENGTH_SHORT, GB.INFO);
|
||||||
|
LOG.info("Received non-ok status for WeatherStart response");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.stopChain();
|
||||||
|
GB.toast(supportProvider.getContext(), "WeatherStart response is not of type WeatherStart response", Toast.LENGTH_SHORT, GB.ERROR);
|
||||||
|
LOG.error("WeatherStart response is not of type WeatherStart response");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
/* 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.requests;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Weather;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.HuaweiSupportProvider;
|
||||||
|
|
||||||
|
public class SendWeatherSunMoonSupportRequest extends Request {
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(SendWeatherSunMoonSupportRequest.class);
|
||||||
|
|
||||||
|
private Weather.Settings settings;
|
||||||
|
|
||||||
|
public SendWeatherSunMoonSupportRequest(HuaweiSupportProvider support, Weather.Settings settings) {
|
||||||
|
super(support);
|
||||||
|
this.serviceId = Weather.id;
|
||||||
|
this.commandId = Weather.WeatherSunMoonSupport.id;
|
||||||
|
this.settings = settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<byte[]> createRequest() throws RequestCreationException {
|
||||||
|
try {
|
||||||
|
return new Weather.WeatherSunMoonSupport.Request(this.paramsProvider).serialize();
|
||||||
|
} catch (HuaweiPacket.CryptoException e) {
|
||||||
|
throw new RequestCreationException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void processResponse() throws ResponseParseException {
|
||||||
|
if (receivedPacket instanceof Weather.WeatherSunMoonSupport.Response) {
|
||||||
|
this.settings.sunRiseSetSupported = ((Weather.WeatherSunMoonSupport.Response) receivedPacket).sunRiseSetSupported;
|
||||||
|
this.settings.moonPhaseSupported = ((Weather.WeatherSunMoonSupport.Response) receivedPacket).moonPhaseSupported;
|
||||||
|
} else {
|
||||||
|
LOG.error("WeatherExtendedSupport response is not of type WeatherExtendedSupport response");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,64 @@
|
|||||||
|
/* 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.requests;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Weather;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.HuaweiSupportProvider;
|
||||||
|
|
||||||
|
public class SendWeatherSupportRequest extends Request {
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(SendWeatherSupportRequest.class);
|
||||||
|
|
||||||
|
private Weather.Settings settings;
|
||||||
|
|
||||||
|
public SendWeatherSupportRequest(HuaweiSupportProvider support, Weather.Settings settings) {
|
||||||
|
super(support);
|
||||||
|
this.serviceId = Weather.id;
|
||||||
|
this.commandId = Weather.WeatherSupport.id;
|
||||||
|
this.settings = settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<byte[]> createRequest() throws RequestCreationException {
|
||||||
|
try {
|
||||||
|
return new Weather.WeatherSupport.Request(this.paramsProvider).serialize();
|
||||||
|
} catch (HuaweiPacket.CryptoException e) {
|
||||||
|
throw new RequestCreationException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void processResponse() throws ResponseParseException {
|
||||||
|
if (receivedPacket instanceof Weather.WeatherSupport.Response) {
|
||||||
|
this.settings.weatherSupported = ((Weather.WeatherSupport.Response) receivedPacket).weatherSupported;
|
||||||
|
this.settings.windSupported = ((Weather.WeatherSupport.Response) receivedPacket).windSupported;
|
||||||
|
this.settings.pm25Supported = ((Weather.WeatherSupport.Response) receivedPacket).pm25Supported;
|
||||||
|
this.settings.temperatureSupported = ((Weather.WeatherSupport.Response) receivedPacket).temperatureSupported;
|
||||||
|
this.settings.locationNameSupported = ((Weather.WeatherSupport.Response) receivedPacket).locationNameSupported;
|
||||||
|
this.settings.currentTemperatureSupported = ((Weather.WeatherSupport.Response) receivedPacket).currentTemperatureSupported;
|
||||||
|
this.settings.unitSupported = ((Weather.WeatherSupport.Response) receivedPacket).unitSupported;
|
||||||
|
this.settings.airQualityIndexSupported = ((Weather.WeatherSupport.Response) receivedPacket).airQualityIndexSupported;
|
||||||
|
} else {
|
||||||
|
LOG.error("WeatherSupport response is not of type WeatherSupport response");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
/* 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.requests;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Weather;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.HuaweiSupportProvider;
|
||||||
|
|
||||||
|
public class SendWeatherUnitRequest extends Request {
|
||||||
|
|
||||||
|
public SendWeatherUnitRequest(HuaweiSupportProvider support) {
|
||||||
|
super(support);
|
||||||
|
this.serviceId = Weather.id;
|
||||||
|
this.commandId = Weather.WeatherUnitRequest.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<byte[]> createRequest() throws RequestCreationException {
|
||||||
|
try {
|
||||||
|
return new Weather.WeatherUnitRequest(this.paramsProvider).serialize();
|
||||||
|
} catch (HuaweiPacket.CryptoException e) {
|
||||||
|
throw new RequestCreationException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user