/* Copyright (C) 2022 José Rebelo
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 . */
package nodomain.freeyourgadget.gadgetbridge.service.devices.huami;
import android.location.Location;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import net.e175.klaus.solarpositioning.DeltaT;
import net.e175.klaus.solarpositioning.SPA;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiWeatherConditions;
import nodomain.freeyourgadget.gadgetbridge.model.Weather;
import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec;
import nodomain.freeyourgadget.gadgetbridge.service.devices.pebble.webview.CurrentPosition;
/**
* The weather models that the bands expect as an http response to weather requests. Base URL usually
* is https://api-mifit.huami.com.
*/
public class Huami2021Weather {
private static final Logger LOG = LoggerFactory.getLogger(Huami2021Weather.class);
private static final Gson GSON = new GsonBuilder()
.serializeNulls()
.setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ") // for pubTimes
//.registerTypeAdapter(LocalDate.class, new LocalDateSerializer()) // Requires API 26
.create();
public static Response handleHttpRequest(final String path, final Map query) {
final WeatherSpec weatherSpec = Weather.getInstance().getWeatherSpec();
if (weatherSpec == null) {
LOG.error("No weather in weather instance");
return new Huami2021Weather.ErrorResponse(404, -2001, "Not found");
}
switch (path) {
case "/weather/v2/forecast":
final int forecastDays = getQueryNum(query, "days", 10);
return new ForecastResponse(weatherSpec, forecastDays);
case "/weather/index":
final int indexDays = getQueryNum(query, "days", 3);
return new IndexResponse(weatherSpec, indexDays);
case "/weather/current":
return new CurrentResponse(weatherSpec);
case "/weather/forecast/hourly":
final int hours = getQueryNum(query, "hours", 72);
return new HourlyResponse(hours);
case "/weather/alerts":
return new AlertsResponse();
//case "/weather/tide":
// return new TideResponse(weatherSpec);
}
LOG.error("Unknown weather path {}", path);
return new Huami2021Weather.ErrorResponse(404, -2001, "Not found");
}
private static int getQueryNum(final Map query, final String key, final int defaultValue) {
final String daysStr = query.get(key);
if (daysStr != null) {
return Integer.parseInt(daysStr);
} else {
return defaultValue;
}
}
private static class RawJsonStringResponse extends Response {
private final String content;
public RawJsonStringResponse(final String content) {
this.content = content;
}
public String toJson() {
return content;
}
}
public static class ErrorResponse extends Response {
private final int httpStatusCode;
private final int errorCode;
private final String message;
public ErrorResponse(final int httpStatusCode, final int errorCode, final String message) {
this.httpStatusCode = httpStatusCode;
this.errorCode = errorCode;
this.message = message;
}
@Override
public int getHttpStatusCode() {
return httpStatusCode;
}
public int getErrorCode() {
return errorCode;
}
public String getMessage() {
return message;
}
}
public static abstract class Response {
public int getHttpStatusCode() {
return 200;
}
public String toJson() {
return GSON.toJson(this);
}
}
// /weather/v2/forecast
//
// locale=zh_CN
// deviceSource=11
// days=10
// isGlobal=true
// locationKey=00.000,-0.000,xiaomi_accu:000000
public static class ForecastResponse extends Response {
public Date pubTime;
public List humidity = new ArrayList<>(); // int
public List temperature = new ArrayList<>(); // ints
public List weather = new ArrayList<>();
public List windDirection = new ArrayList<>();
public List sunRiseSet = new ArrayList<>();
public List windSpeed = new ArrayList<>();
public Object moonRiseSet = new Object(); // MoonRiseSet
public List