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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Raspberry Pi

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

Python

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

Q&A

解決済

2回答

3663閲覧

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

techno

総合スコア22

Raspberry Pi

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

Python

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

0グッド

1クリップ

投稿2017/03/10 08:11

編集2017/03/14 08:09

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

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

python

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

###該当のソースコード

python

1#!/usr/bin/env python 2# -*- coding:utf-8 -*- 3 4import shlex 5import subprocess 6from datetime import datetime 7import urllib2 8import json 9 10CMD_SAY = 'jsay' 11def main(): 12 say_datetime() 13 say_weather() 14 return 15def say_datetime(): 16 d = datetime.now() 17 text = '%s月%s日、%s時%s分%s秒' % (d.month, d.day, d.hour, d.minute, d.second) 18 text = CMD_SAY + ' ' + text 19 print text 20 proc = subprocess.Popen(shlex.split(text)) 21 proc.communicate() 22 return 23def say_weather(): 24 city = '230010'; # Tokyo 他の地域の方は、番号を変えてください。 25 json_url = 'http://weather.livedoor.com/forecast/webservice/json/v1' #API URL 26 weather_text = u'%sの天気は%sです。' 27 temperature_text = u'%sの予想最高気温、%s度、予想最低気温、%s度です。' 28 try: 29 r = urllib2.urlopen('%s?city=%s' % (json_url, city) ) 30 obj = json.loads( unicode(r.read()) ) 31 title = obj['title'] 32 forecasts = obj['forecasts'] 33 # TODAY 34 cast = forecasts[0] 35 temperature = cast['temperature'] 36 today_w_txt = weather_text % (cast['dateLabel'], cast['telop']) 37 today_t_txt = temperature_text % (cast['dateLabel'], temperature['max']['celsius'], temperature['min']['celsius']) 38 # TOMMOROW 39 cast = forecasts[1] 40 temperature = cast['temperature'] 41 tommorow_w_txt = weather_text % (cast['dateLabel'], cast['telop']) 42 # SAY 43 weather_str = title + ' ' + today_w_txt + ' ' + today_t_txt + ' ' + tommorow_w_txt 44 weather_str = weather_str.encode('utf-8') 45 text = '''%s '%s' ''' % (CMD_SAY, weather_str) 46 print text 47 proc = subprocess.Popen(shlex.split(text)) 48 proc.communicate() 49 finally: 50 r.close() 51 return 52### Execute 53if __name__ == "__main__": 54 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」が記述されていませんでした。早速記述し実行した所次のようなエラーが出ました。

↓エラー

python

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

です。

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

python

1 2#!/usr/bin/env python 3# -*- coding:utf-8 -*- 4 5import shlex 6import subprocess 7from datetime import datetime 8import urllib2 9import json 10 11CMD_SAY = 'jsay' 12def main(): 13 say_datetime() 14 say_weather() 15 return 16def say_datetime(): 17 d = datetime.now() 18 text = '%s月%s日、%s時%s分%s秒' % (d.month, d.day, d.hour, d.minute, d.second) 19 text = CMD_SAY + ' ' + text 20 print text 21 proc = subprocess.Popen(shlex.split(text)) 22 proc.communicate() 23 return 24def say_weather(): 25 city = '130010'; # Tokyo 他の地域の方は、番号を変えてください。 26 json_url = 'http://weather.livedoor.com/forecast/webservice/json/v1' #API URL 27 weather_text = u'%sの天気は%sです。' 28 temperature_text = u'%sの予想最高気温、%s度、予想最低気温、%s度です。' 29 try: 30 jsonStr = unicode(r.read()) 31 print(jsonStr) # 確認表示 32 obj = json.loads( jsonStr ) 33 print(obj) # 確認表示 34 title = obj['title'] 35 forecasts = obj['forecasts'] 36 # TODAY 37 cast = forecasts[0] 38 temperature = cast['temperature'] 39 today_w_txt = weather_text % (cast['dateLabel'], cast['telop']) 40 # 最高、最低気温を取得。データが存在しない場合もある 41 temp_max = "" 42 temp_min = "" 43 if temperature['max'] is not None: 44 temp_max = temperature['max']['celsius'] 45 if temperature['min'] is not None: 46 temp_max = temperature['min']['celsius'] 47 48 today_t_txt = temperature_text % (cast['dateLabel'], temp_max, temp_min) 49 # TOMMOROW 50 cast = forecasts[1] 51 temperature = cast['temperature'] 52 tommorow_w_txt = weather_text % (cast['dateLabel'], cast['telop']) 53 # SAY 54 weather_str = title + ' ' + today_w_txt + ' ' + today_t_txt + ' ' + tommorow_w_txt 55 weather_str = weather_str.encode('utf-8') 56 text = '''%s '%s' ''' % (CMD_SAY, weather_str) 57 print text 58 proc = subprocess.Popen(shlex.split(text,)) 59 proc.communicate() 60 finally: 61 r.close() 62 return 63### Execute 64if __name__ == "__main__": 65 main() 66

と記述
結果

python

1 2jsay 314日、174363Traceback (most recent call last): 4 File "tenki.py", line 64, in <module> 5 main() 6 File "tenki.py", line 13, in main 7 say_weather() 8 File "tenki.py", line 60, in say_weather 9 r.close() 10NameError: global name 'r' is not defined 11

となりました。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

can110

2017/03/13 10:15

シェル上で.pyファイルがある場所に移動し「jsay 3月10日、16時48分8秒」と実行した結果を提示ください。(成功するか?jsayにパスは通っているか?の確認)
techno

2017/03/14 00:37

can110さんお返事ありがとうございます「pi@raspberrypi:~$ jsay 3月10日、16時48分8秒 改行  pi@raspberrypi:~$ 」ですちゃんと喋ってくれました。
can110

2017/03/14 01:12

jsayファイルの内容(先頭行に「#!/bin/sh」があるか?)とパーミッション(775など)を提示ください。
techno

2017/03/14 02:55

can110さん、のご指摘のファイルの内容なのですが「#!/bin/sh」が記述されていませんでした。早速記述しました所上記のエラー内容とは違うエラーが表示されました。     today_t_txt = temperature_text % (cast['dateLabel'], temperature['max']['celsius'], temperature['min']['celsius']) TypeError: 'NoneType' object has no attribute '__getitem__'    です。パーミッションはこれで合ってますでしょうか?-rw-r--r-- 1 pi pi 1887 3月 14 11:49 tenki.py  (天気予報のファイル名は「tenki.py」と言う名前にしてあります)
can110

2017/03/14 03:50

say_datetime関数までは正常に動作したということでしょうか?であれば一歩前進なのでよかったです。
can110

2017/03/14 03:52

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

2017/03/14 04:00

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

2017/03/14 08:13

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

回答2

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環境ないのでそれ以降は未検証です。

Python

1(略) 2 today_w_txt = weather_text % (cast['dateLabel'], cast['telop']) 3 4 # 最高、最低気温を取得。データが存在しない場合もある 5 temp_max = "" 6 temp_min = "" 7 if temperature['max'] is not None: 8 temp_max = temperature['max']['celsius'] 9 if temperature['min'] is not None: 10 temp_max = temperature['min']['celsius'] 11 12 today_t_txt = temperature_text % (cast['dateLabel'], temp_max, temp_min) 13(略)

投稿2017/03/14 03:58

編集2017/03/14 04:59
can110

総合スコア38262

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

techno

2017/03/14 08:11

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

2017/03/14 08:40

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

2017/03/14 08:57

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

2017/03/14 09:02

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

0

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

python

1subprocess.Popen(text, shell=True)

投稿2017/03/10 09:02

KaiShoya

総合スコア551

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

techno

2017/03/13 04:46

KaiShoyaさんお返事して頂いてありがとうございます お返事遅れてしまって申し訳ありません 早速、KaiShoyaさんから助言したいただいたプログラムを追加記述してみましたが結果は変わらずでした。 自分の方でも「shellscript」と言うヒントも頂けたので記述の意味(ここはこの構文を使うとか)をいろいろ調べながら引き続き模索していきたいと思っております。 ありがとうございます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問