mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-11-03 00:43:02 +01:00
Add weather forecast
This commit is contained in:
parent
b2b176b65c
commit
2b1c5b5819
@ -16,6 +16,8 @@
|
|||||||
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.devices.huawei.packets;
|
package nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket;
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiTLV;
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiTLV;
|
||||||
|
|
||||||
@ -202,6 +204,78 @@ public class Weather {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class WeatherForecastDataRequest extends HuaweiPacket {
|
||||||
|
public static final byte id = 0x08;
|
||||||
|
|
||||||
|
public static class TimeData {
|
||||||
|
public int timestamp;
|
||||||
|
public byte icon;
|
||||||
|
public byte temperature;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class DayData {
|
||||||
|
public int timestamp;
|
||||||
|
public byte icon;
|
||||||
|
public byte highTemperature;
|
||||||
|
public byte lowTemperature;
|
||||||
|
public int sunriseTime;
|
||||||
|
public int sunsetTime;
|
||||||
|
public int moonRiseTime;
|
||||||
|
public int moonSetTime;
|
||||||
|
public byte moonPhase; // TODO: probably enum
|
||||||
|
}
|
||||||
|
|
||||||
|
public WeatherForecastDataRequest(
|
||||||
|
ParamsProvider paramsProvider,
|
||||||
|
List<TimeData> timeDataList,
|
||||||
|
List<DayData> dayDataList
|
||||||
|
) {
|
||||||
|
super(paramsProvider);
|
||||||
|
|
||||||
|
this.serviceId = Weather.id;
|
||||||
|
this.commandId = id;
|
||||||
|
this.tlv = new HuaweiTLV();
|
||||||
|
|
||||||
|
if (timeDataList != null && !timeDataList.isEmpty()) {
|
||||||
|
HuaweiTLV timeDataTlv = new HuaweiTLV();
|
||||||
|
for (TimeData timeData : timeDataList) {
|
||||||
|
// TODO: NULLs?
|
||||||
|
timeDataTlv.put(0x82, new HuaweiTLV()
|
||||||
|
.put(0x03, timeData.timestamp)
|
||||||
|
.put(0x04, timeData.icon)
|
||||||
|
.put(0x05, timeData.temperature)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
this.tlv.put(0x81, timeDataTlv);
|
||||||
|
}
|
||||||
|
// this.tlv.put(0x81);
|
||||||
|
|
||||||
|
if (dayDataList != null && !dayDataList.isEmpty()) {
|
||||||
|
HuaweiTLV dayDataTlv = new HuaweiTLV();
|
||||||
|
for (DayData dayData : dayDataList) {
|
||||||
|
// TODO: NULLs?
|
||||||
|
dayDataTlv.put(0x91, new HuaweiTLV()
|
||||||
|
.put(0x12, dayData.timestamp)
|
||||||
|
.put(0x13, dayData.icon)
|
||||||
|
.put(0x14, dayData.highTemperature)
|
||||||
|
.put(0x15, dayData.lowTemperature)
|
||||||
|
.put(0x16, dayData.sunriseTime)
|
||||||
|
.put(0x17, dayData.sunsetTime)
|
||||||
|
.put(0x1a, dayData.moonRiseTime)
|
||||||
|
.put(0x1b, dayData.moonSetTime)
|
||||||
|
.put(0x1e, dayData.moonPhase)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
this.tlv.put(0x90, dayDataTlv);
|
||||||
|
}
|
||||||
|
// this.tlv.put(0x90);
|
||||||
|
|
||||||
|
this.isEncrypted = true;
|
||||||
|
this.isSliced = true;
|
||||||
|
this.complete = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static class WeatherStart {
|
public static class WeatherStart {
|
||||||
public static final byte id = 0x09;
|
public static final byte id = 0x09;
|
||||||
|
|
||||||
|
@ -82,6 +82,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.Send
|
|||||||
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.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.SendWeatherStartRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendWeatherSunMoonSupportRequest;
|
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.SendWeatherSupportRequest;
|
||||||
@ -1656,6 +1657,15 @@ public class HuaweiSupportProvider {
|
|||||||
weatherSettings,
|
weatherSettings,
|
||||||
weatherSpec
|
weatherSpec
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (getHuaweiCoordinator().supportsWeatherForecasts()) {
|
||||||
|
SendWeatherForecastRequest sendWeatherForecastRequest = new SendWeatherForecastRequest(
|
||||||
|
this,
|
||||||
|
weatherSpec
|
||||||
|
);
|
||||||
|
sendWeatherCurrentRequest.nextRequest(sendWeatherForecastRequest);
|
||||||
|
}
|
||||||
|
|
||||||
sendWeatherCurrentRequest.doPerform();
|
sendWeatherCurrentRequest.doPerform();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// TODO: Use translatable string
|
// TODO: Use translatable string
|
||||||
@ -1680,35 +1690,32 @@ public class HuaweiSupportProvider {
|
|||||||
};
|
};
|
||||||
|
|
||||||
SendWeatherStartRequest weatherStartRequest = new SendWeatherStartRequest(this);
|
SendWeatherStartRequest weatherStartRequest = new SendWeatherStartRequest(this);
|
||||||
weatherStartRequest.setFinalizeReq(requestCallback);
|
|
||||||
Request lastRequest = weatherStartRequest;
|
Request lastRequest = weatherStartRequest;
|
||||||
|
|
||||||
if (getHuaweiCoordinator().supportsWeatherUnit()) {
|
if (getHuaweiCoordinator().supportsWeatherUnit()) {
|
||||||
SendWeatherUnitRequest weatherUnitRequest = new SendWeatherUnitRequest(this);
|
SendWeatherUnitRequest weatherUnitRequest = new SendWeatherUnitRequest(this);
|
||||||
weatherUnitRequest.setFinalizeReq(requestCallback);
|
|
||||||
lastRequest.nextRequest(weatherUnitRequest);
|
lastRequest.nextRequest(weatherUnitRequest);
|
||||||
lastRequest = weatherUnitRequest;
|
lastRequest = weatherUnitRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
SendWeatherSupportRequest weatherSupportRequest = new SendWeatherSupportRequest(this, weatherSettings);
|
SendWeatherSupportRequest weatherSupportRequest = new SendWeatherSupportRequest(this, weatherSettings);
|
||||||
weatherSupportRequest.setFinalizeReq(requestCallback);
|
|
||||||
lastRequest.nextRequest(weatherSupportRequest);
|
lastRequest.nextRequest(weatherSupportRequest);
|
||||||
lastRequest = weatherSupportRequest;
|
lastRequest = weatherSupportRequest;
|
||||||
|
|
||||||
if (getHuaweiCoordinator().supportsWeatherExtended()) {
|
if (getHuaweiCoordinator().supportsWeatherExtended()) {
|
||||||
SendWeatherExtendedSupportRequest weatherExtendedSupportRequest = new SendWeatherExtendedSupportRequest(this, weatherSettings);
|
SendWeatherExtendedSupportRequest weatherExtendedSupportRequest = new SendWeatherExtendedSupportRequest(this, weatherSettings);
|
||||||
weatherExtendedSupportRequest.setFinalizeReq(requestCallback);
|
|
||||||
lastRequest.nextRequest(weatherExtendedSupportRequest);
|
lastRequest.nextRequest(weatherExtendedSupportRequest);
|
||||||
lastRequest = weatherExtendedSupportRequest;
|
lastRequest = weatherExtendedSupportRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getHuaweiCoordinator().supportsWeatherMoonRiseSet()) {
|
if (getHuaweiCoordinator().supportsWeatherMoonRiseSet()) {
|
||||||
SendWeatherSunMoonSupportRequest weatherSunMoonSupportRequest = new SendWeatherSunMoonSupportRequest(this, weatherSettings);
|
SendWeatherSunMoonSupportRequest weatherSunMoonSupportRequest = new SendWeatherSunMoonSupportRequest(this, weatherSettings);
|
||||||
weatherSunMoonSupportRequest.setFinalizeReq(requestCallback);
|
|
||||||
lastRequest.nextRequest(weatherSunMoonSupportRequest);
|
lastRequest.nextRequest(weatherSunMoonSupportRequest);
|
||||||
// lastRequest = weatherSunMoonSupportRequest;
|
lastRequest = weatherSunMoonSupportRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lastRequest.setFinalizeReq(requestCallback);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
weatherStartRequest.doPerform();
|
weatherStartRequest.doPerform();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -0,0 +1,94 @@
|
|||||||
|
/* 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.ArrayList;
|
||||||
|
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;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Weather.WeatherForecastDataRequest;
|
||||||
|
|
||||||
|
public class SendWeatherForecastRequest extends Request {
|
||||||
|
WeatherSpec weatherSpec;
|
||||||
|
|
||||||
|
public SendWeatherForecastRequest(HuaweiSupportProvider support, WeatherSpec weatherSpec) {
|
||||||
|
super(support);
|
||||||
|
this.serviceId = Weather.id;
|
||||||
|
this.commandId = Weather.WeatherForecastDataRequest.id;
|
||||||
|
this.weatherSpec = weatherSpec;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<byte[]> createRequest() throws RequestCreationException {
|
||||||
|
// TODO: Weather settings
|
||||||
|
ArrayList<WeatherForecastDataRequest.TimeData> timeDataArrayList = new ArrayList<>(
|
||||||
|
this.weatherSpec.hourly.size() // TODO: wrong size
|
||||||
|
);
|
||||||
|
ArrayList<WeatherForecastDataRequest.DayData> dayDataArrayList = new ArrayList<>(
|
||||||
|
this.weatherSpec.forecasts.size() // TODO: wrong size
|
||||||
|
);
|
||||||
|
// for (WeatherSpec.Hourly hourly : weatherSpec.hourly) {
|
||||||
|
for (int i = 0; i < Math.min(weatherSpec.hourly.size(), 24); i++) { // TODO: min?
|
||||||
|
WeatherSpec.Hourly hourly = weatherSpec.hourly.get(i);
|
||||||
|
WeatherForecastDataRequest.TimeData timeData = new WeatherForecastDataRequest.TimeData();
|
||||||
|
timeData.timestamp = hourly.timestamp;
|
||||||
|
timeData.icon = 1; // TODO: hourly.conditionCode conversion
|
||||||
|
timeData.temperature = (byte) (hourly.temp - 273);
|
||||||
|
timeDataArrayList.add(timeData);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add today as well
|
||||||
|
WeatherForecastDataRequest.DayData today = new WeatherForecastDataRequest.DayData();
|
||||||
|
today.timestamp = weatherSpec.sunRise;
|
||||||
|
today.icon = 1; // TODO
|
||||||
|
today.highTemperature = (byte) (weatherSpec.todayMaxTemp - 273);
|
||||||
|
today.lowTemperature = (byte) (weatherSpec.todayMinTemp - 273);
|
||||||
|
today.sunriseTime = weatherSpec.sunRise;
|
||||||
|
today.sunsetTime = weatherSpec.sunSet;
|
||||||
|
today.moonRiseTime = weatherSpec.moonRise;
|
||||||
|
today.moonSetTime = weatherSpec.moonSet;
|
||||||
|
today.moonPhase = (byte) 4; // weatherSpec.moonPhase; // TODO: check
|
||||||
|
dayDataArrayList.add(today);
|
||||||
|
|
||||||
|
for (int i = 0; i < Math.min(weatherSpec.forecasts.size(), 7); i++) { // TODO: min?
|
||||||
|
WeatherSpec.Daily daily = weatherSpec.forecasts.get(i);
|
||||||
|
WeatherForecastDataRequest.DayData dayData = new WeatherForecastDataRequest.DayData();
|
||||||
|
dayData.timestamp = daily.sunRise;
|
||||||
|
dayData.icon = 1; // TODO: daily.conditionCode conversion
|
||||||
|
dayData.highTemperature = (byte) (daily.maxTemp - 273);
|
||||||
|
dayData.lowTemperature = (byte) (daily.minTemp - 273);
|
||||||
|
dayData.sunriseTime = daily.sunRise;
|
||||||
|
dayData.sunsetTime = daily.sunSet;
|
||||||
|
dayData.moonRiseTime = daily.moonRise;
|
||||||
|
dayData.moonSetTime = daily.moonSet;
|
||||||
|
dayData.moonPhase = (byte) 4; // daily.moonPhase; // TODO: check
|
||||||
|
dayDataArrayList.add(dayData);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return new WeatherForecastDataRequest(
|
||||||
|
this.paramsProvider,
|
||||||
|
timeDataArrayList,
|
||||||
|
dayDataArrayList
|
||||||
|
).serialize();
|
||||||
|
} catch (HuaweiPacket.CryptoException e) {
|
||||||
|
throw new RequestCreationException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user