From e661a4661ab4b4c967365629db1c369e3d038c65 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Thu, 2 Jan 2025 00:15:07 +0100 Subject: [PATCH] Marstek B2500: decode more unknown values, display temperature values in activity --- .../DeviceSettingsPreferenceConst.java | 4 +- .../DeviceSpecificSettingsFragment.java | 3 +- .../marstek/SolarEquipmentStatusActivity.java | 36 +++++++++++++++++- .../marstek/MarstekB2500DeviceSupport.java | 38 ++++++++++++------- 4 files changed, 63 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java index 96bece172..8120e4f34 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSettingsPreferenceConst.java @@ -599,7 +599,7 @@ public class DeviceSettingsPreferenceConst { public static final String PREF_BATTERY_DISCHARGE_INTERVAL4_WATT = "battery_discharge_interval4_watt"; public static final String PREF_BATTERY_DISCHARGE_INTERVAL5_WATT = "battery_discharge_interval5_watt"; public static final String PREF_BATTERY_DISCHARGE_INTERVALS_SET = "battery_discharge_intervals_set"; - public static final String PREF_BATTERY_DISCHARGE_MANAUAL = "battery_discharge_manual"; + public static final String PREF_BATTERY_DISCHARGE_MANUAL = "battery_discharge_manual"; public static final String PREF_BATTERY_MINIMUM_CHARGE = "battery_minimum_charge"; - public static final String PREF_BATTERY_ALLOW_PASS_THOUGH = "battery_allow_pass_though"; + public static final String PREF_BATTERY_ALLOW_PASS_THROUGH = "battery_allow_pass_though"; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java index e7c744453..69f807c38 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java @@ -42,7 +42,6 @@ import android.media.AudioManager; import android.os.Bundle; import android.text.InputType; -import androidx.annotation.NonNull; import androidx.localbroadcastmanager.content.LocalBroadcastManager; import androidx.preference.EditTextPreference; import androidx.preference.ListPreference; @@ -884,7 +883,7 @@ public class DeviceSpecificSettingsFragment extends AbstractPreferenceFragment i addPreferenceHandlerFor("lock"); addPreferenceHandlerFor(PREF_BATTERY_MINIMUM_CHARGE); - addPreferenceHandlerFor(PREF_BATTERY_ALLOW_PASS_THOUGH); + addPreferenceHandlerFor(PREF_BATTERY_ALLOW_PASS_THROUGH); final Preference dischargeIntervalsSet = findPreference(PREF_BATTERY_DISCHARGE_INTERVALS_SET); if (dischargeIntervalsSet != null) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/marstek/SolarEquipmentStatusActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/marstek/SolarEquipmentStatusActivity.java index da859b3e3..71c14b3ca 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/marstek/SolarEquipmentStatusActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/marstek/SolarEquipmentStatusActivity.java @@ -53,6 +53,8 @@ public class SolarEquipmentStatusActivity extends AbstractGBActivity { public static String EXTRA_PANEL2_WATT = "panel2_watt"; public static String EXTRA_OUTPUT1_WATT = "output1_watt"; public static String EXTRA_OUTPUT2_WATT = "output2_watt"; + public static String EXTRA_TEMP1 = "temp1"; + public static String EXTRA_TEMP2 = "temp2"; private final Map widgetMap = new HashMap<>(); private GridLayout gridLayout; @@ -68,11 +70,15 @@ public class SolarEquipmentStatusActivity extends AbstractGBActivity { int battery_wh = extras.getInt(EXTRA_BATTERY_WH); int panel1_watt = extras.getInt(EXTRA_PANEL1_WATT); int panel2_watt = extras.getInt(EXTRA_PANEL2_WATT); + int temp1 = extras.getInt(EXTRA_TEMP1); + int temp2 = extras.getInt(EXTRA_TEMP2); int output1_watt = extras.getInt(EXTRA_OUTPUT1_WATT); int output2_watt = extras.getInt(EXTRA_OUTPUT2_WATT); updateWidget("battery", battery_pct + "%\n" + battery_wh + "Wh", (float) (battery_pct / 100.0)); updateWidget("panel1", panel1_watt + "W", (float) (panel1_watt / 380.0)); updateWidget("panel2", panel2_watt + "W", (float) (panel2_watt / 380.0)); + updateWidget("temp1", temp1 + "°C", (float) ((temp1 + 20) / 100.0)); + updateWidget("temp2", temp2 + "°C", (float) ((temp2 + 20) / 100.0)); updateWidget("output1", output1_watt + "W", (float) (output1_watt / 400.0)); updateWidget("output2", output2_watt + "W", (float) (output2_watt / 400.0)); @@ -92,6 +98,16 @@ public class SolarEquipmentStatusActivity extends AbstractGBActivity { }; } + public static int[] getColorsTemp() { + return new int[]{ + ContextCompat.getColor(GBApplication.getContext(), R.color.calories_resting_color), + ContextCompat.getColor(GBApplication.getContext(), R.color.vo2max_value_excellent_color), + ContextCompat.getColor(GBApplication.getContext(), R.color.body_energy_level_color), + ContextCompat.getColor(GBApplication.getContext(), R.color.vo2max_value_fair_color), + ContextCompat.getColor(GBApplication.getContext(), R.color.vo2max_value_poor_color), + }; + } + public static int[] getColorsOutput() { return new int[]{ ContextCompat.getColor(GBApplication.getContext(), R.color.chart_stress_unknown), @@ -110,6 +126,16 @@ public class SolarEquipmentStatusActivity extends AbstractGBActivity { }; } + public static float[] getSegmentsTemp() { + return new float[]{ + 0.2f, + 0.1f, + 0.2f, + 0.3f, + 0.2f, + }; + } + public static float[] getSegmentsOutput() { return new float[]{ 0.01f, @@ -126,7 +152,13 @@ public class SolarEquipmentStatusActivity extends AbstractGBActivity { gaugeValue.setText(value); GaugeDrawer gaugeDrawer = new GaugeDrawer(); ImageView gaugeBar = view.findViewById(R.id.gauge_bar); - gaugeDrawer.drawSegmentedGauge(gaugeBar, name.startsWith("output") ? getColorsOutput() : getColors(), name.startsWith("output") ? getSegmentsOutput() : getSegments(), gaugeFill, true, false); + if (name.startsWith("output")) { + gaugeDrawer.drawSegmentedGauge(gaugeBar, getColorsOutput(), getSegmentsOutput(), gaugeFill, true, false); + } else if (name.startsWith("temp")) { + gaugeDrawer.drawSegmentedGauge(gaugeBar, getColorsTemp(), getSegmentsTemp(), gaugeFill, true, false); + } else { + gaugeDrawer.drawSegmentedGauge(gaugeBar, getColors(), getSegments(), gaugeFill, true, false); + } } } @@ -142,6 +174,8 @@ public class SolarEquipmentStatusActivity extends AbstractGBActivity { createWidget("panel1", "Panel 1", 1); createWidget("panel2", "Panel 2", 1); createWidget("battery", "Battery", 2); + createWidget("temp1", "Temp 1", 1); + createWidget("temp2", "Temp 2", 1); createWidget("output1", "Output 1", 1); createWidget("output2", "Output 2", 1); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/marstek/MarstekB2500DeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/marstek/MarstekB2500DeviceSupport.java index 244f27188..21d89e1bb 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/marstek/MarstekB2500DeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/marstek/MarstekB2500DeviceSupport.java @@ -16,9 +16,9 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.service.devices.marstek; -import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_BATTERY_ALLOW_PASS_THOUGH; +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_BATTERY_ALLOW_PASS_THROUGH; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_BATTERY_DISCHARGE_INTERVALS_SET; -import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_BATTERY_DISCHARGE_MANAUAL; +import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_BATTERY_DISCHARGE_MANUAL; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_BATTERY_MINIMUM_CHARGE; import android.bluetooth.BluetoothGatt; @@ -157,7 +157,7 @@ public class MarstekB2500DeviceSupport extends AbstractBTLEDeviceSupport { Prefs devicePrefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(getDevice().getAddress())); switch (config) { case PREF_BATTERY_DISCHARGE_INTERVALS_SET: - if (devicePrefs.getBoolean(PREF_BATTERY_DISCHARGE_MANAUAL, true)) { + if (devicePrefs.getBoolean(PREF_BATTERY_DISCHARGE_MANUAL, true)) { sendCommand("set discharge intervals", encodeDischargeIntervalsFromPreferences()); } else { sendCommand("set dynamic discharge", COMMAND_SET_AUTO_DISCHARGE); @@ -167,8 +167,8 @@ public class MarstekB2500DeviceSupport extends AbstractBTLEDeviceSupport { case PREF_BATTERY_MINIMUM_CHARGE: sendCommand("set minimum charge", encodeMinimumChargeFromPreferences()); return; - case PREF_BATTERY_ALLOW_PASS_THOUGH: - if (devicePrefs.getBoolean(PREF_BATTERY_ALLOW_PASS_THOUGH, true)) { + case PREF_BATTERY_ALLOW_PASS_THROUGH: + if (devicePrefs.getBoolean(PREF_BATTERY_ALLOW_PASS_THROUGH, true)) { sendCommand("set allow pass-though", COMMAND_SET_BATTERY_ALLOW_PASS_THOUGH); } else { sendCommand("set disallow pass-though", COMMAND_SET_BATTERY_DISALLOW_PASS_THOUGH); @@ -189,18 +189,29 @@ public class MarstekB2500DeviceSupport extends AbstractBTLEDeviceSupport { boolean p2_active = buf.get() != 0x00; int p1_watt = buf.getShort(); int p2_watt = buf.getShort(); - buf.position(buf.position() + 2); // unknown; - + int battery_pct = buf.getShort() / 10; firmwareVersion = buf.get() & 0xff; boolean battery_allow_passthrough = buf.get() != 0x01; boolean battery_manual_discharge_intervals = buf.get() != 0x01; - buf.position(buf.position() + 3); // skip unknown + buf.position(buf.position() + 1); // skip unknown + boolean output1_active = buf.get() != 0x00; + boolean output2_active = buf.get() != 0x00; byte battery_max_use_pct = buf.get(); int output_to_inverter_target = buf.getShort(); - buf.position(buf.position() + 1); // skip unknown + int light_condition = buf.get(); // 1 = low light or none, 2 = some light, 0 = good light condition (?) int battery_wh = buf.getShort(); int output_to_inverter_1_watt = buf.getShort(); int output_to_inverter_2_watt = buf.getShort(); + buf.position(buf.position() + 3); // skip unknown + int hour_utc = buf.get(); + int minute_utc = buf.get(); + int temperature_sensor_1 = buf.getShort(); + int temperature_sensor_2 = buf.getShort(); + buf.position(buf.position() + 3); // skip unknown + int battery_charging_wh_24h = buf.getInt(); + int battery_discharging_wh_24h = buf.getInt(); + int input_wh_last_24h = buf.getInt(); + int output_wh_last_24h = buf.getInt(); int battery_minimum_charge_pct = 100 - battery_max_use_pct; int output_to_inverter_sum_watt = output_to_inverter_1_watt + output_to_inverter_2_watt; @@ -212,12 +223,11 @@ public class MarstekB2500DeviceSupport extends AbstractBTLEDeviceSupport { getDevice().sendDeviceUpdateIntent(getContext()); devicePrefsEdit.putString(PREF_BATTERY_MINIMUM_CHARGE, String.valueOf(battery_minimum_charge_pct)); - devicePrefsEdit.putBoolean(PREF_BATTERY_DISCHARGE_MANAUAL, battery_manual_discharge_intervals); - devicePrefsEdit.putBoolean(PREF_BATTERY_ALLOW_PASS_THOUGH, battery_allow_passthrough); + devicePrefsEdit.putBoolean(PREF_BATTERY_DISCHARGE_MANUAL, battery_manual_discharge_intervals); + devicePrefsEdit.putBoolean(PREF_BATTERY_ALLOW_PASS_THROUGH, battery_allow_passthrough); devicePrefsEdit.apply(); devicePrefsEdit.commit(); - int battery_pct = (int) Math.ceil((battery_wh / 2240.0f) * 100); getDevice().setBatteryLevel(battery_pct); getDevice().sendDeviceUpdateIntent(getContext()); @@ -226,6 +236,8 @@ public class MarstekB2500DeviceSupport extends AbstractBTLEDeviceSupport { intent.putExtra(SolarEquipmentStatusActivity.EXTRA_BATTERY_PCT, battery_pct); intent.putExtra(SolarEquipmentStatusActivity.EXTRA_PANEL1_WATT, p1_watt); intent.putExtra(SolarEquipmentStatusActivity.EXTRA_PANEL2_WATT, p2_watt); + intent.putExtra(SolarEquipmentStatusActivity.EXTRA_TEMP1, temperature_sensor_1); + intent.putExtra(SolarEquipmentStatusActivity.EXTRA_TEMP2, temperature_sensor_2); intent.putExtra(SolarEquipmentStatusActivity.EXTRA_OUTPUT1_WATT, output_to_inverter_1_watt); intent.putExtra(SolarEquipmentStatusActivity.EXTRA_OUTPUT2_WATT, output_to_inverter_2_watt); LocalBroadcastManager.getInstance(getContext()).sendBroadcast(intent); @@ -307,7 +319,7 @@ public class MarstekB2500DeviceSupport extends AbstractBTLEDeviceSupport { private byte[] encodeDischargeIntervalsFromPreferences() { Prefs devicePrefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(getDevice().getAddress())); - if (devicePrefs.getBoolean(PREF_BATTERY_DISCHARGE_MANAUAL, true)) { + if (devicePrefs.getBoolean(PREF_BATTERY_DISCHARGE_MANUAL, true)) { int nr_invervals = (firmwareVersion >= 220) ? 5 : 3; // old firmware V210 only had 3 intervals it seems, so set only 3 int length = 5 + nr_invervals * 7;