The chargers you own, on the phone as well
The web's Charging page grew a real home half while the phone kept a demo one. There, a charger is a record imported from a connected service; here it was a hardcoded row called "Home charger", and the only real thing on the tab was a single OCPP control card. Modbus had been a working transport for a while, and the phone had no way to give it the address it needs. The home tab is now the four cards the web shows, about whichever charger is picked, and the list of the ones you have imported. Control acts on the charger and offers what the transport actually has — boost on Modbus, clear-limit and reset on OCPP. Connection asks for a serial or an address depending on which, and falls back to a text box for a serial the account does not list. Readings render the Modbus snapshot the way it gets asked about: the per-phase matrix, what the charger is doing, what it is set to, what it is, and any alarm word. Information stands without a control mode at all, because what a charger is is known either way; beside it the service's own view of whether it is reachable, asked for when the tab is opened rather than on every build. Rearranging is the one place the two apps differ, for the reason the car's view picker already differs: the web drags the tab bar and the card headings, and on a touch screen the bar owns that gesture and a heading is the fold toggle. Both arrangements are made in a sheet with handles instead, and still saved to chargerTabOrder / chargerCardOrder on the profile — so an arrangement made in either app shows up in the other. Which cards are folded stays on the device. Settings groups its integrations into the same categories the API Server panel does, says Online as well as Offline, and shows firmware in a charger's line. Shared strings are copied out of the web's i18n files rather than retyped, per TRANSLATIONS.md; only the arrange sheet's own three are written here. The readings and information cards look up some sixty keys by name at render time, so models_format_test now guards those the way it guards the car's — an enum value is deliberately left out, since a charger may report a number this release has never heard of and falling back to it is the point. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
3c64d6e84c
commit
641f427db4
11 files changed
+2961
-339
No files matched your search
@@ -17,6 +17,7 @@ import "package:drivervault_phone/main.dart";
|
||||
import "package:drivervault_phone/models.dart";
|
||||
import "package:drivervault_phone/screens/car_form_sheet.dart";
|
||||
import "package:drivervault_phone/screens/car_view_sheet.dart";
|
||||
import "package:drivervault_phone/screens/charging_screen.dart";
|
||||
import "package:drivervault_phone/service_parts.dart";
|
||||
|
||||
void main() {
|
||||
@@ -498,6 +499,51 @@ void main() {
|
||||
expectLabelled("car.provider.metrics.$key");
|
||||
}
|
||||
});
|
||||
|
||||
test("the charging page's tabs and cards", () {
|
||||
for (final key in kChargerTabKeys) {
|
||||
expectLabelled("charging.tabs.$key");
|
||||
}
|
||||
// The cards are named by their own headings rather than by their keys, so
|
||||
// the arrange sheet reads like the page. Those headings are the labels.
|
||||
for (final key in ["charging.control.title", "charging.control.connectionTitle",
|
||||
"charging.modbus.title", "charging.info.title"]) {
|
||||
expectLabelled(key);
|
||||
}
|
||||
});
|
||||
|
||||
test("everything the charger information card names", () {
|
||||
// Every row is drawn every time, so a missing label is a raw key path in
|
||||
// the middle of the card rather than a row that quietly stays away.
|
||||
for (final key in ["vendor", "model", "firmware", "serial", "site", "siteId", "sources",
|
||||
"power", "connector", "state", "chargePower", "ocpp", "providerId",
|
||||
"added", "online", "offline", "refresh", "title", "empty"]) {
|
||||
expectLabelled("charging.info.$key");
|
||||
}
|
||||
// The service's own word for how a charger is registered. Mirrors the
|
||||
// sources a chargerSource reports in the API's chargerproviders.go; an
|
||||
// unlisted one falls back to the slug, which is why these are named.
|
||||
for (final key in ["standalone", "site", "bound"]) {
|
||||
expectLabelled("charging.info.sourceNames.$key");
|
||||
}
|
||||
});
|
||||
|
||||
test("every Modbus reading the card can show", () {
|
||||
// Mirrors the fields of ModbusStatus in the API's ankersolix/modbus.go
|
||||
// that the readings card asks for by name. The enum values below it are
|
||||
// deliberately not here: an unlisted number falls back to itself, because
|
||||
// the charger may report one this release has never heard of.
|
||||
for (final key in ["title", "phases", "live", "settings", "device", "alarms", "phase",
|
||||
"voltage", "current", "activePower", "reactivePower", "apparentPower",
|
||||
"lineToLine", "power", "sessionDuration", "cpSignal", "cpVoltage",
|
||||
"phaseMode", "relayTemps", "pwm", "maxCurrentSet", "timeout",
|
||||
"phaseSetting", "boostSet", "lastCommand", "chargingMode",
|
||||
"loadBalancing", "solarBalancing", "ledBrightness", "model", "serial",
|
||||
"firmware", "hardware", "productNumber", "ratedPower", "currentRange",
|
||||
"ocppLink", "mqttLink", "alarmsHint"]) {
|
||||
expectLabelled("charging.modbus.$key");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test("no key is left behind in a translation", () {
|
||||
|
||||
Reference in new issue
Block a user