Add support for multiple batteries per device

This commit is contained in:
vanous
2021-11-02 14:37:47 +01:00
parent b0585fc852
commit 788f4d8ae0
11 changed files with 281 additions and 63 deletions
@@ -43,7 +43,7 @@ public class GBDaoGenerator {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
Schema schema = new Schema(34, MAIN_PACKAGE + ".entities"); Schema schema = new Schema(35, MAIN_PACKAGE + ".entities");
Entity userAttributes = addUserAttributes(schema); Entity userAttributes = addUserAttributes(schema);
Entity user = addUserInfo(schema, userAttributes); Entity user = addUserInfo(schema, userAttributes);
@@ -613,6 +613,7 @@ public class GBDaoGenerator {
Property deviceId = batteryLevel.addLongProperty("deviceId").primaryKey().notNull().getProperty(); Property deviceId = batteryLevel.addLongProperty("deviceId").primaryKey().notNull().getProperty();
batteryLevel.addToOne(device, deviceId); batteryLevel.addToOne(device, deviceId);
batteryLevel.addIntProperty("level").notNull(); batteryLevel.addIntProperty("level").notNull();
batteryLevel.addIntProperty("batteryIndex").notNull().primaryKey();;
return batteryLevel; return batteryLevel;
} }
@@ -22,11 +22,13 @@ import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils; import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
public class BatteryInfoActivity extends AbstractGBActivity { public class
BatteryInfoActivity extends AbstractGBActivity {
private static final Logger LOG = LoggerFactory.getLogger(BatteryInfoActivity.class); private static final Logger LOG = LoggerFactory.getLogger(BatteryInfoActivity.class);
GBDevice gbDevice; GBDevice gbDevice;
private int timeFrom; private int timeFrom;
private int timeTo; private int timeTo;
private int batteryIndex = 0;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@@ -42,6 +44,7 @@ public class BatteryInfoActivity extends AbstractGBActivity {
Bundle bundle = intent.getExtras(); Bundle bundle = intent.getExtras();
if (bundle != null) { if (bundle != null) {
gbDevice = bundle.getParcelable(GBDevice.EXTRA_DEVICE); gbDevice = bundle.getParcelable(GBDevice.EXTRA_DEVICE);
batteryIndex = bundle.getInt("BATTERY_INDEX", 0);
} else { } else {
throw new IllegalArgumentException("Must provide a device when invoking this activity"); throw new IllegalArgumentException("Must provide a device when invoking this activity");
} }
@@ -55,7 +58,7 @@ public class BatteryInfoActivity extends AbstractGBActivity {
timeTo = (int) (System.currentTimeMillis() / 1000); timeTo = (int) (System.currentTimeMillis() / 1000);
batteryInfoChartFragment.setDateAndGetData(gbDevice, timeFrom, timeTo); batteryInfoChartFragment.setDateAndGetData(gbDevice, batteryIndex, timeFrom, timeTo);
TextView battery_status_device_name_text = (TextView) findViewById(R.id.battery_status_device_name); TextView battery_status_device_name_text = (TextView) findViewById(R.id.battery_status_device_name);
TextView battery_status_battery_voltage = (TextView) findViewById(R.id.battery_status_battery_voltage); TextView battery_status_battery_voltage = (TextView) findViewById(R.id.battery_status_battery_voltage);
@@ -105,7 +108,7 @@ public class BatteryInfoActivity extends AbstractGBActivity {
battery_status_time_span_text.setText(text); battery_status_time_span_text.setText(text);
battery_status_date_from_text.setText(DateTimeUtils.formatDate(new Date(timeFrom * 1000L))); battery_status_date_from_text.setText(DateTimeUtils.formatDate(new Date(timeFrom * 1000L)));
battery_status_date_to_text.setText(DateTimeUtils.formatDate(new Date(timeTo * 1000L))); battery_status_date_to_text.setText(DateTimeUtils.formatDate(new Date(timeTo * 1000L)));
batteryInfoChartFragment.setDateAndGetData(gbDevice, timeFrom, timeTo); batteryInfoChartFragment.setDateAndGetData(gbDevice, batteryIndex, timeFrom, timeTo);
} }
@@ -141,7 +144,7 @@ public class BatteryInfoActivity extends AbstractGBActivity {
battery_status_time_span_seekbar.setProgress(0); battery_status_time_span_seekbar.setProgress(0);
battery_status_time_span_seekbar.setProgress(1); battery_status_time_span_seekbar.setProgress(1);
batteryInfoChartFragment.setDateAndGetData(gbDevice, timeFrom, timeTo); batteryInfoChartFragment.setDateAndGetData(gbDevice, batteryIndex, timeFrom, timeTo);
} }
}, currentDate.get(Calendar.YEAR), currentDate.get(Calendar.MONTH), currentDate.get(Calendar.DATE)).show(); }, currentDate.get(Calendar.YEAR), currentDate.get(Calendar.MONTH), currentDate.get(Calendar.DATE)).show();
} }
@@ -74,11 +74,13 @@ public class BatteryInfoChartFragment extends AbstractGBFragment {
private int startTime; private int startTime;
private int endTime; private int endTime;
private GBDevice gbDevice; private GBDevice gbDevice;
private int batteryIndex;
public void setDateAndGetData(GBDevice gbDevice, long startTime, long endTime) { public void setDateAndGetData(GBDevice gbDevice, int batteryIndex, long startTime, long endTime) {
this.startTime = (int) startTime; this.startTime = (int) startTime;
this.endTime = (int) endTime; this.endTime = (int) endTime;
this.gbDevice = gbDevice; this.gbDevice = gbDevice;
this.batteryIndex = batteryIndex;
try { try {
createRefreshTask("Visualizing data", getActivity()).execute(); createRefreshTask("Visualizing data", getActivity()).execute();
} catch (Exception e) { } catch (Exception e) {
@@ -174,12 +176,13 @@ public class BatteryInfoChartFragment extends AbstractGBFragment {
yAxisRight.setTextColor(CHART_TEXT_COLOR); yAxisRight.setTextColor(CHART_TEXT_COLOR);
} }
private List<? extends BatteryLevel> getBatteryLevels(DBHandler db, GBDevice device, int tsFrom, int tsTo) { private List<? extends BatteryLevel> getBatteryLevels(DBHandler db, GBDevice device, int batteryIndex, int tsFrom, int tsTo) {
BatteryLevelDao batteryLevelDao = db.getDaoSession().getBatteryLevelDao(); BatteryLevelDao batteryLevelDao = db.getDaoSession().getBatteryLevelDao();
Device dbDevice = DBHelper.findDevice(device, db.getDaoSession()); Device dbDevice = DBHelper.findDevice(device, db.getDaoSession());
QueryBuilder<BatteryLevel> qb = batteryLevelDao.queryBuilder(); QueryBuilder<BatteryLevel> qb = batteryLevelDao.queryBuilder();
qb.where(BatteryLevelDao.Properties.DeviceId.eq(dbDevice.getId())).orderAsc(BatteryLevelDao.Properties.Timestamp); qb.where(BatteryLevelDao.Properties.DeviceId.eq(dbDevice.getId())).orderAsc(BatteryLevelDao.Properties.Timestamp);
qb.where(BatteryLevelDao.Properties.BatteryIndex.eq(batteryIndex));
qb.where(BatteryLevelDao.Properties.Timestamp.gt(tsFrom)); qb.where(BatteryLevelDao.Properties.Timestamp.gt(tsFrom));
qb.where(BatteryLevelDao.Properties.Timestamp.lt(tsTo)); qb.where(BatteryLevelDao.Properties.Timestamp.lt(tsTo));
@@ -215,7 +218,7 @@ public class BatteryInfoChartFragment extends AbstractGBFragment {
@Override @Override
protected void doInBackground(DBHandler handler) { protected void doInBackground(DBHandler handler) {
List<? extends BatteryLevel> samples = getBatteryLevels(handler, gbDevice, startTime, endTime); List<? extends BatteryLevel> samples = getBatteryLevels(handler, gbDevice, batteryIndex, startTime, endTime);
DefaultBatteryChartsData dcd = null; DefaultBatteryChartsData dcd = null;
try { try {
dcd = fill_dcd(samples); dcd = fill_dcd(samples);
@@ -144,38 +144,51 @@ public class GBDeviceAdapterv2 extends RecyclerView.Adapter<GBDeviceAdapterv2.Vi
//begin of action row //begin of action row
//battery //battery
holder.batteryStatusBox.setVisibility(View.VISIBLE); // multiple battery support: at this point we support up to three batteries
short batteryLevel = device.getBatteryLevel(); // to support more batteries, the battery UI would need to be extended
float batteryVoltage = device.getBatteryVoltage();
BatteryState batteryState = device.getBatteryState();
if (batteryLevel != GBDevice.BATTERY_UNKNOWN) { holder.batteryStatusBox0.setVisibility(coordinator.getBatteryCount() > 0 ? View.VISIBLE : View.GONE);
holder.batteryStatusBox.setVisibility(View.VISIBLE); holder.batteryStatusBox1.setVisibility(coordinator.getBatteryCount() > 1 ? View.VISIBLE : View.GONE);
holder.batteryStatusLabel.setText(device.getBatteryLevel() + "%"); holder.batteryStatusBox2.setVisibility(coordinator.getBatteryCount() > 2 ? View.VISIBLE : View.GONE);
if (BatteryState.BATTERY_CHARGING.equals(batteryState) ||
BatteryState.BATTERY_CHARGING_FULL.equals(batteryState)) { LinearLayout[] batteryStatusBoxes = {holder.batteryStatusBox0, holder.batteryStatusBox1, holder.batteryStatusBox2};
holder.batteryIcon.setImageLevel(device.getBatteryLevel() + 100); TextView[] batteryStatusLabels = {holder.batteryStatusLabel0, holder.batteryStatusLabel1, holder.batteryStatusLabel2};
} else { ImageView[] batteryIcons = {holder.batteryIcon0, holder.batteryIcon1, holder.batteryIcon2};
holder.batteryIcon.setImageLevel(device.getBatteryLevel());
for (int battery = 0; battery < coordinator.getBatteryCount(); battery++) {
int batteryLevel = device.getBatteryLevel(battery);
float batteryVoltage = device.getBatteryVoltage(battery);
BatteryState batteryState = device.getBatteryState();
if (batteryLevel != GBDevice.BATTERY_UNKNOWN) {
batteryStatusBoxes[battery].setVisibility(View.VISIBLE);
batteryStatusLabels[battery].setText(device.getBatteryLevel(battery) + "%");
if (BatteryState.BATTERY_CHARGING.equals(batteryState) ||
BatteryState.BATTERY_CHARGING_FULL.equals(batteryState)) {
batteryIcons[battery].setImageLevel(device.getBatteryLevel(battery) + 100);
} else {
batteryIcons[battery].setImageLevel(device.getBatteryLevel(battery));
}
} else if (BatteryState.NO_BATTERY.equals(batteryState) && batteryVoltage != GBDevice.BATTERY_UNKNOWN) {
batteryStatusBoxes[battery].setVisibility(View.VISIBLE);
batteryStatusLabels[battery].setText(String.format(Locale.getDefault(), "%.2f", batteryVoltage));
batteryIcons[battery].setImageLevel(200);
} }
} else if (BatteryState.NO_BATTERY.equals(batteryState) && batteryVoltage != GBDevice.BATTERY_UNKNOWN) { final int finalBattery = battery;
holder.batteryStatusBox.setVisibility(View.VISIBLE); batteryStatusBoxes[battery].setOnClickListener(new View.OnClickListener() {
holder.batteryStatusLabel.setText(String.format(Locale.getDefault(), "%.2f", batteryVoltage)); @Override
holder.batteryIcon.setImageLevel(200); public void onClick(View v) {
Intent startIntent;
startIntent = new Intent(context, BatteryInfoActivity.class);
startIntent.putExtra(GBDevice.EXTRA_DEVICE, device);
startIntent.putExtra("BATTERY_INDEX", finalBattery);
context.startActivity(startIntent);
}
}
);
} }
holder.batteryStatusBox.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v) {
Intent startIntent;
startIntent = new Intent(context, BatteryInfoActivity.class);
startIntent.putExtra(GBDevice.EXTRA_DEVICE, device);
context.startActivity(startIntent);
}
}
);
holder.heartRateStatusBox.setVisibility((device.isInitialized() && coordinator.supportsRealtimeData() && coordinator.supportsHeartRateMeasurement(device)) ? View.VISIBLE : View.GONE); holder.heartRateStatusBox.setVisibility((device.isInitialized() && coordinator.supportsRealtimeData() && coordinator.supportsHeartRateMeasurement(device)) ? View.VISIBLE : View.GONE);
if (parent.getContext() instanceof ControlCenterv2) { if (parent.getContext() instanceof ControlCenterv2) {
ActivitySample sample = ((ControlCenterv2) parent.getContext()).getCurrentHRSample(); ActivitySample sample = ((ControlCenterv2) parent.getContext()).getCurrentHRSample();
@@ -590,9 +603,15 @@ public class GBDeviceAdapterv2 extends RecyclerView.Adapter<GBDeviceAdapterv2.Vi
TextView deviceStatusLabel; TextView deviceStatusLabel;
//actions //actions
LinearLayout batteryStatusBox; LinearLayout batteryStatusBox0;
TextView batteryStatusLabel; TextView batteryStatusLabel0;
ImageView batteryIcon; ImageView batteryIcon0;
LinearLayout batteryStatusBox1;
TextView batteryStatusLabel1;
ImageView batteryIcon1;
LinearLayout batteryStatusBox2;
TextView batteryStatusLabel2;
ImageView batteryIcon2;
ImageView deviceSpecificSettingsView; ImageView deviceSpecificSettingsView;
LinearLayout fetchActivityDataBox; LinearLayout fetchActivityDataBox;
ImageView fetchActivityData; ImageView fetchActivityData;
@@ -628,9 +647,18 @@ public class GBDeviceAdapterv2 extends RecyclerView.Adapter<GBDeviceAdapterv2.Vi
deviceStatusLabel = view.findViewById(R.id.device_status); deviceStatusLabel = view.findViewById(R.id.device_status);
//actions //actions
batteryStatusBox = view.findViewById(R.id.device_battery_status_box); batteryStatusBox0 = view.findViewById(R.id.device_battery_status_box);
batteryStatusLabel = view.findViewById(R.id.battery_status); batteryStatusLabel0 = view.findViewById(R.id.battery_status);
batteryIcon = view.findViewById(R.id.device_battery_status); batteryIcon0 = view.findViewById(R.id.device_battery_status);
batteryStatusBox1 = view.findViewById(R.id.device_battery_status_box1);
batteryStatusLabel1 = view.findViewById(R.id.battery_status1);
batteryIcon1 = view.findViewById(R.id.device_battery_status1);
batteryStatusBox2 = view.findViewById(R.id.device_battery_status_box2);
batteryStatusLabel2 = view.findViewById(R.id.battery_status2);
batteryIcon2 = view.findViewById(R.id.device_battery_status2);
deviceSpecificSettingsView = view.findViewById(R.id.device_specific_settings); deviceSpecificSettingsView = view.findViewById(R.id.device_specific_settings);
fetchActivityDataBox = view.findViewById(R.id.device_action_fetch_activity_box); fetchActivityDataBox = view.findViewById(R.id.device_action_fetch_activity_box);
fetchActivityData = view.findViewById(R.id.device_action_fetch_activity); fetchActivityData = view.findViewById(R.id.device_action_fetch_activity);
@@ -0,0 +1,54 @@
/* Copyright (C) 2017-2020 Andreas Shimokawa, protomors
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 <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.database.schema;
import android.database.sqlite.SQLiteDatabase;
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
import nodomain.freeyourgadget.gadgetbridge.database.DBUpdateScript;
import nodomain.freeyourgadget.gadgetbridge.entities.BaseActivitySummaryDao;
import nodomain.freeyourgadget.gadgetbridge.entities.BatteryLevelDao;
public class GadgetbridgeUpdate_35 implements DBUpdateScript {
@Override
public void upgradeSchema(SQLiteDatabase db) {
if (!DBHelper.existsColumn(BatteryLevelDao.TABLENAME, BatteryLevelDao.Properties.BatteryIndex.columnName, db)) {
String MOVE_DATA_TO_TEMP_TABLE = "ALTER TABLE battery_level RENAME TO battery_levels_temp;";
db.execSQL(MOVE_DATA_TO_TEMP_TABLE);
String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS \"BATTERY_LEVEL\" (\"TIMESTAMP\" INTEGER NOT NULL ," +
"\"DEVICE_ID\" INTEGER NOT NULL ,\"LEVEL\" INTEGER NOT NULL ,\"BATTERY_INDEX\" INTEGER NOT NULL ," +
"PRIMARY KEY (\"TIMESTAMP\" ,\"DEVICE_ID\" ,\"BATTERY_INDEX\" ) ON CONFLICT REPLACE) WITHOUT ROWID;";
db.execSQL(CREATE_TABLE);
String MIGATE_DATA = "insert into " + BatteryLevelDao.TABLENAME
+ " (" + BatteryLevelDao.Properties.Timestamp.columnName + ","
+ BatteryLevelDao.Properties.DeviceId.columnName + ","
+ BatteryLevelDao.Properties.BatteryIndex.columnName + ","
+ BatteryLevelDao.Properties.Level.columnName + ") "
+ " select Timestamp, Device_ID, 0, Level from battery_levels_temp;";
db.execSQL(MIGATE_DATA);
String DROP_TEMP_TABLE = "drop table if exists battery_levels_temp";
db.execSQL(DROP_TEMP_TABLE);
}
}
@Override
public void downgradeSchema(SQLiteDatabase db) {
}
}
@@ -24,7 +24,8 @@ import nodomain.freeyourgadget.gadgetbridge.model.BatteryState;
public class GBDeviceEventBatteryInfo extends GBDeviceEvent { public class GBDeviceEventBatteryInfo extends GBDeviceEvent {
public GregorianCalendar lastChargeTime = null; public GregorianCalendar lastChargeTime = null;
public BatteryState state = BatteryState.UNKNOWN; public BatteryState state = BatteryState.UNKNOWN;
public short level = 50; public int batteryIndex = 0;
public int level = 50;
public int numCharges = -1; public int numCharges = -1;
public float voltage = -1f; public float voltage = -1f;
@@ -246,4 +246,9 @@ public abstract class AbstractDeviceCoordinator implements DeviceCoordinator {
public Class<? extends Activity> getCalibrationActivity() { public Class<? extends Activity> getCalibrationActivity() {
return null; return null;
} }
@Override
public int getBatteryCount() {
return 1;
} //multiple battery support, default is 1, maximum is 3, 0 will disable the battery in UI
} }
@@ -348,4 +348,12 @@ public interface DeviceCoordinator {
*/ */
String[] getSupportedLanguageSettings(GBDevice device); String[] getSupportedLanguageSettings(GBDevice device);
/**
*
* Multiple battery support: Indicates how many batteries the device has.
* 1 is default, 3 is maximum at the moment (as per UI layout)
* 0 will disable the battery from the UI
*/
int getBatteryCount();
} }
@@ -17,6 +17,8 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */ along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.impl; package nodomain.freeyourgadget.gadgetbridge.impl;
import static nodomain.freeyourgadget.gadgetbridge.model.BatteryState.UNKNOWN;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Parcel; import android.os.Parcel;
@@ -75,10 +77,13 @@ public class GBDevice implements Parcelable {
private String mFirmwareVersion2; private String mFirmwareVersion2;
private String mModel; private String mModel;
private State mState = State.NOT_CONNECTED; private State mState = State.NOT_CONNECTED;
private short mBatteryLevel = BATTERY_UNKNOWN;
private float mBatteryVoltage = BATTERY_UNKNOWN; // multiple battery support: at this point we support up to three batteries
private int[] mBatteryLevel = {BATTERY_UNKNOWN, BATTERY_UNKNOWN, BATTERY_UNKNOWN};
private float[] mBatteryVoltage = {BATTERY_UNKNOWN, BATTERY_UNKNOWN, BATTERY_UNKNOWN};
private short mBatteryThresholdPercent = BATTERY_THRESHOLD_PERCENT; private short mBatteryThresholdPercent = BATTERY_THRESHOLD_PERCENT;
private BatteryState mBatteryState; private BatteryState[] mBatteryState = {UNKNOWN, UNKNOWN, UNKNOWN};
private short mRssi = RSSI_UNKNOWN; private short mRssi = RSSI_UNKNOWN;
private String mBusyTask; private String mBusyTask;
private List<ItemWithDetails> mDeviceInfos; private List<ItemWithDetails> mDeviceInfos;
@@ -111,9 +116,10 @@ public class GBDevice implements Parcelable {
mFirmwareVersion2 = in.readString(); mFirmwareVersion2 = in.readString();
mModel = in.readString(); mModel = in.readString();
mState = State.values()[in.readInt()]; mState = State.values()[in.readInt()];
mBatteryLevel = (short) in.readInt(); mBatteryLevel = in.createIntArray();
mBatteryVoltage = in.createFloatArray();
mBatteryThresholdPercent = (short) in.readInt(); mBatteryThresholdPercent = (short) in.readInt();
mBatteryState = (BatteryState) in.readSerializable(); mBatteryState = ordinalsToEnums(in.createIntArray());
mRssi = (short) in.readInt(); mRssi = (short) in.readInt();
mBusyTask = in.readString(); mBusyTask = in.readString();
mDeviceInfos = in.readArrayList(getClass().getClassLoader()); mDeviceInfos = in.readArrayList(getClass().getClassLoader());
@@ -136,9 +142,10 @@ public class GBDevice implements Parcelable {
dest.writeString(mFirmwareVersion2); dest.writeString(mFirmwareVersion2);
dest.writeString(mModel); dest.writeString(mModel);
dest.writeInt(mState.ordinal()); dest.writeInt(mState.ordinal());
dest.writeInt(mBatteryLevel); dest.writeIntArray(mBatteryLevel);
dest.writeFloatArray(mBatteryVoltage);
dest.writeInt(mBatteryThresholdPercent); dest.writeInt(mBatteryThresholdPercent);
dest.writeSerializable(mBatteryState); dest.writeIntArray(enumsToOrdinals(mBatteryState));
dest.writeInt(mRssi); dest.writeInt(mRssi);
dest.writeString(mBusyTask); dest.writeString(mBusyTask);
dest.writeList(mDeviceInfos); dest.writeList(mDeviceInfos);
@@ -154,6 +161,22 @@ public class GBDevice implements Parcelable {
} }
} }
private int[] enumsToOrdinals(BatteryState[] arrayEnum) {
int[] ordinals = new int[arrayEnum.length];
for (int i = 0; i < arrayEnum.length; i++) {
ordinals[i] = arrayEnum[i].ordinal();
}
return ordinals;
}
private BatteryState[] ordinalsToEnums(int[] arrayInt){
BatteryState[] enums = new BatteryState[arrayInt.length];
for(int i = 0; i<arrayInt.length; i++){
enums[i]=BatteryState.values()[arrayInt[i]];
}
return enums;
}
public String getName() { public String getName() {
return mName; return mName;
@@ -324,8 +347,12 @@ public class GBDevice implements Parcelable {
} }
private void unsetDynamicState() { private void unsetDynamicState() {
setBatteryLevel(BATTERY_UNKNOWN); setBatteryLevel(BATTERY_UNKNOWN, 0);
setBatteryState(BatteryState.UNKNOWN); setBatteryLevel(BATTERY_UNKNOWN, 1);
setBatteryLevel(BATTERY_UNKNOWN, 2);
setBatteryState(UNKNOWN, 0);
setBatteryState(UNKNOWN, 1);
setBatteryState(UNKNOWN, 2);
setFirmwareVersion(null); setFirmwareVersion(null);
setFirmwareVersion2(null); setFirmwareVersion2(null);
setRssi(RSSI_UNKNOWN); setRssi(RSSI_UNKNOWN);
@@ -471,21 +498,35 @@ public class GBDevice implements Parcelable {
* *
* @return the battery level in range 0-100, or -1 if unknown * @return the battery level in range 0-100, or -1 if unknown
*/ */
public short getBatteryLevel() { public int getBatteryLevel() {
return mBatteryLevel; return getBatteryLevel(0);
} }
public void setBatteryLevel(short batteryLevel) { public int getBatteryLevel(int index) {
return mBatteryLevel[index];
}
public void setBatteryLevel(int batteryLevel) {
setBatteryLevel(batteryLevel, 0);
}
public void setBatteryLevel(int batteryLevel, int index) {
if ((batteryLevel >= 0 && batteryLevel <= 100) || batteryLevel == BATTERY_UNKNOWN) { if ((batteryLevel >= 0 && batteryLevel <= 100) || batteryLevel == BATTERY_UNKNOWN) {
mBatteryLevel = batteryLevel; mBatteryLevel[index] = batteryLevel;
} else { } else {
LOG.error("Battery level musts be within range 0-100: " + batteryLevel); LOG.error("Battery level musts be within range 0-100: " + batteryLevel);
} }
} }
public void setBatteryVoltage(float batteryVoltage) { public void setBatteryVoltage(float batteryVoltage) {
setBatteryVoltage(batteryVoltage, 0);
}
public void setBatteryVoltage(float batteryVoltage, int index) {
if (batteryVoltage >= 0 || batteryVoltage == BATTERY_UNKNOWN) { if (batteryVoltage >= 0 || batteryVoltage == BATTERY_UNKNOWN) {
mBatteryVoltage = batteryVoltage; mBatteryVoltage[index] = batteryVoltage;
} else { } else {
LOG.error("Battery voltage must be > 0: " + batteryVoltage); LOG.error("Battery voltage must be > 0: " + batteryVoltage);
} }
@@ -497,15 +538,27 @@ public class GBDevice implements Parcelable {
* @return the battery voltage, or -1 if unknown * @return the battery voltage, or -1 if unknown
*/ */
public float getBatteryVoltage() { public float getBatteryVoltage() {
return mBatteryVoltage; return getBatteryVoltage(0);
}
public float getBatteryVoltage(int index) {
return mBatteryVoltage[index];
} }
public BatteryState getBatteryState() { public BatteryState getBatteryState() {
return mBatteryState; return getBatteryState(0);
}
public BatteryState getBatteryState(int index) {
return mBatteryState[index];
} }
public void setBatteryState(BatteryState mBatteryState) { public void setBatteryState(BatteryState mBatteryState) {
this.mBatteryState = mBatteryState; setBatteryState(mBatteryState, 0);
}
public void setBatteryState(BatteryState mBatteryState, int index) {
this.mBatteryState[index] = mBatteryState;
} }
public short getBatteryThresholdPercent() { public short getBatteryThresholdPercent() {
@@ -395,9 +395,9 @@ public abstract class AbstractDeviceSupport implements DeviceSupport {
protected void handleGBDeviceEvent(GBDeviceEventBatteryInfo deviceEvent) { protected void handleGBDeviceEvent(GBDeviceEventBatteryInfo deviceEvent) {
Context context = getContext(); Context context = getContext();
LOG.info("Got BATTERY_INFO device event"); LOG.info("Got BATTERY_INFO device event");
gbDevice.setBatteryLevel(deviceEvent.level); gbDevice.setBatteryLevel(deviceEvent.level, deviceEvent.batteryIndex);
gbDevice.setBatteryState(deviceEvent.state); gbDevice.setBatteryState(deviceEvent.state);
gbDevice.setBatteryVoltage(deviceEvent.voltage); gbDevice.setBatteryVoltage(deviceEvent.voltage, deviceEvent.batteryIndex);
if (deviceEvent.level == GBDevice.BATTERY_UNKNOWN) { if (deviceEvent.level == GBDevice.BATTERY_UNKNOWN) {
// no level available, just "high" or "low" // no level available, just "high" or "low"
@@ -455,6 +455,7 @@ public abstract class AbstractDeviceSupport implements DeviceSupport {
int ts = (int) (System.currentTimeMillis() / 1000); int ts = (int) (System.currentTimeMillis() / 1000);
BatteryLevel batteryLevel = new BatteryLevel(); BatteryLevel batteryLevel = new BatteryLevel();
batteryLevel.setTimestamp(ts); batteryLevel.setTimestamp(ts);
batteryLevel.setBatteryIndex(deviceEvent.batteryIndex);
batteryLevel.setDevice(device); batteryLevel.setDevice(device);
batteryLevel.setLevel(deviceEvent.level); batteryLevel.setLevel(deviceEvent.level);
handler.getDaoSession().getBatteryLevelDao().insert(batteryLevel); handler.getDaoSession().getBatteryLevelDao().insert(batteryLevel);
+61
View File
@@ -161,6 +161,67 @@
</LinearLayout> </LinearLayout>
<LinearLayout
android:id="@+id/device_battery_status_box1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_margin="3dp"
android:orientation="vertical">
<ImageView
android:id="@+id/device_battery_status1"
android:layout_width="40dp"
android:layout_height="40dp"
android:padding="3dp"
android:scaleType="fitXY"
card_view:srcCompat="@drawable/level_list_battery"
card_view:tint="@color/secondarytext" />
<TextView
android:id="@+id/battery_status1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:minWidth="36dp"
android:textColor="@color/secondarytext"
android:textStyle="bold"
tools:text="100%" />
</LinearLayout>
<LinearLayout
android:id="@+id/device_battery_status_box2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_margin="3dp"
android:orientation="vertical">
<ImageView
android:id="@+id/device_battery_status2"
android:layout_width="40dp"
android:layout_height="40dp"
android:padding="3dp"
android:scaleType="fitXY"
card_view:srcCompat="@drawable/level_list_battery"
card_view:tint="@color/secondarytext" />
<TextView
android:id="@+id/battery_status2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:minWidth="36dp"
android:textColor="@color/secondarytext"
android:textStyle="bold"
tools:text="100%" />
</LinearLayout>
<ImageView <ImageView
android:id="@+id/device_specific_settings" android:id="@+id/device_specific_settings"
android:layout_width="40dp" android:layout_width="40dp"