Repository navigation
fix(plugin): resolve string product ids and serve the iOS app plugin - #224
Open
AlexanderBabel wants to merge 1 commit into
Open
AlexanderBabel wants to merge 1 commit into
AlexanderBabel wants to merge 1 commit into
Conversation
The cloud lists newer models (e.g. roborock.vacuum.a226) under a string product id, so the import never fetched their app plugin and /api/v5/product answered with a hashed id that matches no plugin. The app then fails with "device initialization failed". The import now fetches the cloud's /api/v5/product to map models to their numeric id, and fetches /api/v1/appplugin for both type 2 (Android) and type 1 (iOS), which get different zips. The appplugin route answers iOS requests from the iOS catalog, falling back to the existing one. Fixes Python-roborock#221
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #221.
Problem
On a Qrevo Curv/Edge 2 Pro (
roborock.vacuum.a226), the official iOS app (4.74.02) showed "Device initialization failed" against the local server. The server log showedPOST /api/v1/apppluginbut no/plugin/proxy/...download. Two gaps caused it:30uADinyLKa3Qpga60B1Ke), on both the product and the device._plugin_product_ids()only acceptsint(...), so the import never asked for/api/v1/appplugin("error": "no product ids available")./api/v5/productthen answered withstable_int(...) % 1_000_000as the numeric id, which matches no plugin. The cloud has a numeric id for the model: its/api/v5/productreturns{"id": 199, "model": "roborock.vacuum.a226"}.type:1for iOS,2for Android. The import only fetchedtype: 2, and the route answered every request with that. The iOS app cannot load the Android zip.Fix
import_web_inventory_from_cloud.py): fetches the cloud's/api/v5/productintoplugin_catalogs.product. It maps string product ids to their numeric id by model, then fetches/api/v1/apppluginfortype: 2(appplugin, unchanged) andtype: 1(newappplugin_ios)./api/v5/product(product_service.py): for a model without an entry inMODEL_PRODUCT_ID_OVERRIDES, the numericidnow comes from the cloud catalog in the snapshot, before the hash fallback. Numeric ids andrriotidare unchanged./api/v1/appplugin: a request with"type": 1getsappplugin_ios. If that catalog is missing (snapshots imported before this change), it falls back to the current list, so existing setups behave as before. A GET without a body is unchanged.shared/data_helpers.model_product_ids()holds the model → id walk that both sides use.Nothing is hardcoded for the a226. Every id and URL comes from the cloud import.
Tests
tests/test_cloud_plugin_catalogs.py: with home data that uses a string product id, the import requestsapppluginwithproductids: [199]for bothtype1 and 2, and stores the product catalog and both plugin catalogs.tests/test_product_response.py: a string product id gets the cloud's numeric id for its model, andrriotidstays the string.tests/test_plugin_routes.py:POST /api/v1/apppluginreturns the iOS zip fortype: 1and the Android zip fortype: 2. A snapshot withoutappplugin_iosfalls back to the existing catalog.Full suite:
uv run pytest -qpasses (459 tests).Live check (Oct 2026), a226 on firmware 02.43.62, iOS app 4.74.02:
_fetch_plugin_catalogsfrom this branch against the real cloud with my imported session. It resolved30uADinyLKa3Qpga60B1Ke→ 199 and returned plugin 6846 with69588500….zipfor type 2 and22598cbf….zipfor type 1.Notes
endpoint_rules.pystill has an older copy of_build_product_responsethat nothing calls. I left it alone, as fix(api): add rriotid, categoryId, category code and agreements to /api/v5/product #207 did.appfeaturepluginandpluginsare still fetched only withtype: 2. I didn't check whether the cloud serves different zips for iOS there too./api/v5/productand the secondappplugin. Like the other catalogs, a failure is stored as anerrorand doesn't stop the import.