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

[Snap] Implement Localisation Settings #3153

Open
benfrancis opened this issue Aug 21, 2024 · 4 comments
Open

[Snap] Implement Localisation Settings #3153

benfrancis opened this issue Aug 21, 2024 · 4 comments
Labels
snap Issues relating to the snap package task
Milestone

Comments

@benfrancis
Copy link
Member

benfrancis commented Aug 21, 2024

STR:

  • In web interface navigate to Main Menu -> Settings - Localisation

Expected:

  • Country, Timezone, Language, and Temperature Units preferences displayed
  • Can change each preference by selecting an item in the dropdown

Actual:

  • Country and Timezone dropdowns are unpopulated
  • Language and Temperature dropdowns are populated but changing them doesn't seem to have any effect

From the browser console when setting Language:

Uncaught (in promise) Error: 500
    getJson api.ts:44
    promise callback*getJson api.ts:42
    getPushKey api.ts:474
    r notifications.js:23
    i thing-model.js:324
    a notifications.js:16
    promise callback*i thing-model.js:324
    a notifications.js:16
    s notifications.js:16
    s notifications.js:16
    onReady notifications.js:16
    promise callback*96710 app.js:619
    Webpack 3
api.ts:44:14

Also noticed network errors in the browser console during first time setup:

Uncaught (in promise) TypeError: NetworkError when attempting to fetch resource.

XHRPUT
http://localhost:8080/settings/localization/language
[HTTP/1.1 401 Unauthorized 1ms]

XHRGET
http://localhost:8080/settings/localization/units
[HTTP/1.1 401 Unauthorized 2ms]

Uncaught (in promise) Error: 401
    getJson http://localhost:8080/bundle/6f3f2b9653370ff453ac-app.js:8
    promise callback*getJson http://localhost:8080/bundle/6f3f2b9653370ff453ac-app.js:8
    getUnits http://localhost:8080/bundle/6f3f2b9653370ff453ac-app.js:8
    e http://localhost:8080/bundle/6f3f2b9653370ff453ac-app.js:8
    promise callback*e http://localhost:8080/bundle/6f3f2b9653370ff453ac-app.js:8
    96710 http://localhost:8080/bundle/6f3f2b9653370ff453ac-app.js:8
    n http://localhost:8080/bundle/6f3f2b9653370ff453ac-app.js:8
    <anonymous> http://localhost:8080/bundle/6f3f2b9653370ff453ac-app.js:8
    <anonymous> http://localhost:8080/bundle/6f3f2b9653370ff453ac-app.js:8
6f3f2b9653370ff453ac-app.js:8:946120

XHRGET
http://localhost:8080/settings/localization/language
[HTTP/1.1 401 Unauthorized 2ms]

On one occasion I also noticed an error in run-app.log after creating a username and password during first time setup:

2024-08-20 19:00:20.691 ERROR : Failed to set localization.language to 'en-GB'

@benfrancis benfrancis added bug snap Issues relating to the snap package labels Aug 21, 2024
@benfrancis benfrancis added this to the 2.0 milestone Aug 21, 2024
@benfrancis benfrancis changed the title [Snap] Localisation settings don't work [Snap] Implement Localisation settings Aug 22, 2024
@benfrancis benfrancis added task and removed bug labels Aug 22, 2024
@benfrancis benfrancis changed the title [Snap] Implement Localisation settings [Snap] Implement localisation settings Aug 22, 2024
@benfrancis benfrancis changed the title [Snap] Implement localisation settings [Snap] Implement Localisation Settings Aug 22, 2024
@dilyn-corner
Copy link
Contributor

Are there any errors or messages in the system log when this is attempted?

My initial guess is you need the locale-control interface.

You'll probably need to consider what locales to include in your snap(s) as well, though the core22 base snap does ship a usr/share/locale.

It may be worth investigating snaps like the gnome-**-2X04 snaps provide and how the gnome extension works. It may provide some insights into how you may need to craft your graphics setup to make everything work smoothly.

@benfrancis
Copy link
Member Author

@dilyn-corner wrote:

It may be worth investigating snaps like the gnome-**-2X04 snaps provide and how the gnome extension works. It may provide some insights into how you may need to craft your graphics setup to make everything work smoothly.

There is no graphics setup since WebThings Gateway is a headless application, so I'm assuming this isn't relevant?

Looking more closely at the source code of what the Raspbian back end for localisation settings does I see:

  • getValidTimezones() - This reads from /usr/share/zoneinfo/zone.tab
  • getTimezone() - This reads from /etc/timezone
  • setTimezone() - This calls sudo raspi-config nonint do_change_timezone {zone}
  • getValidWirelessCountries() - This reads from /usr/share/zoneinfo/iso3166.tab
  • getWirelessCountry() - This callse sudo raspi-config noint get_wifi_country and reads from /usr/share/zoneinfo/iso3166.tab
  • setWirelessCountry() - This reads from /usr/share/zoneinfo/iso3166.tab and calls raspi-config nonint do_wifi_country {data}. I'm guessing this may edit wpa_supplicant.conf on the back end but I don't know for sure.

The language and unit settings just seem to be stored internally to the application and are used for the Fluent localisation on the front end:

  • Settings.getSetting('localization.language')
  • Settings.setSetting('localization.language', {language})
  • Settings.getSetting('localization.units.temperature')
  • Settings.setSetting(localization.units.{key}, value)

@dilyn-corner / @ogra1 What would be really useful to know is how you would implement all of the functions in that first list on Ubuntu Core and what interfaces would be required to do that. It looks like it really boils down to listing, getting and setting timezones and listing, getting and setting wireless country.

I see there is a timezone-control interface which allows setting the system timezone via systemd-timedated "independently of config core". Is this what I should use to list, get and set timezones and if so how?

I assume the reason for setting the Wi-Fi country is so that the correct (legally allowed) frequency bands are used for the country you are in. How would you do this on Ubuntu Core? Can it be set via NetworkManager, or do I need to use another tool? And how do I get a list of valid country codes?

Thanks

@ogra1
Copy link
Contributor

ogra1 commented Oct 23, 2024

This is another place where the code misses proper abstraction to be more portable:

Looking more closely at the source code of what the Raspbian back end for localisation settings does I see:

* [`getValidTimezones()`](https://github.com/WebThingsIO/gateway/blob/master/src/platforms/linux-raspbian.ts#L805)  - This reads from `/usr/share/zoneinfo/zone.tab`

Instead of reading the file directly it should use timedatectl list-timezones

* [`getTimezone()`](https://github.com/WebThingsIO/gateway/blob/master/src/platforms/linux-raspbian.ts#L832) - This reads from `/etc/timezone`

Same thing timedatectl show| grep ^Timezone ...

* [`setTimezone()`](https://github.com/WebThingsIO/gateway/blob/master/src/platforms/linux-raspbian.ts#L854) - This calls `sudo raspi-config nonint do_change_timezone {zone}`

timedatectl set-timezone

* [`getValidWirelessCountries()`](https://github.com/WebThingsIO/gateway/blob/master/src/platforms/linux-raspbian.ts#L869) - This reads from `/usr/share/zoneinfo/iso3166.tab`

iw reg get

* [`getWirelessCountry()`](https://github.com/WebThingsIO/gateway/blob/master/src/platforms/linux-raspbian.ts#L896) - This callse `sudo raspi-config noint get_wifi_country` and reads from `/usr/share/zoneinfo/iso3166.tab`

Not sure what the difference is to the above function here ...

* [`setWirelessCountry()`](https://github.com/WebThingsIO/gateway/blob/master/src/platforms/linux-raspbian.ts#L938) - This reads from `/usr/share/zoneinfo/iso3166.tab` and calls `raspi-config nonint do_wifi_country {data}`. I'm guessing this may edit `wpa_supplicant.conf` on the back end but I don't know for sure.

iw reg set ...

All in all the code would really benefit from using the above standard tools, even without using it in a snap it would enable you to run seamlessly on fedora, arch, you name it ...

The language and unit settings just seem to be stored internally to the application and are used for the Fluent localisation on the front end:

* `Settings.getSetting('localization.language')`

* `Settings.setSetting('localization.language', {language})`

* `Settings.getSetting('localization.units.temperature')`

* `Settings.setSetting(`localization.units.{key}`, value)`

For all of these you likely need a proper locale-gen call ad ship the locale files your app wants to use which the steps that @dilyn-corner described above should provide.

@benfrancis
Copy link
Member Author

This is another place where the code misses proper abstraction to be more portable

Just to be clear, the LinuxRaspbianPlatform class was always intended to be very specific to Raspbian, running on a Raspberry Pi. That's why there's an abstract BasePlatform class and then subclasses for different distributions.

  • BasePlatform
    • DarwinPlatform
    • LinuxArchPlatform
    • LinuxDebianPlatform
    • LinuxRaspbianPlatform
    • LinuxUbuntuPlatform

Could it have been written in a more portable way? Yes, probably. But that wasn't even a consideration when some of this code was first written as a Raspberry Pi-only experiment as far back as 2017!

I'm grateful for your advice on how to implement this functionality in a more portable way, which will also work inside snap confinement. I'll work my way through your suggestions, thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
snap Issues relating to the snap package task
Projects
Status: Sprint Backlog
Development

No branches or pull requests

3 participants