Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auto-sync Cockpit settings with BlueOS #701

Merged

Conversation

rafaellehmkuhl
Copy link
Member

@rafaellehmkuhl rafaellehmkuhl commented Jan 24, 2024

This is a major patch, that changes how Cockpit works with its settings fundamentally.

With it, instead of having the browser localStorage as the source of truth for its settings, Cockpit now uses the backend (provided here by the bag-of-holdings service on BlueOS) to sync Cockpit's storage with BlueOS.

There's a pipeline, where Cockpit first tries to fetch its settings from BlueOS. We call it the initial sync. If the values differ, the user will be asked which one they want to keep.

After a successful sync, it then starts to use its own variables, now synced, as the new source of truth. We do that so the settings are always stored in the vehicle, but in the case the user changes something in Cockpit, this change is pushed to the BlueOS storage as the new (updated) value.

In case something goes wrong during the initial fetch (e.g.: the vehicle was not connected yet), Cockpit will keep trying to sync. When the vehicle connects, if the user has made no change to the settings, nothing will happen, but if the user has made some change during this interval, a popup will open asking if the user prefers to keep the changes made in Cockpit or prefers to use the value stored on BlueOS. We do that so we don't overwrite changes explicitly made by the user.

image

I'm opening this as a draft because I'm still testing to see if everything works correctly, but the code structure is ready and there won't be major changes.

Fix #666.
To be merged after #559.

@goasChris
Copy link
Contributor

Hello Rafael :) I was hoping to include this PR in my testing branch, to give it some time in the water, but there are a few merge conflicts against current master, for example: #857

I'm a little bit torn, as I tried to fix it up, but then I end up with some parts of the code that is now using the old useStorage() method, and I am not familiar enough with the codebase to tell if this is going to be okay'ish or if it could cause trouble.

Any chance you could rebase this on current master when you have some spare time? I know it is not a small ask, so no rush, just wanted to let you know that this currently making it a bit difficult for me to test :) Much love, thank you for all your hard work <3

@rafaellehmkuhl
Copy link
Member Author

Hello Rafael :) I was hoping to include this PR in my testing branch, to give it some time in the water, but there are a few merge conflicts against current master, for example: #857

I'm a little bit torn, as I tried to fix it up, but then I end up with some parts of the code that is now using the old useStorage() method, and I am not familiar enough with the codebase to tell if this is going to be okay'ish or if it could cause trouble.

Any chance you could rebase this on current master when you have some spare time? I know it is not a small ask, so no rush, just wanted to let you know that this currently making it a bit difficult for me to test :) Much love, thank you for all your hard work <3

Hey Chris! Everything cool?

Sure! Let me take a look at that.
This PR is actually almost ready, I just need to fix some edge-cases.
Will rebase this now.

@rafaellehmkuhl rafaellehmkuhl force-pushed the auto-sync-cockpit-settings branch from 886e307 to 9d76664 Compare April 30, 2024 12:56
@rafaellehmkuhl
Copy link
Member Author

@goasChris just rebased it. Can you take a look?

@goasChris
Copy link
Contributor

Yep, no problems pulling in the PR now :) Well, besides failing CI/autotests, but I'm not too concerned about that, hehe. Thank you very much!

@rafaellehmkuhl rafaellehmkuhl force-pushed the auto-sync-cockpit-settings branch from 9d76664 to 76493d9 Compare April 30, 2024 14:50
@rafaellehmkuhl
Copy link
Member Author

rafaellehmkuhl commented Apr 30, 2024

Yep, no problems pulling in the PR now :) Well, besides failing CI/autotests, but I'm not too concerned about that, hehe. Thank you very much!

Nice! No problem! Also, just fixed the CI, it was an unused import left in the code.

Let us know if you have anything more, and feel free to open issues around problems and/or feature requests, so we can track and discuss them!

Edit: strangely, there's a test for widget-loading failing, even if this part of the code wasn't touched here. Will investigate more.

@goasChris
Copy link
Contributor

I've tried to debug why the tests are failing, but not being very familiar with ts, bun or vitest for that matter, I essentially just ended up setting a higher timeout, and printing a bunch of stuff. Unsure if its useful, or if its just noise.

stdout | src/tests/libs/widgets-loader.test.ts > Test widgets exist
Starting enum_to_files_checker...
Importing: @/components/widgets/Attitude.vue at 0 ms
Importing: @/components/widgets/Compass.vue at 0 ms
Importing: @/components/widgets/DepthHUD.vue at 0 ms
Importing: @/components/widgets/CompassHUD.vue at 1 ms
Importing: @/components/widgets/IFrame.vue at 1 ms
Importing: @/components/widgets/ImageView.vue at 1 ms
Importing: @/components/widgets/Map.vue at 1 ms
Importing: @/components/widgets/MiniWidgetsBar.vue at 1 ms
Importing: @/components/widgets/URLVideoPlayer.vue at 1 ms
Importing: @/components/widgets/VideoPlayer.vue at 1 ms
Importing: @/components/widgets/VirtualHorizon.vue at 1 ms
...
stderr | src/tests/libs/widgets-loader.test.ts > Test widgets exist
Failed to import: @/components/widgets/ImageView.vue at 1292 ms TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".css" for /home/chris/repos/cockpit/node_modules/vuetify/lib/components/VBtn/VBtn.css
    at Object.getFileProtocolModuleFormat [as file:] (node:internal/modules/esm/get_format:160:9)
    at defaultGetFormat (node:internal/modules/esm/get_format:203:36)
    at defaultLoad (node:internal/modules/esm/load:143:22)
    at async nextLoad (node:internal/modules/esm/hooks:865:22)
    at async Hooks.load (node:internal/modules/esm/hooks:448:20)
    at async handleMessage (node:internal/modules/esm/worker:196:18) {
  code: 'ERR_UNKNOWN_FILE_EXTENSION'
}
Failed to import: @/components/widgets/URLVideoPlayer.vue at 1294 ms TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".css" for /home/chris/repos/cockpit/node_modules/vuetify/lib/components/VBtn/VBtn.css
    at Object.getFileProtocolModuleFormat [as file:] (node:internal/modules/esm/get_format:160:9)
    at defaultGetFormat (node:internal/modules/esm/get_format:203:36)
    at defaultLoad (node:internal/modules/esm/load:143:22)
    at async nextLoad (node:internal/modules/esm/hooks:865:22)
    at async Hooks.load (node:internal/modules/esm/hooks:448:20)
    at async handleMessage (node:internal/modules/esm/worker:196:18) {
  code: 'ERR_UNKNOWN_FILE_EXTENSION'
}

stdout | src/tests/libs/widgets-loader.test.ts > Test mini-widgets exist
Starting enum_to_files_checker...
Importing: @/components/mini-widgets/ArmerButton.vue at 0 ms
Importing: @/components/mini-widgets/BaseCommIndicator.vue at 0 ms
Importing: @/components/mini-widgets/BatteryIndicator.vue at 0 ms
Importing: @/components/mini-widgets/ChangeAltitudeCommander.vue at 0 ms
Importing: @/components/mini-widgets/DepthIndicator.vue at 0 ms
Importing: @/components/mini-widgets/RelativeAltitudeIndicator.vue at 0 ms
Importing: @/components/mini-widgets/TakeoffLandCommander.vue at 0 ms
Importing: @/components/mini-widgets/VeryGenericIndicator.vue at 0 ms
Importing: @/components/mini-widgets/JoystickCommIndicator.vue at 0 ms
Importing: @/components/mini-widgets/MiniVideoRecorder.vue at 0 ms
Importing: @/components/mini-widgets/ModeSelector.vue at 0 ms
Importing: @/components/mini-widgets/SatelliteIndicator.vue at 0 ms
Importing: @/components/mini-widgets/ViewSelector.vue at 0 ms

stderr | src/tests/libs/widgets-loader.test.ts > Test mini-widgets exist
Failed to import: @/components/mini-widgets/JoystickCommIndicator.vue at 127 ms Error: This browser does not support gamepad API.
    at new a (/home/chris/repos/cockpit/node_modules/gamepad.js/gamepad.js:1:13751)
    at <instance_members_initializer> (/home/chris/repos/cockpit/src/libs/joystick/manager.ts:75:21)
    at new JoystickManager (/home/chris/repos/cockpit/src/libs/joystick/manager.ts:78:14)
    at <static_initializer> (/home/chris/repos/cockpit/src/libs/joystick/manager.ts:72:21)
    at /home/chris/repos/cockpit/src/libs/joystick/manager.ts:70:3
    at async VitestRunner.directRequest (file:///home/chris/repos/cockpit/node_modules/vitest/dist/chunk-vite-node-client.115caed2.mjs:188:5)
    at async VitestRunner.cachedRequest (file:///home/chris/repos/cockpit/node_modules/vitest/dist/chunk-vite-node-client.115caed2.mjs:88:12)
    at async _VitestMocker.request (file:///home/chris/repos/cockpit/node_modules/vitest/dist/chunk-vite-node-client.115caed2.mjs:110:21)
    at async /home/chris/repos/cockpit/src/components/mini-widgets/JoystickCommIndicator.vue:5:31
    at async VitestRunner.directRequest (file:///home/chris/repos/cockpit/node_modules/vitest/dist/chunk-vite-node-client.115caed2.mjs:188:5)

@rafaellehmkuhl rafaellehmkuhl marked this pull request as ready for review May 16, 2024 11:32
@rafaellehmkuhl rafaellehmkuhl marked this pull request as draft May 16, 2024 11:34
@rafaellehmkuhl
Copy link
Member Author

I've tried to debug why the tests are failing, but not being very familiar with ts, bun or vitest for that matter, I essentially just ended up setting a higher timeout, and printing a bunch of stuff. Unsure if its useful, or if its just noise.

The strange part is that none of those things were modified...

BTW have you been able to use the PR?

@goasChris
Copy link
Contributor

goasChris commented May 16, 2024

I unfortunately have not been able to test it, cus the only way I know how to fairly easily get the extension input one of our bots is to rely on CI (which won't build heh)

@rafaellehmkuhl rafaellehmkuhl force-pushed the auto-sync-cockpit-settings branch 4 times, most recently from 2bd32a0 to 77ae20a Compare June 10, 2024 16:36
@rafaellehmkuhl rafaellehmkuhl force-pushed the auto-sync-cockpit-settings branch 3 times, most recently from a309deb to 374ba77 Compare June 20, 2024 17:09
@patrickelectric patrickelectric self-requested a review June 21, 2024 12:17
@rafaellehmkuhl rafaellehmkuhl force-pushed the auto-sync-cockpit-settings branch 4 times, most recently from 351e730 to 781cc84 Compare June 26, 2024 18:48
@rafaellehmkuhl rafaellehmkuhl force-pushed the auto-sync-cockpit-settings branch from 781cc84 to b9c64ce Compare June 26, 2024 18:56
@rafaellehmkuhl rafaellehmkuhl marked this pull request as ready for review June 26, 2024 18:56
@rafaellehmkuhl rafaellehmkuhl force-pushed the auto-sync-cockpit-settings branch from b9c64ce to 7c613da Compare June 26, 2024 18:58
@rafaellehmkuhl
Copy link
Member Author

rafaellehmkuhl commented Jun 26, 2024

@ArturoManzoli @patrickelectric there's some strange CI problem happening that I'm investigating, but the PR is already done and ready for review.

Fixed.

@goasChris
Copy link
Contributor

@rafaellehmkuhl You are the best! Thank you for all the good work. I have to admit I am extremely curious how you fixed CI, since I failed to do so myself.

@rafaellehmkuhl
Copy link
Member Author

@rafaellehmkuhl You are the best! Thank you for all the good work. I have to admit I am extremely curious how you fixed CI, since I failed to do so myself.

I actually did nothing 😂

I wrote the comment before the CI finished running and afterwards realized it was fixed by itself.

Probably a bug on some dynamically versioned package.

Comment on lines 72 to 73
{ text: 'Use the value from BlueOS', action: () => preferBlueOs() },
{ text: "Keep Cockpit's value", action: () => preferCockpit() },
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
{ text: 'Use the value from BlueOS', action: () => preferBlueOs() },
{ text: "Keep Cockpit's value", action: () => preferCockpit() },
{ text: 'Use the value from BlueOS', action: preferBlueOs },
{ text: "Keep Cockpit's value", action: preferCockpit },

This should work, right ?

The `useBlueOsStorage` composable will keep a setting in sync between local storage and BlueOS.

The initial value will be the one stored on BlueOS. If we fail to get the value from BlueOS on the first seconds after boot, we will ask the user if they prefer to use the value stored locally or the value stored on BlueOS.

Once everything is in sync, if the local value changes, it will update the value on BlueOS.

In resume, the initial source of truth is BlueOS, and once everything is in sync, the source of truth is the local value.
This can be used to check if the path was not set, and should then be set for the first time.
This is now done automatically by the settings syncer.
This prevents bloat of the user's storage as well as problematic behaviors when the user changes devices.
Prevents updates on one part of the code that brakes the other that is not connected to it.
We were using it to check if the widget was ever mounted, so it already satisfies the requirements. Updating it on every mount was causing the profile to change all the time, which makes syncing dificult.
@rafaellehmkuhl rafaellehmkuhl force-pushed the auto-sync-cockpit-settings branch from 7c613da to 1aedae6 Compare June 27, 2024 19:59
@patrickelectric patrickelectric merged commit 78365a5 into bluerobotics:master Jun 27, 2024
8 checks passed
@rafaellehmkuhl rafaellehmkuhl deleted the auto-sync-cockpit-settings branch June 27, 2024 20:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs-needed Change needs to be documented
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Cockpit configurations get lost if the URL changes (like when reinstalling the BlueOS extension)
3 participants