Pebble: Support multiple weather location with system weather app (on fw 4.x)

This commit is contained in:
Andreas Shimokawa
2025-11-19 20:43:15 +01:00
parent 4ced0d574c
commit 6959f7655e
2 changed files with 46 additions and 22 deletions
+2 -1
View File
@@ -1,8 +1,9 @@
### Changelog ### Changelog
#### Next #### Next
* Initial support for Pebble 2 Duo (Experimental) * Initial support for Pebble 2 Duo
* Pebble 2/2 Duo: Fix random crashes on disconnect * Pebble 2/2 Duo: Fix random crashes on disconnect
* Pebble: Support multiple weather location with system weather app (on fw 4.x)
#### 0.87.1 #### 0.87.1
@@ -443,12 +443,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
super(device); super(device);
mAppMessageHandlers.put(UUID_MORPHEUZ, new AppMessageHandlerMorpheuz(UUID_MORPHEUZ, PebbleProtocol.this)); mAppMessageHandlers.put(UUID_MORPHEUZ, new AppMessageHandlerMorpheuz(UUID_MORPHEUZ, PebbleProtocol.this));
mAppMessageHandlers.put(UUID_MISFIT, new AppMessageHandlerMisfit(UUID_MISFIT, PebbleProtocol.this)); mAppMessageHandlers.put(UUID_MISFIT, new AppMessageHandlerMisfit(UUID_MISFIT, PebbleProtocol.this));
mAppMessageHandlers.put(UUID_WEATHER, new AppMessageHandler(UUID_WEATHER, PebbleProtocol.this) { mAppMessageHandlers.put(UUID_WEATHER, new AppMessageHandler(UUID_WEATHER, PebbleProtocol.this));
@Override
public GBDeviceEvent[] onAppStart() {
return new GBDeviceEvent[]{new GBDeviceEventSendBytes(encodeSendWeather())};
}
});
if (!((PebbleCoordinator) device.getDeviceCoordinator()).isBackgroundJsEnabled(device)) { if (!((PebbleCoordinator) device.getDeviceCoordinator()).isBackgroundJsEnabled(device)) {
mAppMessageHandlers.put(UUID_PEBBLE_TIMESTYLE, new AppMessageHandlerTimeStylePebble(UUID_PEBBLE_TIMESTYLE, PebbleProtocol.this)); mAppMessageHandlers.put(UUID_PEBBLE_TIMESTYLE, new AppMessageHandlerTimeStylePebble(UUID_PEBBLE_TIMESTYLE, PebbleProtocol.this));
mAppMessageHandlers.put(UUID_PEBSTYLE, new AppMessageHandlerPebStyle(UUID_PEBSTYLE, PebbleProtocol.this)); mAppMessageHandlers.put(UUID_PEBSTYLE, new AppMessageHandlerPebStyle(UUID_PEBSTYLE, PebbleProtocol.this));
@@ -718,13 +713,25 @@ public class PebbleProtocol extends GBDeviceProtocol {
byte[] encodeActivateWeather(boolean activate) { byte[] encodeActivateWeather(boolean activate) {
if (activate) { if (activate) {
ByteBuffer buf = ByteBuffer.allocate(0x61); ByteBuffer buf = ByteBuffer.allocate(5 * LENGTH_UUID + 1);
buf.put((byte) 1); buf.put((byte) 5); // nr_locations
buf.order(ByteOrder.BIG_ENDIAN); buf.order(ByteOrder.BIG_ENDIAN);
buf.putLong(UUID_LOCATION.getMostSignificantBits()); buf.putLong(UUID_LOCATION.getMostSignificantBits());
buf.putLong(UUID_LOCATION.getLeastSignificantBits()); buf.putLong(UUID_LOCATION.getLeastSignificantBits());
// disable remaining 5 possible location
buf.put(new byte[60 - LENGTH_UUID]); // just put fake UUIDs for the remaining ones
buf.putLong(0);
buf.putLong(1);
buf.putLong(0);
buf.putLong(2);
buf.putLong(0);
buf.putLong(3);
buf.putLong(0);
buf.putLong(4);
return encodeBlobdb("weatherApp", BLOBDB_INSERT, BLOBDB_APPSETTINGS, buf.array()); return encodeBlobdb("weatherApp", BLOBDB_INSERT, BLOBDB_APPSETTINGS, buf.array());
} else { } else {
return encodeBlobdb("weatherApp", BLOBDB_DELETE, BLOBDB_APPSETTINGS, null); return encodeBlobdb("weatherApp", BLOBDB_DELETE, BLOBDB_APPSETTINGS, null);
@@ -1087,30 +1094,44 @@ public class PebbleProtocol extends GBDeviceProtocol {
@Override @Override
public byte[] encodeSendWeather() { public byte[] encodeSendWeather() {
final WeatherSpec weatherSpec = Weather.getWeatherSpec(); final List<WeatherSpec> weatherSpecs = Weather.getWeatherSpecs();
if (weatherSpec == null) { if (weatherSpecs.isEmpty()) {
LOG.warn("No weather found in singleton"); LOG.warn("No weather found in singleton");
return null; return null;
} }
byte[] forecastProtocol = null;
byte[] watchfaceProtocol = null; byte[] watchfaceProtocol = null;
byte[][] forecastProtocolBuf = {null, null, null, null, null};
byte[] deleteWeatherDataProtocol = null;
int length = 0; int length = 0;
if (mFwMajor >= 4) { if (mFwMajor >= 4) {
forecastProtocol = encodeWeatherForecast(weatherSpec); deleteWeatherDataProtocol = encodeBlobDBClear(BLOBDB_WEATHER);
length += forecastProtocol.length; length += deleteWeatherDataProtocol.length;
for (int i = 0; i < 5; i++) {
if (weatherSpecs.size() < i + 1)
break;
WeatherSpec weatherSpec = weatherSpecs.get(i);
forecastProtocolBuf[i] = encodeWeatherForecast(weatherSpec, i);
length += forecastProtocolBuf[i].length;
}
} }
AppMessageHandler handler = mAppMessageHandlers.get(currentRunningApp); AppMessageHandler handler = mAppMessageHandlers.get(currentRunningApp);
if (handler != null) { if (handler != null) {
watchfaceProtocol = handler.encodeUpdateWeather(weatherSpec); watchfaceProtocol = handler.encodeUpdateWeather(weatherSpecs.get(0));
if (watchfaceProtocol != null) { if (watchfaceProtocol != null) {
length += watchfaceProtocol.length; length += watchfaceProtocol.length;
} }
} }
ByteBuffer buf = ByteBuffer.allocate(length); ByteBuffer buf = ByteBuffer.allocate(length);
if (forecastProtocol != null) { if (deleteWeatherDataProtocol != null) {
buf.put(forecastProtocol); buf.put(deleteWeatherDataProtocol);
}
for (byte[] forecastProtocol : forecastProtocolBuf) {
if (forecastProtocol != null) {
buf.put(forecastProtocol);
}
} }
if (watchfaceProtocol != null) { if (watchfaceProtocol != null) {
buf.put(watchfaceProtocol); buf.put(watchfaceProtocol);
@@ -1119,8 +1140,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
return buf.array(); return buf.array();
} }
private byte[] encodeWeatherForecast(WeatherSpec weatherSpec) { private byte[] encodeWeatherForecast(WeatherSpec weatherSpec, int location) {
short currentTemp = (short) (weatherSpec.getCurrentTemp() - 273); short currentTemp = (short) (weatherSpec.getCurrentTemp() - 273);
short todayMax = (short) (weatherSpec.getTodayMaxTemp() - 273); short todayMax = (short) (weatherSpec.getTodayMaxTemp() - 273);
short todayMin = (short) (weatherSpec.getTodayMinTemp() - 273); short todayMin = (short) (weatherSpec.getTodayMinTemp() - 273);
@@ -1184,7 +1204,10 @@ public class PebbleProtocol extends GBDeviceProtocol {
LOG.info(s); LOG.info(s);
} }
return encodeBlobdb(UUID_LOCATION, BLOBDB_INSERT, BLOBDB_WEATHER, buf.array()); if (location == 0) {
return encodeBlobdb(UUID_LOCATION, BLOBDB_INSERT, BLOBDB_WEATHER, buf.array()); // compatibility for people who already had the weather app enabled
}
return encodeBlobdb(new UUID(0, location), BLOBDB_INSERT, BLOBDB_WEATHER, buf.array());
} }
private byte[] encodeActionResponse(UUID uuid, int iconId, String caption) { private byte[] encodeActionResponse(UUID uuid, int iconId, String caption) {