Это старая версия документа!


Эксперимент 70. Графический интерфейс метеостанции

В предыдущем эксперименте мы зарегистрировались в интернет-сервисе weatherbit.io, подключились к нему и получили данные о текущей погоде в Москве. Если заменить название города, то можно получить данные о погоде в другом городе.

Но эти данные приходят в виде удобном для программы, но не для человека. Человеку хотелось бы видеть красивую иконку погоды на дисплее, которая бы символизировала ситуацию на улице, например солнышко или облачко. Температуру нужно вывести крупным шрифтом, а влажность и скорость ветра — мелким. Многие другие данные вообще могут быть не интересны человеку. Иными словами нам нужно сделать графический пользовательский интерфейс (англ. graphical user interface, GUI)

Для отображения иконок погоды и пользовательского интерфейса их нужно загрузить во внутреннюю память микроконтроллера. Для этого нужно создать папку weather в корне файловой системы, в нее загрузим все файлы из архива.

Отображать данные мы будем на TFT дисплее, поэтому подключим его согласно схеме.

Схема эксперимента

Рисунок 1. Монтажная схема эксперимента

Программный код эксперимента

Exp70.py
  1. from machine import Pin, SPI
  2. from tft import TFT_GREEN
  3. import font
  4. import network
  5. import gc
  6. import time
  7. import socket
  8.  
  9. _init()
  10. gc.collect()
  11.  
  12. dc = Pin(4, Pin.OUT)
  13. cs = Pin(2, Pin.OUT)
  14. rst = Pin(5, Pin.OUT)
  15.  
  16.  
  17. spi = SPI(1, baudrate=40000000, polarity=0, phase=0)
  18. tft = TFT_GREEN(128, 160, spi, dc, cs, rst, rotate=0)
  19. tft.initr()
  20.  
  21.  
  22. data = {'count': 1, 'data': [{'wind_cdir_full': 'southeast', 'weather': {'code': '804', 'icon': 'r01d', 'description': 'Light rain'}, 'datetime': '2020-06-15:11', 'temp': 24.4, 'station': 'E8051', 'elev_angle': 53.53, 'app_temp': 23.8, 'state_code': '48', 'wind_dir': 137, 'last_ob_time': '2020-06-15T10:46:00', 'solar_rad': 163.2, 'sunrise': '00:43', 'slp': 1007, 'pod': 'd', 'vis': 1.5, 'pres': 992.8, 'wind_cdir': 'SE', 'wind_spd': 1.34, 'ghi': 815.91, 'ts': 1592217960, 'snow': 0, 'uv': 8.64467, 'clouds': 100, 'city_name': 'Moscow', 'precip': 2.84211, 'timezone': 'Europe/Moscow', 'country_code': 'RU', 'dni': 882.12, 'dhi': 113.84, 'sunset': '18:15', 'ob_time': '2020-06-15 10:46', 'h_angle': 20, 'dewpt': 6.2, 'aqi': 48, 'lat': 55.7522, 'rh': 31, 'lon': 37.6156}]}
  23.  
  24. wCity = data['data'][0]['city_name']
  25. wTemp = round(data['data'][0]['temp'])
  26. wTempFeels = data['data'][0]['app_temp']
  27. wHumidity = data['data'][0]['rh']
  28. wWind = data['data'][0]['wind_spd']
  29.  
  30. pod = data['data'][0]['pod']
  31.  
  32. wCode = int(data['data'][0]['weather']['code'])
  33.  
  34. if wCode <= 233:
  35. wPic = '11'
  36. elif (wCode >= 300 and wCode <= 520) or wCode == 522:
  37. wPic = '09'
  38. elif wCode in (521, 600):
  39. wPic = '10'
  40. elif wCode >= 601 and wCode <= 622:
  41. wPic = '13'
  42. elif wCode >= 623 and wCode <= 751:
  43. wPic = '50'
  44. elif wCode == 800:
  45. wPic = '01'
  46. elif wCode in (801, 802):
  47. wPic = '02'
  48. elif wCode == 803:
  49. wPic = '03'
  50. elif wCode == 804:
  51. wPic = '04'
  52.  
  53. if (wTemp > 0):
  54. wTempPic = 'tp'
  55. else:
  56. wTempPic = 'tn'
  57.  
  58. FontColor = tft.rgbcolor(33,149, 82)
  59. FontColor2 = tft.rgbcolor(8,85, 41)
  60.  
  61.  
  62. tft.clear(tft.rgbcolor(255,255, 255))
  63.  
  64.  
  65. tft.text(1,1,wCity, font.terminalfont, FontColor, 2)
  66.  
  67. tft.draw_bmp(34,16,'/weather/' + wPic + pod + '.bmp')
  68. tft.draw_bmp(5,70,'/weather/' + wTempPic + '.bmp')
  69.  
  70. tft.text(30,75, str(wTemp), font.terminalfont, FontColor, 4)
  71.  
  72. tft.text(5,120,"Feels: " + str(wTempFeels), font.terminalfont, FontColor2, 1)
  73. tft.text(5,128,"Humidity: " + str(wHumidity) + "%", font.terminalfont, FontColor2, 1)
  74. tft.text(5,136,"Wind: " + str(wWind) + "m/s", font.terminalfont, FontColor2, 1)

В этой программе мы сосредоточились на создании GUI — графического интерфейса пользователя, поэтому пока убрали из программы обращение к интернет- сервису. Вместо этого мы задали в коде типовой ответ от сервера. Эту «заглушку» и будем использовать как временный источник данных.

Первым делом извлекаем из структуры нужные нам данные. А именно: название города, текущую температуру, влажность, скорость ветра, время суток, код погоды. Разберем по порядку:

Название города записываем в переменную wCity

wCity = data['data'][0]['city_name'] 

Текущую температуру записываем в переменную wTemp

wTemp = round(data['data'][0]['temp'])

Ощущение температуры записываем в переменную wTempFeels. (например из-за ветра или влажности температура может ощущаться человеком как более низкая, чем есть на самом деле)

wTempFeels = data['data'][0]['app_temp']

Влажность в % записываем в переменную wHumidity

wHumidity = data['data'][0]['rh']

Скорость ветра в метрах в секунду записываем в переменную wWind

wWind = data['data'][0]['wind_spd']

Текущее время суток записываем в переменную pod. Если сейчас день, то в ней будет значение d, а если ночь — n. Эти данные нам понадобятся для выбора правильной иконки погоды. Например, днем мы будем отображать солнышко, а ночью луну.

pod = data['data'][0]['pod']