Weather widget in gnome-shell

danigm's picture

These days I'm playing arround gnome shell and gjs code. Yesterday night I started to implement a weather widget to have in gnome-shell status bar, and that isn't as easy as I thought but today I've something.

gshell weather

I tried to use libgweather to get the weather, but I can't get it working with gjs. I spent some hours yesterday triying it, going to sleep late at night, but I can't get it working.

So today I've taken the easy way. Look for a web service that provides weather information and parse that information.

I've taken the yahoo weather rss and I've parsed the output using regular expresions (ok, I know that is odd, but use gmarkup with gjs isn't easy), and voilá, I get a gnome-shell weather widget. It isn't the best, but is something.

To get it working I add the file weather.js to /usr/share/gnome-shell/js/ui/status and then modify the file /usr/share/gnome-shell/js/ui/panel.js adding weather tray icon:

const STANDARD_TRAY_ICON_ORDER = ['a11y', 'display', 'keyboard', 'volume', 'bluetooth', 'network', 'battery', 'weather'];
'a11y': imports.ui.status.accessibility.ATIndicator,
'volume': imports.ui.status.volume.Indicator,
'battery': imports.ui.status.power.Indicator,
'keyboard': imports.ui.status.keyboard.XKBIndicator

The city code to get the weather is hardcoded in weather.js, line 95: "zone = 'SPXX0220';". If you want to use that hack, you should change the file, because there's not ui to change the zone, wheather settings does nothing :P

weather.js4.18 KB


amuchamu's picture

¡Buenas! Aunque la entrada está en inglés espero que no te importe que te escriba en español.

Estaba mirando cómo hacer una extensión para controlar la frecuencia del procesador y tu código me va a venir muy bien, ya que debo de ser un zoquete y no encuentro documentación por ninguna parte.

Si sigues mejorándolo, podrías hacerlo como extensión independiente y así no tener que tocar ningún archivo de fuera del ~.

Básicamente es hacer una extensión con el código de tu weather.js en medio y 4 cosillas más:

const Panel = imports.ui.panel;


function main() {
Panel.STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION['weather'] = this.Indicator;

Así lo tengo yo ahora mismo y va bastante bien.

Un saludo

danigm's picture

No importa que comentes en español :D

Estuve comentando por el canal irc de gnome-shell el widget este, y me estuvieron comentando que estaría bien hacerlo como extensión y meterlo en el repositorio de gnome-shell-extensions, pero me da pereza ponerme a hacerlo.

Así que si tienes el código hecho como extensión y quieres ver si es posible meterlo en el repositorio oficial de extensiones podemos preguntar por el irc y preguntar a ver si hay interés.

SnocK's picture

queda muy bien xd , no se puede traducir en español los mensajes ?

amuchamu's picture

A mí más que pereza es que de javascript no tengo mucha idea, y al no encontrar la documentación me cuesta bastante hacer cualquier extensión.

Lo que has hecho lo he metido dentro del código que he puesto y sólo he llegado a poner un tooltip de modo que al poner el ratón encima del icono me muestre la temperatura actual, pero a más por ahora no llego :P

Miguelroboso's picture

Thanks! Even though I suspect you are from Cordoba, I hope you won't be offended if I write in English :.
I added your weather "applet" to my shell, it's gorgeous. I only have to understand why the numbers in parenthesis are still in fahrenheit for me...(or what they actually mean)

danigm's picture

The numbers in parenthesis aren't the fahrenheit, its are the number of image to show using this url, if you change the last number you have the icon showed by yahoo.

There's a switch in weather.js that set the icon looking that number.

For fahrenheit you can change this url:

uri = ''+zone+'&u=c';


uri = ''+zone+'&u=f';

Miguelroboso's picture

Oh I see.
As for farhenheit I was already good (I use Celsius, darn imperial system!).
However, I have both the numbers and the image now, I will try to fiddle with the js to fix it (screenshot attached )

Eduaro's picture

Seguí las instrucciones y no tuve problemas para instalarlo en mi laptop con Fedora 15. Sólo me preguntaba si era necesario conservar "Weather settings", si en realidad no tienen una función. Gracias y no dejes de avisar cambios en el script. Saludos

jeff's picture

I made the additions to weather.js to make it an extension after an update replaced panel.js.
Make a new directory in "~/.local/share/gnome-shell/extensions/". I used "Weather_Widget@amd64". In that directory create 2 files, the weather.js with the following lines added. The weather.js file must be renamed to extension.js. The other file metadata.json's content is given at the end of my post. Alt-F2 then "r" to restart the shell. This should survive updates.


const Gettext = imports.gettext.domain('gnome-shell');
const _ = Gettext.gettext;

const Panel = imports.ui.panel;

function main () {
Panel.STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION ['weather'] = this.Indicator;

function Indicator() {
this._init.apply(this, arguments);


{"shell-version": ["3.0.1"], "uuid": "Weather_Widget@amd64", "name": "Weather Widget", "description": "Display a weather info icon"}

arzanulhaq's picture

I use your extension on my gnome-shell.
It's works.
Thx a lot.

BTW, I add \u00B0 before 'C ' to get degree symbol

Monigote's picture

Ya que usamos javascript: ¿No sería más facil utilizar JSON para leer los datos del tiempo?
Se puede ver en:
con los mismos parametros!!!

Monigote's picture

Mejor usar JSON:

_callback: function(s, sm, ind) {
var msg = {};
eval("msg = " +"\n"));
var condition = msg["condition"];
var forecasts = msg["forecast"];
var city = msg["location"]["city"];

output = ind._outputTomorrow;
if (condition) {
cloud = condition["code"];
text = _(condition["text"]);
temp = condition["temperature"];

ind._outputTitle.label.set_text(_("Tiempo") + " " + _("en") + " " + city);
ind._outputToday.label.set_text(text + ' ' + temp + '\u00B0C ');
gicon = Shell.util_icon_from_string(ind.get_icon(cloud));
ind._outputToday._icon.gicon = gicon;

if (forecasts) {
var total = forecasts.length;
for(var i = 0; i < total; i++){
var forecast = forecasts[i];
if (forecast) {
cloud = (forecast["code"])? forecast["code"] : 28; // (default 28 "weather-few-clouds": NO CODES!!!)
text = _(forecast["condition"]);
day = _(forecast["day"]);
temph = forecast["high_temperature"];
templ = forecast["low_temperature"];

output.label.set_text(day + ': ' + text + ' ' + templ + '\u00B0C-' + temph + '\u00B0C ');
gicon = Shell.util_icon_from_string(ind.get_icon(cloud));
output._icon.gicon = gicon;

output = ind._outputNext;

y en _on_update cambiar:

uri = ''+zone+'&u=c';

Vamos a ver si alguien se anima a hacer el dialogo de configuración ;)

Eder John's picture

Hey, I liked your widget.
And i was wondering if I can modify it?
Maybe translate to Portuguese, wich is my mother language. Or to implement the weather settings, or a list with the most popular citys in Brazil, maybe in the world.


danigm's picture

Thank you, you can take the code and make modification if you want. But currently there're other gnome shell weather extension that's more complete, you can find one here: