.. note:: こんにちは、SunFounderのRaspberry Pi & Arduino & ESP32愛好家コミュニティへようこそ!Facebook上でRaspberry Pi、Arduino、ESP32についてもっと深く掘り下げ、他の愛好家と交流しましょう。 **参加する理由は?** - **エキスパートサポート**:コミュニティやチームの助けを借りて、販売後の問題や技術的な課題を解決します。 - **学び&共有**:ヒントやチュートリアルを交換してスキルを向上させましょう。 - **独占的なプレビュー**:新製品の発表や先行プレビューに早期アクセスしましょう。 - **特別割引**:最新製品の独占割引をお楽しみください。 - **祭りのプロモーションとギフト**:ギフトや祝日のプロモーションに参加しましょう。 👉 私たちと一緒に探索し、創造する準備はできていますか?[|link_sf_facebook|]をクリックして今すぐ参加しましょう! 4. @OpenWeatherMapからのリアルタイム天気情報 =============================================== このプロジェクトでは、LCDに時間と一緒に現在の天気を表示するスマートクロックを作成します。 **1. 必要なコンポーネント** このプロジェクトには以下のコンポーネントが必要です。 一式をまとめて購入するのが便利です。リンクはこちら: .. list-table:: :widths: 20 20 20 :header-rows: 1 * - 名称 - このキットに含まれるアイテム数 - リンク * - ケプラーキット - 450+ - |link_kepler_kit| 下記のリンクから個別にも購入可能です。 .. list-table:: :widths: 5 20 5 20 :header-rows: 1 * - SN - コンポーネント - 個数 - リンク * - 1 - :ref:`cpn_pico_w` - 1 - |link_picow_buy| * - 2 - Micro USBケーブル - 1 - * - 3 - :ref:`cpn_breadboard` - 1 - |link_breadboard_buy| * - 4 - :ref:`cpn_wire` - 数本 - |link_wires_buy| * - 5 - :ref:`cpn_i2c_lcd` - 1 - |link_i2clcd1602_buy| * - 6 - :ref:`cpn_lipo_charger` - 1 - * - 7 - 18650バッテリー - 1 - * - 8 - バッテリーホルダー - 1 - **2. 回路を作成する** .. warning:: Li-po充電モジュールが図の通りに接続されていることを確認してください。それ以外の場合、ショートが起きてバッテリーや回路が損傷する可能性があります。 .. image:: img/wiring/4.owm_bb.png **3. OpenWeatherのAPIキーを取得する** |link_openweather| は、OpenWeather Ltdが運営するオンラインサービスで、APIを介して全世界の天気データを提供しています。現在の天気、予報、短期予報、過去の天気データなど、地理的な位置に関係なく取得できます。 #. |link_openweather| にアクセスしてログイン/アカウントを作成します。 .. image:: img/OWM-1.png #. ナビゲーションバーからAPIページに移動します。 .. image:: img/OWM-2.png #. **現在の天気データ** を見つけて、サブスクライブをクリックします。 .. image:: img/OWM-3.png #. **現在の天気と予報コレクション** の下で、適切なサービスにサブスクライブします。このプロジェクトでは、無料プランで十分です。 .. image:: img/OWM-4.png #. **APIキー** ページからキーをコピーします。 .. image:: img/OWM-5.png #. それをRaspberry Pi Pico Wの ``secrets.py`` スクリプトにコピーします。 .. image:: img/4_openweather1.png .. note:: もしPico Wに ``do_connect.py`` および ``secrets.py`` スクリプトがない場合、 :ref:`iot_access` を参照して作成してください。 .. code-block:: python :emphasize-lines: 5 secrets = { 'ssid': 'SSID', 'password': 'PASSWORD', 'webhooks_key':'WEBHOOKS_API_KEY', 'openweather_api_key':'OPENWEATHERMAP_API_KEY' } **4. スクリプトを実行する** #. ``kepler-kit-main/iot`` パスの下にある ``4_weather.py`` ファイルを開き、 **現在のスクリプトを実行** ボタンをクリックするか、F5キーを押して実行します。 .. image:: img/4_openweather2.png #. スクリプトが実行された後、I2C LCD1602にあなたの地域の時間と天気情報が表示されます。 .. note:: コードが実行中で画面が真っ白な場合は、モジュールの背面にあるポテンショメータを回してコントラストを調整できます。 #. このスクリプトを起動時に自動的に実行させたい場合は、それをRaspberry Pi Pico Wに ``main.py`` として保存できます。 **動作原理は?** Raspberry Pi Pico Wは、 :ref:`iot_access` で説明されているように、インターネットに接続する必要があります。このプロジェクトでは、そのまま使用します。 .. code-block:: python from do_connect import * do_connect() インターネットに接続した後、以下の数行のコードでPico Wの時刻をグリニッジ標準時に同期します。 .. code-block:: python import ntptime while True: try: ntptime.settime() print('Time Set Successfully') break except OSError: print('Time Setting...') continue LCDを初期化するには、 :ref:`py_lcd` を参照して、使用方法の詳細を確認してください。 .. code-block:: python from lcd1602 import LCD lcd=LCD() lcd.clear() string = 'Loading...' lcd.message(string) 天気データ(例:気温、風速)を取得する前に、単位を選択する必要があります。この場合、単位は ``metric`` です。 .. code-block:: python # Open Weather TEMPERATURE_UNITS = { "standard": "K", "metric": "°C", "imperial": "°F", } SPEED_UNITS = { "standard": "m/s", "metric": "m/s", "imperial": "mph", } units = "metric" 次に、この関数は ``openweathermap.org`` から天気データを取得します。 都市名、APIキー、設定された単位でURLメッセージを投稿します。 結果として、天気データが含まれる ``JSON`` ファイルを受け取ります。 .. code-block:: python def get_weather(city, api_key, units='metric', lang='en'): ''' Get weather data from openweathermap.org city: City name, state code and country code divided by comma, Please, refer to ISO 3166 for the state codes or country codes. https://www.iso.org/obp/ui/#search api_key: Your unique API key (you can always find it on your openweather account page under the "API key" tab https://home.openweathermap.org/api_keys) unit: Units of measurement. standard, metric and imperial units are available. If you do not use the units parameter, standard units will be applied by default. More: https://openweathermap.org/current#data lang: You can use this parameter to get the output in your language. More: https://openweathermap.org/current#multi ''' url = f"https://api.openweathermap.org/data/2.5/weather?q={city}&appid={api_key}&units={units}&lang={lang}" print(url) res = urequests.post(url) return res.json() この一連の生データを出力すると、以下に示すような情報が表示されます。 .. code-block:: python weather data example: { 'timezone': 28800, 'sys': { 'type': 2, 'sunrise': 1659650200, 'country': 'CN', 'id': 2031340, 'sunset': 1659697371 }, 'base': 'stations', 'main': { 'pressure': 1008, 'feels_like': 304.73, 'temp_max': 301.01, 'temp': 300.4, 'temp_min': 299.38, 'humidity': 91, 'sea_level': 1008, 'grnd_level': 1006 }, 'visibility': 10000, 'id': 1795565, 'clouds': { 'all': 96 }, 'coord': { 'lon': 114.0683, 'lat': 22.5455 }, 'name': 'Shenzhen', 'cod': 200, 'weather':[{ 'id': 804, 'icon': '04d', 'main': 'Clouds', 'description': 'overcast clouds' }], 'dt': 1659663579, 'wind': { 'gust': 7.06, 'speed': 3.69, 'deg': 146 } } ``print_weather(weather_data)`` 関数を使って、これらの生データを読みやすい形式に変換して出力します。 この関数は呼び出されていませんが、 ``while True`` 内で必要に応じてこの行をコメント解除できます。 .. image:: img/4_openweather3.png .. code-block:: python :emphasize-lines: 2 # シェル出力 print_weather(weather_data) ``while True`` ループでは、最初に ``get_weather()`` 関数が呼び出され、このプロジェクトに必要な ``weather`` 、 ``temperature`` 、 ``humidity`` 情報が取得されます。 .. code-block:: python weather_data = get_weather('shenzhen', secrets['openweather_api_key'], units=units) weather=weather_data["weather"][0]["main"] t=weather_data["main"]["temp"] rh=weather_data["main"]["humidity"] 現地時間を取得します。ここでは ``time.localtime()`` 関数が呼び出され、タプル(年、月、日、時間、分、秒、曜日、年日)のセットが返されます。この中から ``hour`` と ``minute`` を取り出しています。 すでにPico Wはグリニッジ標準時に同期されているため、あなたの地域のタイムゾーンを加える必要があります。 .. code-block:: python # 時間の取得(+24は西半球用) # 負の場合は24を加える # hours = time.localtime()[3] + int(weather_data["timezone"] / 3600) + 24 # 西半球のみ hours = time.localtime()[3] + int(weather_data["timezone"] / 3600) mins = time.localtime()[4] 最終的に、天気情報と時刻はLCD1602に表示されます。 .. code-block:: python lcd.clear() time.sleep_ms(200) string = f'{hours:02d}:{mins:02d} {weather}\n' lcd.message(string) string = f'{t}{TEMPERATURE_UNITS[units]} {rh}%rh' lcd.message(string) メインループが30秒ごとに実行されると、LCD1602は30秒ごとにリフレッシュする時計になります。