{"slug": "building-the-first-dart-flutter-client-for-mg-saic-connected-vehicles-where-ai", "title": "Building the first Dart/Flutter client for MG/SAIC connected vehicles: where AI did more than write code", "summary": "A developer has built the first Dart/Flutter client for SAIC connected vehicles, creating a pure Dart package called `saic_ismart` that enables mobile apps to directly communicate with the SAIC iSmart API. The package, which supports MG, Roewe, and Maxus/LDV vehicles, was developed by reverse-engineering the encrypted REST API protocol that uses AES-128-CBC encryption and HMAC-SHA-256 signatures. The developer used Claude AI to analyze existing Python and Java client implementations and generate a technical specification, which served as the foundation for porting the authentication and encryption pipeline to Dart.", "body_md": "Last weekend, I unlocked my car using my own Dart package (according to pub.dev, the first one ever built for it). I walked down to the parking lot, opened the app, tapped the button, heard the clunk. \"Worth it.\" Then I locked it again, went back upstairs, and called it a productive Sunday.\n\nBut let's get back a few months earlier, when I had bought a connected MG. I opened the official app, and like any developer who gets a new piece of technology, I spent about five minutes enjoying it as a normal person. Then I started wondering how it worked, what APIs were behind the app, and whether I could build something on top of it myself.\n\nA quick search confirmed that no Dart package existed for the SAIC iSmart API. That's how I ended up building the first one.\n\nMy initial approach was to decompile the official app.\n\nI extracted the APK directly from my phone via `adb`\n\nand decompiled it with `apktool`\n\n. The official iSmart app is a native Kotlin Android app.\n\nMost of the business logic is protected by ijiami encryption, so the core algorithms aren't readable statically. From the unprotected resources (strings, drawables, layout files) I was able to confirm a handful of things: undocumented features, error codes, model naming conventions. Useful context, but not enough. The actual API protocol wasn't there. It lives in the encrypted DEX (the compiled Android bytecode), and I had hit a wall.\n\nI wasn't the first to hit that wall. A GitHub organization called [SAIC-iSmart-API](https://github.com/SAIC-iSmart-API) has been reverse-engineering the SAIC API for years via traffic capture. They have a Python client, a Java client, a Home Assistant integration, an MQTT gateway, and even a [dedicated documentation repo](https://github.com/SAIC-iSmart-API/documentation) with real captured API responses.\n\nWhat wasn't covered was mobile-first development. No Dart client, no Swift client, no TypeScript package designed for mobile development. The Java client exists but is built for server-side use (Maven, MQTT gateways, Spring). A workaround exists: run the Python client on a server and use it as a proxy. But a mobile app should ideally call the API directly.\n\nSo, as a Flutter developer, I built `saic_ismart`\n\n: the first pure Dart package for the SAIC iSmart API. MG, Roewe, Maxus/LDV: brands that together represent millions of connected vehicles across Europe, Australia, India, and beyond.\n\nThe SAIC API isn't officially documented. There's no Swagger file, no official SDK. Everything I know about it came from reading the Python and Java clients line by line (well, Claude did most of the reading), cross-referenced with the community documentation repo.\n\nHere's what's actually going on under the hood.\n\nThe SAIC API isn't REST. It's encrypted REST, with AES-128-CBC on every request, HMAC-SHA-256 signatures, and an event-id polling loop for asynchronous commands. Non-trivial to implement, but the Python client had a test vector. Matching it exactly in Dart was the first real milestone.\n\nA few other things worth knowing before you use it:\n\n`sha256(vin)`\n\n`sword:sword_secret`\n\nSome of these quirks are just amusing. Others are real constraints. The package surfaces them clearly so you know exactly what you're dealing with.\n\nClaude Code was part of my stack on this one, and it made a real difference. Not just for code generation.\n\nBefore writing a single line of Dart, I had Claude analyze both the Python and Java repos and produce a concrete technical spec: authentication flow, encryption pipeline, endpoint behavior, known quirks. What would have taken days of reading became a structured document in a fraction of the time. That's how `TECHNICAL_REFERENCE.md`\n\nwas born, not as an afterthought but as the foundation the implementation was built on.\n\nClaude also helped port the AES-128-CBC crypto pipeline from Python to Dart and write the HMAC-SHA-256 implementation with the right key derivation. Technically straightforward once you know what to do, but tedious to get right.\n\nThere's a limit to what AI can do here though. No language model can plug a phone into a car and tell you what the raw values actually mean in the real world. For that, I had to test on my MG3 EU. *(Though technically, an MCP integration could have automated that too. Maybe next time.)*\n\nThe Python client leaves some fields uninterpreted. So I ran the code, looked at the numbers, and reasoned about them. A few examples:\n\n| Field | Raw value | Unit | Converted |\n|---|---|---|---|\n| Mileage | `243790` |\ndecameters | 24 379 km |\n| Tyre pressure (FL) | `61` |\nPSI×2 | 30.5 PSI / 2.1 bar |\n| Tyre pressure (RR) | `70` |\nPSI×2 | 35 PSI / 2.4 bar |\n\nMany other fields follow similar patterns: sentinel values, unexpected scales, units that only make sense once you cross-reference with the real world. All of these field experiments enriched the `TECHNICAL_REFERENCE.md`\n\n, turning it from a protocol spec into something that actually reflects how the API behaves on a real vehicle.\n\nHere's what the package actually lets you do:\n\n`vehicleModelConfiguration`\n\nand exposes 23 typed gettersA few lines of setup, then straight to the data:\n\n```\nfinal client = SaicClient(\n  config: SaicConfig(\n    username: 'you@example.com',\n    password: 'yourpassword',\n    region: SaicRegion.europe,\n  ),\n);\n\nawait client.login();\n\nfinal vehicles = await client.getVehicles();\nfinal vin = vehicles.first.vin;\n\n// Status\nfinal status = await client.getVehicleStatus(vin);\nprint(status.basicVehicleStatus?.mileageKm);                // 24447.0\nprint(status.basicVehicleStatus?.lockState);                // LockStatus.locked\nprint(status.basicVehicleStatus?.frontLeftTyrePressureBar); // 2.48\n\n// Remote commands\nawait client.lockVehicle(vin);\nawait client.startClimate(vin, temperatureIndex: 8);\nawait client.controlHeatedSeats(vin, driverLevel: HeatLevel.medium);\nawait client.findMyCar(vin);\n```\n\nAll API calls are serialized. The SAIC server doesn't support concurrent requests on the same session.\n\nThe first time I unlocked my car from my own Flutter app, not from iSmart, not from a terminal, but from a UI I had built on top of code I had written, was a genuinely satisfying moment. And it kept happening: the first successful `findMyCar()`\n\ntriggering the horn from across the street, the first time heated seats started before I even got to the car. Each feature that went from \"POST /vehicle/control\" to a real physical reaction felt like a small proof of concept becoming real.\n\n452 tests. 160/160 on pub.dev. 23 vehicle feature detection getters. Tested in production on a real MG3 EU. Pure Dart, no native code, works in any Flutter or Dart project.\n\nThe package is on pub.dev: [saic_ismart](https://pub.dev/packages/saic_ismart)\n\nEV features like battery SoC, charging management, and climate scheduling are the natural next milestone. I don't own an EV myself, so I can't develop or validate those features without the right hardware. I would be genuinely happy to welcome contributors who own an MG4, ZS EV, or Roewe. The architecture is in place and ready to be extended. Open an issue on GitHub.\n\nThe client is pure Dart, so wherever Flutter runs, this can run too. The package is a foundation. Build what's missing.\n\n*Built with significant help from the research work of the SAIC-iSmart-API community. Their work greatly accelerated my development.*", "url": "https://wpnews.pro/news/building-the-first-dart-flutter-client-for-mg-saic-connected-vehicles-where-ai", "canonical_source": "https://dev.to/tanguymossion/building-the-first-dartflutter-client-for-mgsaic-connected-vehicles-where-ai-did-more-than-write-3anc", "published_at": "2026-06-04 07:24:53+00:00", "updated_at": "2026-06-04 07:42:02.592301+00:00", "lang": "en", "topics": ["artificial-intelligence"], "entities": ["MG", "SAIC", "Dart", "Flutter", "iSmart", "GitHub", "SAIC-iSmart-API"], "alternates": {"html": "https://wpnews.pro/news/building-the-first-dart-flutter-client-for-mg-saic-connected-vehicles-where-ai", "markdown": "https://wpnews.pro/news/building-the-first-dart-flutter-client-for-mg-saic-connected-vehicles-where-ai.md", "text": "https://wpnews.pro/news/building-the-first-dart-flutter-client-for-mg-saic-connected-vehicles-where-ai.txt", "jsonld": "https://wpnews.pro/news/building-the-first-dart-flutter-client-for-mg-saic-connected-vehicles-where-ai.jsonld"}}