質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.34%

  • Python

    9136questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

  • Raspberry Pi

    890questions

    Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。

Raspberry piで天気予報を実行したいのですがエラーが出て実行できません。

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 1,281

techno

score 10

前提・実現したいこと

raspberry piでPythonを使って天気予報を読み上げるというプログラムを実行したいのですがエラーがでて実行できませんでした。
僕が質問する前に他の方が同じ内容で苦しんでいらっしゃったのですが全く同じ内容ででした。その方はプログラムを置いてある場所じゃ無い所で実行していた為実行出来なかったとの事です。

発生している問題・エラーメッセージ

jsay 310日、16488秒
Traceback (most recent call last):
  File "tenki.py", line 54, in <module>
    main()
  File "tenki.py", line 12, in main
    say_datetime()
  File "tenki.py", line 20, in say_datetime
    proc = subprocess.Popen(shlex.split(text))
  File "/usr/lib/python2.7/subprocess.py", line 710, in __init__
    errread, errwrite)
  File "/usr/lib/python2.7/subprocess.py", line 1335, in _execute_child
    raise child_exception
OSError: [Errno 8] Exec format error

該当のソースコード

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import shlex
import subprocess
from datetime import datetime
import urllib2
import json

CMD_SAY = 'jsay'
def main():
    say_datetime()
    say_weather()
    return
def say_datetime():
    d = datetime.now()
    text = '%s月%s日、%s時%s分%s秒' % (d.month, d.day, d.hour, d.minute, d.second)
    text = CMD_SAY + ' ' + text
    print text
    proc = subprocess.Popen(shlex.split(text))
    proc.communicate()
    return
def say_weather():
    city = '230010'; # Tokyo 他の地域の方は、番号を変えてください。
    json_url = 'http://weather.livedoor.com/forecast/webservice/json/v1' #API URL
    weather_text = u'%sの天気は%sです。'
    temperature_text = u'%sの予想最高気温、%s度、予想最低気温、%s度です。'
    try:
        r = urllib2.urlopen('%s?city=%s' % (json_url, city) )
        obj = json.loads( unicode(r.read()) )
        title = obj['title']
        forecasts = obj['forecasts']
        # TODAY
        cast = forecasts[0]
        temperature = cast['temperature']
        today_w_txt = weather_text % (cast['dateLabel'], cast['telop'])
        today_t_txt = temperature_text % (cast['dateLabel'], temperature['max']['celsius'], temperature['min']['celsius'])
        # TOMMOROW
        cast = forecasts[1]
        temperature = cast['temperature']
        tommorow_w_txt = weather_text % (cast['dateLabel'], cast['telop'])
        # SAY
        weather_str = title + ' ' + today_w_txt + ' ' + today_t_txt + ' ' + tommorow_w_txt
        weather_str = weather_str.encode('utf-8')
        text = '''%s '%s' ''' % (CMD_SAY, weather_str)
        print text
        proc = subprocess.Popen(shlex.split(text))
        proc.communicate()
    finally:
        r.close()
    return
### Execute
if __name__ == "__main__":
    main()

試したこと

下記のサイトさんを拝見しましてエラーが出る構文を調べたりしましたが全く分からずこのサイトに希望をかけた次第です

http://raspi.seesaa.net/article/415530289.html
http://www.tapun.net/raspi/raspberry-pi-talk-weather

補足情報(言語/FW/ツール等のバージョンなど)

python初心者なので何か目的を持ってプログラミング出来ればと思いpythonが標準で入っているRasbperry piで天気予報を喋ってもらうプログラムを作成したくいろいろ調べていたらたどり着いた次第です

使用いているRaspberry piは
Raspberry Pi3 Model Bです
Open Jtalkはインストール済みでコマンドを入力すればその言葉を喋ってくれるところまでは出来ました。

こういう質問サイトで質問するのは初めてなのでまだまだ言葉足らずやそのほか至らぬ点が多々あると思います。藁をもつかむ思いです、何かアドバイス等頂けらたと思います。よろしくお願いいたします。

***追記

can110 さんにご指摘頂きjsayのプログラムを確認した所「#!/bin/sh」が記述されていませんでした。早速記述し実行した所次のようなエラーが出ました。

↓エラー

jsay 314日、1706秒
Traceback (most recent call last):
  File "tenki2.py", line 52, in <module>
    main()
  File "tenki2.py", line 11, in main
    say_weather()
  File "tenki2.py", line 35, in say_weather
    today_t_txt = temperature_text % (cast['dateLabel'], temperature['max']['celsius'], temperature['min']['celsius'])
TypeError: 'NoneType' object has no attribute '__getitem__'


です。

更にcan110 さんに助言して頂きプログラムを追加致しました
↓追加

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import shlex
import subprocess
from datetime import datetime
import urllib2
import json

CMD_SAY = 'jsay'
def main():
    say_datetime()
    say_weather()
    return
def say_datetime():
    d = datetime.now()
    text = '%s月%s日、%s時%s分%s秒' % (d.month, d.day, d.hour, d.minute, d.second)
    text = CMD_SAY + ' ' + text
    print text
    proc = subprocess.Popen(shlex.split(text))
    proc.communicate()
    return
def say_weather():
    city = '130010'; # Tokyo 他の地域の方は、番号を変えてください。
    json_url = 'http://weather.livedoor.com/forecast/webservice/json/v1' #API URL
    weather_text = u'%sの天気は%sです。'
    temperature_text = u'%sの予想最高気温、%s度、予想最低気温、%s度です。'
    try:
        jsonStr = unicode(r.read())
        print(jsonStr)  # 確認表示
        obj = json.loads( jsonStr )
        print(obj)      # 確認表示
        title = obj['title']
        forecasts = obj['forecasts']
        # TODAY
        cast = forecasts[0]
        temperature = cast['temperature']
        today_w_txt = weather_text % (cast['dateLabel'], cast['telop'])
        # 最高、最低気温を取得。データが存在しない場合もある
        temp_max = ""
        temp_min = ""
        if temperature['max'] is not None:
            temp_max = temperature['max']['celsius']
        if temperature['min'] is not None:
            temp_max = temperature['min']['celsius']

        today_t_txt = temperature_text % (cast['dateLabel'], temp_max, temp_min)
        # TOMMOROW
        cast = forecasts[1]
        temperature = cast['temperature']
        tommorow_w_txt = weather_text % (cast['dateLabel'], cast['telop'])
        # SAY
        weather_str = title + ' ' + today_w_txt + ' ' + today_t_txt + ' ' + tommorow_w_txt
        weather_str = weather_str.encode('utf-8')
        text = '''%s '%s' ''' % (CMD_SAY, weather_str)
        print text
        proc = subprocess.Popen(shlex.split(text,))
        proc.communicate()
    finally:
        r.close()
    return
### Execute
if __name__ == "__main__":
    main()

と記述
結果

jsay 314日、17436秒
Traceback (most recent call last):
  File "tenki.py", line 64, in <module>
    main()
  File "tenki.py", line 13, in main
    say_weather()
  File "tenki.py", line 60, in say_weather
    r.close()
NameError: global name 'r' is not defined

となりました。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • can110

    2017/03/14 12:52

    パーミッションについてはjsayのほうを知りたかったのですが、実行できたのでよいです。

    キャンセル

  • can110

    2017/03/14 13:00

    できればこれまでの流れ(「#!/bin/sh」追加で動作~次のエラー内容)を質問本文にも転記ください。

    キャンセル

  • can110

    2017/03/14 17:13

    「try:」行の次「r = urllib2.urlopen('%s?city=%s' % (json_url, city) )」 の行が抜けています。

    キャンセル

回答 2

checkベストアンサー

0

say_datetime関数は成功したものとして、次のエラーについての回答です。

http://weather.livedoor.com/forecast/webservice/json/v1からの返信データ形式が以前と変わったなどので理由で、以降のデータを抽出する処理が正しく動作していない可能性があります。
以下のようにして返信データの内容を表示し、提示ください。

r = urllib2.urlopen('%s?city=%s' % (json_url, city) )

        # 以下のように書き換える
        jsonStr = unicode(r.read())
        print(jsonStr)  # 確認表示
        obj = json.loads( jsonStr )
        print(obj)      # 確認表示

        title = obj['title']
           :

検証結果を追記

こちらの環境(Win10)で試したところ、返信データ中にお天気Webサービス仕様に記載されているmin・・・最低気温データが存在しませんでした(季節による?)。以下のようにするとデータなしでもjsay処理前までは正しく動作しました。こちらJTalk環境ないのでそれ以降は未検証です。

(略)
        today_w_txt = weather_text % (cast['dateLabel'], cast['telop'])

        # 最高、最低気温を取得。データが存在しない場合もある
        temp_max = ""
        temp_min = ""
        if temperature['max'] is not None:
            temp_max = temperature['max']['celsius']
        if temperature['min'] is not None:
            temp_max = temperature['min']['celsius']

        today_t_txt = temperature_text % (cast['dateLabel'], temp_max, temp_min)
(略)

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/03/14 17:11

    お返事遅れてしまい申し訳ありません。いろいろ調べて頂いてありがとうございます。状況をまとめてみました。確認して頂けると幸いです

    キャンセル

  • 2017/03/14 17:40

    「try:」行の次「r = urllib2.urlopen('%s?city=%s' % (json_url, city) )」 の行(Webから気象データを取得する処理)が抜けちゃってますので追加してください。

    キャンセル

  • 2017/03/14 17:57

    can110さん出来ました!!!親身になってご教示くださり心からありがとうございます。本当に嬉しいです
    ありがとうございました。

    キャンセル

  • 2017/03/14 18:02

    無事に動いてよかったです。自分もRaspPiで試してみようと思います。

    キャンセル

0

手元にraspberry piがないため、プログラムを実行してはいないのですが、Popenの引数にshell=Trueをつけたら動くと思います。
(以前似たようなプログラムを作ったんですが、shellscriptを動かすときはshell=Trueをつけないと動かなかった気がします。間違っていたらすみません。。。)

subprocess.Popen(text, shell=True)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/03/13 13:46

    KaiShoyaさんお返事して頂いてありがとうございます
    お返事遅れてしまって申し訳ありません

    早速、KaiShoyaさんから助言したいただいたプログラムを追加記述してみましたが結果は変わらずでした。

    自分の方でも「shellscript」と言うヒントも頂けたので記述の意味(ここはこの構文を使うとか)をいろいろ調べながら引き続き模索していきたいと思っております。
    ありがとうございます

    キャンセル

同じタグがついた質問を見る

  • Python

    9136questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

  • Raspberry Pi

    890questions

    Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。