RuWeather App

Application with accurate weather for residents of Russia and other countries.
Current weather, hourly, for 10 days (with schedule).
Works in the background. Writes to a file for use in dials or other applications.

App features

Dashboard icon

Servers (RU, COM)

Accurate weather service for RU users, and COM version for the rest of the world
* Ru server return Cityname in the Russian
* Com -- in English

Magic icon

Style, design, presentation

Display of information is presented in 2 pages:
First - main - current weather and weather for 24 hours
Second - weather forecast for 10 days with smooth schedule of day and night temperature

Radar icon

Coordinate acquisition

First (phone) -- via settings in the Zepp app (there is a list of main cities, you can set the coordinates manually or get them from the phone's GPS)

Second (watch) -- coordinates are taken from the system value of the city and the coordinates used by the Zepp weather system

Mouse icon

Update time

When the service is enabled (background service - periodic or constant), the update time is as follows:
- weather 10 minutes
- forecast 30 minutes
*You can also refresh manually by clicking on “last refresh time” at the top of the screen (no more than once per minute)

Watchface integration

The application collects and stores data in 2 files (weather.json and forecast.json)
You can see examples of the contents of these files below:

weather.json

Plus icon
{
    "temperature": 6,
    "temperatureFeels": 1,
    "temperatureMax": 10,
    "temperatureMin": 1,
    "weatherDescription": "OVERCAST",
    "weatherDescriptionExtended": "В ближайшие 2 часа осадков не ожидается",
    "windSpeed": 5.7,
    "windGust": 11.7,
    "windDirection": 310,
    "windTitle": "NW",
    "chanceOfRain": 0,
    "precType": 0,
    "humidity": 87,
    "pressure": 759,
    "uvi": 0,
    "timeZone": 180,
    "sunriseTime": "07:37",
    "sunsetTime": "15:57",
    "weatherIcon": 5,
    "weatherIconString": "ovc",
    "city": "Ройал-Боро-оф-Гринвич, Лондон",
    "lat": "51.5055",
    "lon": "0.0883",
    "weatherTime": 1732716229533,
    "weatherTimeStr": "2024-11-27 17:03",
    "hourlyForecast": [{
        "hourTime": "14:00",
        "hourIcon": 5,
        "hourIconString": "ovc",
        "hourTemp": "+6"
    }, {
        "hourTime": "15:00",
        "hourIcon": 5,
        "hourIconString": "ovc",
        "hourTemp": "+6"
    }, {
        "hourTime": "15:57",
        "hourIcon": 26,
        "hourIconString": "fct_sn_dwn",
        "hourTemp": "Sunset"
    }, {
        "hourTime": "16:00",
        "hourIcon": 5,
        "hourIconString": "ovc",
        "hourTemp": "+6"
    }, {
        "hourTime": "17:00",
        "hourIcon": 27,
        "hourIconString": "bkn_n",
        "hourTemp": "+6"
    }, {
        "hourTime": "18:00",
        "hourIcon": 29,
        "hourIconString": "skc_n",
        "hourTemp": "+5"
    }, {
        "hourTime": "19:00",
        "hourIcon": 29,
        "hourIconString": "skc_n",
        "hourTemp": "+4"
    }, {
        "hourTime": "20:00",
        "hourIcon": 29,
        "hourIconString": "skc_n",
        "hourTemp": "+4"
    }, {
        "hourTime": "21:00",
        "hourIcon": 29,
        "hourIconString": "skc_n",
        "hourTemp": "+4"
    }, {
        "hourTime": "22:00",
        "hourIcon": 29,
        "hourIconString": "skc_n",
        "hourTemp": "+3"
    }, {
        "hourTime": "23:00",
        "hourIcon": 29,
        "hourIconString": "skc_n",
        "hourTemp": "+3"
    }, {
        "hourTime": "00:00",
        "hourIcon": 29,
        "hourIconString": "skc_n",
        "hourTemp": "+2"
    }, {
        "hourTime": "01:00",
        "hourIcon": 27,
        "hourIconString": "bkn_n",
        "hourTemp": "+2"
    }, {
        "hourTime": "02:00",
        "hourIcon": 27,
        "hourIconString": "bkn_n",
        "hourTemp": "+2"
    }, {
        "hourTime": "03:00",
        "hourIcon": 27,
        "hourIconString": "bkn_n",
        "hourTemp": "+1"
    }, {
        "hourTime": "04:00",
        "hourIcon": 27,
        "hourIconString": "bkn_n",
        "hourTemp": "+1"
    }, {
        "hourTime": "05:00",
        "hourIcon": 27,
        "hourIconString": "bkn_n",
        "hourTemp": "+1"
    }, {
        "hourTime": "06:00",
        "hourIcon": 5,
        "hourIconString": "ovc",
        "hourTemp": "0"
    }, {
        "hourTime": "07:00",
        "hourIcon": 5,
        "hourIconString": "ovc",
        "hourTemp": "0"
    }, {
        "hourTime": "07:38",
        "hourIcon": 26,
        "hourIconString": "fct_sn_rs",
        "hourTemp": "Sunrise"
    }, {
        "hourTime": "08:00",
        "hourIcon": 5,
        "hourIconString": "ovc",
        "hourTemp": "0"
    }, {
        "hourTime": "09:00",
        "hourIcon": 1,
        "hourIconString": "bkn_d",
        "hourTemp": "0"
    }, {
        "hourTime": "10:00",
        "hourIcon": 1,
        "hourIconString": "bkn_d",
        "hourTemp": "+2"
    }, {
        "hourTime": "11:00",
        "hourIcon": 1,
        "hourIconString": "bkn_d",
        "hourTemp": "+4"
    }, {
        "hourTime": "12:00",
        "hourIcon": 4,
        "hourIconString": "skc_d",
        "hourTemp": "+5"
    }, {
        "hourTime": "13:00",
        "hourIcon": 4,
        "hourIconString": "skc_d",
        "hourTemp": "+6"
    }, {
        "hourTime": "14:00",
        "hourIcon": 4,
        "hourIconString": "skc_d",
        "hourTemp": "+6"
    }, {
        "hourTime": "15:00",
        "hourIcon": 4,
        "hourIconString": "skc_d",
        "hourTemp": "+6"
    }, {
        "hourTime": "15:56",
        "hourIcon": 26,
        "hourIconString": "fct_sn_dwn",
        "hourTemp": "Sunset"
    }, {
        "hourTime": "16:00",
        "hourIcon": 29,
        "hourIconString": "skc_n",
        "hourTemp": "+4"
    }, {
        "hourTime": "17:00",
        "hourIcon": 29,
        "hourIconString": "skc_n",
        "hourTemp": "+3"
    }, {
        "hourTime": "18:00",
        "hourIcon": 29,
        "hourIconString": "skc_n",
        "hourTemp": "+3"
    }, {
        "hourTime": "19:00",
        "hourIcon": 27,
        "hourIconString": "bkn_n",
        "hourTemp": "+2"
    }, {
        "hourTime": "20:00",
        "hourIcon": 27,
        "hourIconString": "bkn_n",
        "hourTemp": "+2"
    }, {
        "hourTime": "21:00",
        "hourIcon": 5,
        "hourIconString": "ovc",
        "hourTemp": "+2"
    }, {
        "hourTime": "22:00",
        "hourIcon": 5,
        "hourIconString": "ovc",
        "hourTemp": "+2"
    }, {
        "hourTime": "23:00",
        "hourIcon": 5,
        "hourIconString": "ovc",
        "hourTemp": "+3"
    }]
}

forecast.json

Plus icon
{
    "city": "Ройал-Боро-оф-Гринвич, Лондон",
    "timeZone": -180,
    "weatherTime": 1732716229474,
    "weatherTimeStr": "2024-11-27 17:03",
    "forecast": [{
        "weatherDescriptionExtended": "RAIN",
        "weatherIcon": 2,
        "weatherIconString": "bkn_ra_d",
        "temperatureFeels": 0,
        "temperatureMax": 10,
        "temperatureMin": 1,
        "humidity": 86,
        "pressure": 758,
        "windSpeed": 6.4,
        "windDirection": 315,
        "windTitle": "NW",
        "date": "27 ноября",
        "dayOfWeek": "среда"
    }, {
        "weatherDescriptionExtended": "PARTLY_CLOUDY",
        "weatherIcon": 1,
        "weatherIconString": "bkn_d",
        "temperatureFeels": 0,
        "temperatureMax": 6,
        "temperatureMin": 2,
        "humidity": 86,
        "pressure": 770,
        "windSpeed": 2.3,
        "windDirection": 90,
        "windTitle": "E",
        "date": "28 ноября",
        "dayOfWeek": "четверг"
    }, {
        "weatherDescriptionExtended": "PARTLY_CLOUDY",
        "weatherIcon": 1,
        "weatherIconString": "bkn_d",
        "temperatureFeels": 2,
        "temperatureMax": 10,
        "temperatureMin": 7,
        "humidity": 78,
        "pressure": 768,
        "windSpeed": 5.2,
        "windDirection": 135,
        "windTitle": "SE",
        "date": "29 ноября",
        "dayOfWeek": "пятница"
    }, {
        "weatherDescriptionExtended": "OVERCAST",
        "weatherIcon": 5,
        "weatherIconString": "ovc",
        "temperatureFeels": 8,
        "temperatureMax": 13,
        "temperatureMin": 11,
        "humidity": 87,
        "pressure": 766,
        "windSpeed": 3.7,
        "windDirection": 180,
        "windTitle": "S",
        "date": "30 ноября",
        "dayOfWeek": "суббота"
    }, {
        "weatherDescriptionExtended": "LIGHT_RAIN",
        "weatherIcon": 2,
        "weatherIconString": "ovc_-ra",
        "temperatureFeels": 7,
        "temperatureMax": 12,
        "temperatureMin": 10,
        "humidity": 84,
        "pressure": 759,
        "windSpeed": 6.3,
        "windDirection": 180,
        "windTitle": "S",
        "date": "1 декабря",
        "dayOfWeek": "воскресенье"
    }, {
        "weatherDescriptionExtended": "RAIN",
        "weatherIcon": 2,
        "weatherIconString": "bkn_ra_d",
        "temperatureFeels": 5,
        "temperatureMax": 10,
        "temperatureMin": 6,
        "humidity": 82,
        "pressure": 759,
        "windSpeed": 5.1,
        "windDirection": 270,
        "windTitle": "W",
        "date": "2 декабря",
        "dayOfWeek": "понедельник"
    }, {
        "weatherDescriptionExtended": "LIGHT_RAIN",
        "weatherIcon": 2,
        "weatherIconString": "bkn_-ra_d",
        "temperatureFeels": 2,
        "temperatureMax": 7,
        "temperatureMin": 4,
        "humidity": 85,
        "pressure": 764,
        "windSpeed": 4.1,
        "windDirection": 315,
        "windTitle": "NW",
        "date": "3 декабря",
        "dayOfWeek": "вторник"
    }, {
        "weatherDescriptionExtended": "RAIN",
        "weatherIcon": 2,
        "weatherIconString": "bkn_ra_d",
        "temperatureFeels": 1,
        "temperatureMax": 7,
        "temperatureMin": 6,
        "humidity": 83,
        "pressure": 762,
        "windSpeed": 4.6,
        "windDirection": 225,
        "windTitle": "SW",
        "date": "4 декабря",
        "dayOfWeek": "среда"
    }, {
        "weatherDescriptionExtended": "RAIN",
        "weatherIcon": 2,
        "weatherIconString": "ovc_ra",
        "temperatureFeels": 3,
        "temperatureMax": 10,
        "temperatureMin": 6,
        "humidity": 84,
        "pressure": 760,
        "windSpeed": 6,
        "windDirection": 180,
        "windTitle": "S",
        "date": "5 декабря",
        "dayOfWeek": "четверг"
    }, {
        "weatherDescriptionExtended": "LIGHT_RAIN",
        "weatherIcon": 2,
        "weatherIconString": "bkn_-ra_d",
        "temperatureFeels": 1,
        "temperatureMax": 9,
        "temperatureMin": 6,
        "humidity": 82,
        "pressure": 759,
        "windSpeed": 7.2,
        "windDirection": 225,
        "windTitle": "SW",
        "date": "6 декабря",
        "dayOfWeek": "пятница"
    }]
}

Json code example for implement get data from RuWeather

Plus icon

Security is our top priority. Torch uses end-to-end encryption, secure data centres, and regular security audits to ensure your data is protected at all times. We also offer role-based access control to manage permissions within your team.

//#region Loading data from RuWeather

        //arrayBufferToCyrillic thx @SashaCX75
        function arrayBufferToCyrillic(buffer) {
          let result = '';
          const bytes = new Uint8Array(buffer);

          let i = 0;
          while (i < bytes.length) {
            let byte1 = bytes[i++];

            // Обработка 1-байтовых символов (ASCII)
            if (byte1 < 0x80) {
              result += String.fromCharCode(byte1);
            }
            // Обработка 2-байтовых символов (UTF-8 кодировка для кириллицы)
            else if (byte1 >= 0xC0 && byte1 < 0xE0) {
              let byte2 = bytes[i++];
              let charCode = ((byte1 & 0x1F) << 6) | (byte2 & 0x3F);
              result += String.fromCharCode(charCode);
            }
            // Обработка 3-байтовых символов (например, для UTF-8)
            else if (byte1 >= 0xE0 && byte1 < 0xF0) {
              let byte2 = bytes[i++];
              let byte3 = bytes[i++];
              let charCode = ((byte1 & 0x0F) << 12) | ((byte2 & 0x3F) << 6) | (byte3 & 0x3F);
              result += String.fromCharCode(charCode);
            }
          }

          return result;
        }
        function read_weather_data_str() {
          console.log('start read weather data');
          let str_result = "";
          try {
            const file_name = "weather.json"; //указываем путь к файлу данных weather.json или forecast.json
            const mini_app_id = 1066654; //указываем ID приложения

            const [fs_stat, err] = hmFS.stat(file_name, {
              appid: mini_app_id
            });
            if (err == 0) {
              //console.log('--->size_alt:', fs_stat.size);

              const fh = hmFS.open(file_name, hmFS.O_RDONLY, {
                appid: mini_app_id
              })

              const len = fs_stat.size;
              let array_buffer = new ArrayBuffer(len);
              hmFS.read(fh, array_buffer, 0, len);
              hmFS.close(fh);
              str_result = arrayBufferToCyrillic(array_buffer);
              //console.log(`str_result = ${str_result}`);
              return str_result;

            } else {
              console.log('err:', err)
            }

          } catch (error) {
            console.log('error:', error);
            console.log("FAIL: No access to hmFS.");
          }
          return "";
        }
        function getDataValue(str = "") {
          let value = 0;
          try {
            const data = JSON.parse(str); //получаем массив данных
            //присваиваем виджетам их значения
            normal_temperature_current_text_font.setProperty(hmUI.prop.TEXT, data.temperature + '°') //присваиваем виджетам их значения
            idle_temperature_current_text_font.setProperty(hmUI.prop.TEXT, data.temperature + '°')

            wCurTemp.setProperty(hmUI.prop.TEXT, data.temperature + '°(' + data.temperatureFeels + '°)')
            wCity.setProperty(hmUI.prop.TEXT, data.city)
            wUpdate.setProperty(hmUI.prop.TEXT, data.weatherTimeStr)

          } catch (error) {
            console.log('error:', error);
          }

        }

        function updateWeatherApp() {
          console.log('update_weather_from_app')
          let read_str = read_weather_data_str();
          getDataValue(read_str);
        }
        //#endregion

Sample code for update weather data

Plus icon
        let timeSensor = ''
        if (!timeSensor) timeSensor = hmSensor.createSensor(hmSensor.id.TIME);
        
        const deviceInfo = hmSetting.getDeviceInfo();
        timeSensor.addEventListener(timeSensor.event.MINUTEEND, function () {

          if (screenType == hmSetting.screen_type.WATCHFACE) {
            // Обновляем только на основном экране каждые 10 минут
            if (timeSensor.minute % 10 === 0) {
              updateWeatherApp();
            }
          }

          if (screenType == hmSetting.screen_type.AOD) {
            // Обновляем только в режиме AOD каждые 10 минут
            if (timeSensor.minute % 10 === 0) {
              updateWeatherApp();
            }
          }

        });

Weather icons tags

Plus icon
1skc_d	"Clear day"
2skc_n	"Clear night"
3fg_d	"Fog day"
4fg_n	"Fog night"
5bkn_d	"Partly cloudy day"
6bkn_n	"Partly cloudy night"
7bkn_-ra_d	"Light rain day"
8bkn_-ra_n	"Light rain night"
9bkn_-sn_d	"Light snow day"
10bkn_-sn_n	"Light snow night"
11bkn_ra_d	"Rain day"
12bkn_ra_n	"Rain night"
13bkn_sn_d	"Snow day"
14bkn_sn_n	"Snow night"
15bkn_+ra_d	"Heavy rain day"
16bkn_+ra_n	"Heavy rain night"
17bkn_+sn_d	"Heavy snow day"
18bkn_+sn_n	"Heavy snow night"
19ovc_ts	"Thunderstorm"
20ovc_ts_ra	"Thunderstorm with rain"
21ovc_ts_ha	"Thunderstorm with hail"
22ovc	"Cloudy"
23ovc_-ra	"Cloudy with light rain"
24ovc_-sn	"Cloudy with light snow"
25ovc_ra	"Cloudy with rain"
26ovc_sn	"Cloudy with snow"
27ovc_+ra	"Cloudy with heavy rain"
28ovc_+sn	"Cloudy with heavy snow"
29ovc_ra_sn	"Cloudy with sleet"
30ovc_ha	"Hail"
31-bl	"Snowstorm"
32bl	"Heavy snowstorm"
33dst	"Dust"
34du_st	"Dust strom"
35smog	"Smog"
36strm	"Storm"
37vlka	"olcanic eruption"

Watchface intergration

Plus icon

Integrated code to display: sunset, sunrise, current temperature and weather states in a separate window.
Long tap on the weather opens RuWeather application

Source code this watchface for GTR4, Balance, T-Rex 3 bellow

UltraDialThree RuWeather watchface