sparky8512 / starlink-grpc-tools

Random scripts and other bits for interacting with the SpaceX Starlink user terminal hardware
The Unlicense
482 stars 64 forks source link

Check for and trigger software updates #89

Closed mtraynor7 closed 6 months ago

mtraynor7 commented 7 months ago

Is it possible to check for and install any available software updates for the dish using GRPC?

sparky8512 commented 7 months ago

I think so. If I recall correctly, a request to initiate an update showed up in the protocol some time ago, but I never looked into it because it's a bit difficult to test and I couldn't think of a substantial use case: the dish will update by itself automatically overnight if there is an update available. I can look into it further if you're interested, though.

On the "check for" side, there is an install_pending alert. However, I'm not sure whether that means the update has been downloaded already and will install next time the dish is rebooted or if the update must still be initiated via the afore mentioned request. There is also a more thorough SoftwareUpdateStats message included in the status response, but I never incorporated that into the tools, as that seems like it's related to that other request.

wcoekaer commented 7 months ago

I should try it out - there were some changes for business starlink that would allow for updates to be installed when you approve it rather than always overnight. Except for critical updates. It would come in handy for that. I have a business starlink setup, let me see if I can try it out, I never bothered to look.

On Apr 18, 2024, at 7:27 AM, sparky8512 @.***> wrote:

I think so. If I recall correctly, a request to initiate an update showed up in the protocol some time ago, but I never looked into it because it's a bit difficult to test and I couldn't think of a substantial use case: the dish will update by itself automatically overnight if there is an update available. I can look into it further if you're interested, though.

On the "check for" side, there is an install_pending alert. However, I'm not sure whether that means the update has been downloaded already and will install next time the dish is rebooted or if the update must still be initiated via the afore mentioned request. There is also a more thorough SoftwareUpdateStats message included in the status response, but I never incorporated that into the tools, as that seems like it's related to that other request.

— Reply to this email directly, view it on GitHubhttps://urldefense.com/v3/__https://github.com/sparky8512/starlink-grpc-tools/issues/89*issuecomment-2064008901__;Iw!!ACWV5N9M2RV99hQ!J69s7IHXXv6kYu7x365AuaergYtvJf5BDB87svjmfdtIl36Oq0NbkthQHuUabS9yWdyZbGggNS74QusyzoWp-TUWTfI$, or unsubscribehttps://urldefense.com/v3/__https://github.com/notifications/unsubscribe-auth/AHDMHYRBF4TS5TXFABFGSWTY57J6VAVCNFSM6AAAAABGMKDLEOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDANRUGAYDQOJQGE__;!!ACWV5N9M2RV99hQ!J69s7IHXXv6kYu7x365AuaergYtvJf5BDB87svjmfdtIl36Oq0NbkthQHuUabS9yWdyZbGggNS74QusyzoWptCZjJ00$. You are receiving this because you are subscribed to this thread.Message ID: @.***>

sparky8512 commented 7 months ago

A little more info on the update request(s):

It looks like there are 2 separate request messages for this: update, of type UpdateRequest, and software_update, of type SoftwareUpdateRequest. UpdateRequest and its corresponding response type are both empty messages, so I assume that is meant to just initiate the update attempt and the progress is to be monitored via get_status. By contrast, SoftwareUpdateRequest looks like it includes the actual binary data in the request message.

Unfortunately, when I tried update on my dish, I got a permission denied error, so that's probably one of the requests that will only work when done remotely. That's... technically possible to implement, but not something I'm willing to publish without permission from SpaceX as it involves interacting with their servers, not just the dish.

I did not get a permission error when I tried software_update, but I got a different error due to (deliberately) not following the right sequence. I don't have a firmware binary image to test and would not want to test that blindly on my personal dish, anyway, so I left it at that. I'm guessing this request is meant for cases where the dish cannot connect to the satellite network, so cannot rely on the remote authentication mechanism.

mtraynor7 commented 7 months ago

I'm happy to help test it with my dish - I find updates tend to begin automatically in the afternoon rather than overnight, so I'd like to fire a script overnight to manually initiate any available updates.

sparky8512 commented 7 months ago

I find updates tend to begin automatically in the afternoon rather than overnight ...

OK, that does sound like a pretty compelling use case. However, I think the best we're going to be able to do is poll the status for the "install pending" flag(s) and initiate a dish reboot if/when it shows pending. I'll hack together something for proof-of-concept testing. If that appears effective, it can be refined into something more usable.

The difficulty in testing this is that software updates only come down every week or 2, and sometimes longer, at least for me.

sparky8512 commented 7 months ago

... and no sooner had I claimed that, then another update went pending. How fortunate.

It does appear that rebooting is all that is required once the status indicated install is pending. Specifically, the install_pending alert was showing as true and the software_update_state field of the status showed REBOOT_REQUIRED. There is also a swupdate_reboot_ready flag in the status which was not showing true. That flag got added about a month ago, so maybe they just haven't implemented it, or maybe it means something different from what it sounds, as it seems redundant as it is.

Anyway, I can easily throw together something that works similar to the other scripts, but unless you want to call it from cron, or similar, this one may need more sophisticated timing control in order to handle the do-software-updates-at-a-specific-time use case.

mtraynor7 commented 7 months ago

Thank you, that sounds promising. Can you clarify where/how you are checking install_pending and software_update_state please?

I had assumed the update process itself would need to be initiated, but it seems the dish stages the updates itself and a reboot is the final step? So my plan is to simply have a cron job which checks these values and initiates a reboot of the dish when they're in the relevant states. Adding a function to these scripts to check these flags and trigger a dish reboot might be useful for some, but otherwise I'm happy with this approach.

sparky8512 commented 7 months ago

Can you clarify where/how you are checking install_pending and software_update_state please?

I was looking at the raw status result from a get_status request. The tools don't currently support the software_update_state field, but the install_pending alert can be polled by looking at either the alert_install_pending boolean item from the alert_detail group or the alerts integer item from the status group, in which it shows up as bit 7 (so & it with 128 to check).

I had assumed the update process itself would need to be initiated, but it seems the dish stages the updates itself and a reboot is the final step?

That's been my experience, although I have not confirmed that's what the mobile app does when you tell it to update right away. It's possible the update request message would cause it to check if an update is available and thus start the whole process earlier than it would have otherwise, or maybe it's related to the case @wcoekaer mentioned earlier on this issue.

So my plan is to simply have a cron job which checks these values and initiates a reboot of the dish when they're in the relevant states.

That should work. There is technically enough there already in the tools to do this, but you'd have to parse out the relevant alert, so it would require some additional scripting to do that, anyway.

sparky8512 commented 7 months ago

That commit adds the script in a branch, as it is mostly untested. If anyone wants to test it, you can pull the branch, or just the script itself (that is the only change for now) by grabbing https://github.com/sparky8512/starlink-grpc-tools/raw/update-checker/dish_check_update.py

I am considering adding cron-like scheduling (via croniter) as an option to avoid having to launch it from cron, but it should work fine to run it non-looping from cron, too.

mtraynor7 commented 6 months ago

Where can I find the loop_util module you reference on line 15?

sparky8512 commented 6 months ago

Sorry, I should have mentioned that, since I previously said you'd only need the new script. I added that file in a later change, also in the branch, but you can find it here: https://github.com/sparky8512/starlink-grpc-tools/raw/update-checker/loop_util.py

Additionally, if you want to use the new cron-like scheduling, you will need to do a pip install croniter, but the script should load fine without it unless you pass the command line option to use that. More detailed instruction is in the README.

I may merge it into the main branch soon, as it should work and I have verified that it doesn't break anything else, but I have yet to verify it against an actual software update.

sparky8512 commented 6 months ago

My dish got another software update yesterday, so I was able to test that the --install option works. This has now been merged into the main branch and I'm not planning any more work on this issue, so I'm going to close it as completed.