From 929ea7ae57e19929610b3e7567280a130386da51 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Tue, 24 Oct 2023 16:35:16 +0200 Subject: [PATCH] Xiaomi: Implement sending current weather MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TODO: Support °F, find out about unknown values Tested on Mi Watch Lite --- .../xiaomi/services/XiaomiWeatherService.java | 63 +++++++++++++++++-- app/src/main/proto/xiaomi.proto | 49 +++++++++++++++ 2 files changed, 106 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/services/XiaomiWeatherService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/services/XiaomiWeatherService.java index 3b236b77a..ca659f769 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/services/XiaomiWeatherService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/services/XiaomiWeatherService.java @@ -19,14 +19,14 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.services; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import nodomain.freeyourgadget.gadgetbridge.GBApplication; -import nodomain.freeyourgadget.gadgetbridge.R; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + import nodomain.freeyourgadget.gadgetbridge.activities.SettingsActivity; -import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiCoordinator; -import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst; +import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiWeatherConditions; import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec; import nodomain.freeyourgadget.gadgetbridge.proto.xiaomi.XiaomiProto; -import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; import nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.XiaomiSupport; import nodomain.freeyourgadget.gadgetbridge.util.Prefs; @@ -37,6 +37,7 @@ public class XiaomiWeatherService extends AbstractXiaomiService { private static final int CMD_TEMPERATURE_UNIT_GET = 9; private static final int CMD_TEMPERATURE_UNIT_SET = 10; + private static final int CMD_SET_CURRENT_WEATHER = 0; public XiaomiWeatherService(final XiaomiSupport support) { super(support); @@ -64,7 +65,57 @@ public class XiaomiWeatherService extends AbstractXiaomiService { } public void onSendWeather(final WeatherSpec weatherSpec) { - // TODO + String timestamp = new StringBuilder( + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.US) + .format(new Date(weatherSpec.timestamp * 1000L))) + .insert(22, ':') // FIXME: I bet this fails for some, but all this java date craps sucks + .toString(); + + + getSupport().sendCommand( + "set current weather", + XiaomiProto.Command.newBuilder() + .setType(COMMAND_TYPE) + .setSubtype(CMD_SET_CURRENT_WEATHER) + .setWeather(XiaomiProto.Weather.newBuilder().setCurrent( + XiaomiProto.WeatherCurrent.newBuilder() + .setTimeLocation(XiaomiProto.WeatherCurrentTimeLocation.newBuilder() + .setTimestamp(timestamp) + .setUnk2("") + .setCurrentLocationString(weatherSpec.location) + ) + .setWeatherCondition(HuamiWeatherConditions.mapToAmazfitBipWeatherCode(weatherSpec.currentConditionCode)) // *SEEMS* to work + .setTemperature(XiaomiProto.WeatherCurrentTemperature.newBuilder() + .setDegrees(weatherSpec.currentTemp - 273) // TODO: support inches for weather + .setSymbol("℃") + ) + .setHumidity(XiaomiProto.WeatherCurrentHumidity.newBuilder() + .setHumidity(weatherSpec.currentHumidity) + .setSymbol("%") + ) + .setUnk5(XiaomiProto.WeatherCurrentUnk5.newBuilder() + .setUnk1("") + .setUnk2(0) + ) + .setUnk6(XiaomiProto.WeatherCurrentUnk6.newBuilder() + .setUnk1("") + .setUnk2(0) + ) + .setUnk7(XiaomiProto.WeatherCurrentUnk7.newBuilder() + .setUnk1("") + .setUnk2(0) + ) + .setWarning(XiaomiProto.WeatherCurrentWarning.newBuilder() + .setCurrentWarning1(XiaomiProto.WeatherCurrentWarning1.newBuilder() + .setCurrentWarningText("") + .setCurrentWarningSeverityText("") + ) + ) + .setPressure(weatherSpec.pressure) + + )) + .build() + ); } private void setMeasurementSystem() { diff --git a/app/src/main/proto/xiaomi.proto b/app/src/main/proto/xiaomi.proto index 32e57a8b3..19616fd9b 100644 --- a/app/src/main/proto/xiaomi.proto +++ b/app/src/main/proto/xiaomi.proto @@ -635,7 +635,56 @@ message Weather { } message WeatherCurrent { + optional WeatherCurrentTimeLocation timeLocation = 1; + optional uint32 weatherCondition = 2; + optional WeatherCurrentTemperature temperature = 3; + optional WeatherCurrentHumidity humidity= 4; + optional WeatherCurrentUnk5 unk5 = 5; + optional WeatherCurrentUnk6 unk6 = 6; + optional WeatherCurrentUnk7 unk7 = 7; + optional WeatherCurrentWarning warning = 8; // Seems to be an array? + optional float pressure = 9; } +message WeatherCurrentTimeLocation { + optional string timestamp = 1; + optional string unk2 = 2; + optional string currentLocationString = 3; +} + +message WeatherCurrentTemperature { + optional string symbol = 1; + optional sint32 degrees = 2; +} + +message WeatherCurrentHumidity { + optional string symbol = 1; + optional sint32 humidity = 2; +} + +message WeatherCurrentUnk5 { + optional string unk1 = 1; + optional uint32 unk2 = 2; +} + +message WeatherCurrentUnk6 { + optional string unk1 = 1; + optional uint32 unk2 = 2; +} + +message WeatherCurrentUnk7 { + optional string unk1 = 1; + optional uint32 unk2 = 2; +} + +message WeatherCurrentWarning { + optional WeatherCurrentWarning1 currentWarning1 = 1; // FIXME: this is probably an array +} + +message WeatherCurrentWarning1 { + optional string currentWarningText = 1; + optional string currentWarningSeverityText = 2; +} + message WeatherDaily { }