1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

fswebcamで撮影した画像をtwythonを使ってツイートする (アプリ開発)

Last updated at Posted at 2017-09-26

動機

元々は、文ちゃん(文鳥)の住んでるケージ周辺の日中の環境(温度・湿度)をモニターしたかったのが始まり。
その為、ラズパイでLチカから勉強し始めたんだけど、色々自理由をつけていつの間にかフェードアウト。。。
しばらくして、ラズパイとUSBカメラが接続できて、写真をキャプチャ出きる事を知り、
何かできそうなのでやってみようと方向転換。

よって今回の最終目標を、
写真で文ちゃんの日中の挙動をカメラで定期的に撮影し、Twitterに投稿する。そして仕事場から見て楽しむ:heart:
とした。

目次

  1. 使った機材
  2. 環境構築(ラズパイ&開発環境) 
  3. アプリ開発
  4. コードの置き場所とbotの紹介

前回は、目次2. 環境構築(ラズパイ&開発環境)まで説明したので、当記事は

    1. アプリ開発
    1. コードの置き場所とbotの紹介についてまとめる。

この記事で伝えたいこと

  1. 仕組み
  2. ハマったポイント

この記事で伝えないこと

  1. Twitter Application Managementでアプリの登録をする手順

仕組み

  1. crontabはshellをキック
  2. shellは、記述しているPythonスクリプトを実行
  3. Pythonスクリプトは、設定ファイルからtwitterで作成した
    • Consumer Key
    • Consumer Secret
    • Access Token
    • Access Token Secretを読み取る。
  4. fswebcamを実行し、撮影を行いファイルを保存する。
  5. 保存したファイルを読み込む。
  6. twythonを使ってtweetする。

1. crontabはshellをキック

何の変哲も無い設定。

raspberrypi% crontab -l
# hour:7-18 week:mon-fri
0,30 7-18 * * 1,2,3,4,5 /home/pi/code/git/twitterSample/twitterSample.sh >/dev/null 2>&1

2. shellは、中に記述しているPythonスクリプトを実行

開発はvirtualenvで構築した環境で行っていたので、pythonを直接実行するのではなくshellでvirutalenvのコマンドを実行しPythonを実行するようにした。

# !/bin/zsh
export CURRENT_PATH=`echo $(cd $(dirname $0) && pwd)`
export ENV_NAME=twitterSample
export VIRTUALENV_PATH=$CURRENT_PATH/$ENV_NAME

source $VIRTUALENV_PATH/bin/activate
python $CURRENT_PATH/twitterSample.py

参考リンク:[Shell] $(cd $(dirname $0) && pwd) を理解する

3以降はコード内で説明

Consumer Keyなどはtwitter.configとして記述

(twitterSample) raspberrypi% cat twitter.config
[KEY]
CONSUMER_KEY = xxxxxxxxxxxxxxxxxxxx
CONSUMER_SECRET = xxxxxxxxxxxxxxxxxxxx
ACCESS_TOKEN = xxxxxxxxxxxxxxxxxxxx
ACCESS_TOKEN_SECRET = xxxxxxxxxxxxxxxxxxxx
# -*- coding: utf-8 -*-

import subprocess
import sys
import configparser
from PIL import Image
import io
import os
from twython import Twython, TwythonError
from datetime import datetime

def tweet():

        // 3. Pythonスクリプトは、設定ファイルからtwitterで作成した云々の箇所
        // import configparserが必要。
        // twitter.configを読み込みconfig内にDictionaryとして展開。

        config = configparser.ConfigParser()
        config.read(os.path.dirname(os.path.abspath(__file__)) + '/twitter.config')

        twitter = Twython(
                config['KEY']['CONSUMER_KEY'],
                config['KEY']['CONSUMER_SECRET'],
                config['KEY']['ACCESS_TOKEN'],
                config['KEY']['ACCESS_TOKEN_SECRET']);

        #try:
        #       twitter.update_status(status='Tweet Sample')
        #except TwythonError as e:
        #       print(e)

        image_io = None
        try:

                // 4. fswebcamを実行し、撮影を行いファイルを保存するの箇所。
                // import subprocessが必要。

                subprocess.run('fswebcam -F 1 -S 20 -r 640x480 ' + os.path.dirname(os.path.abspath(__file__)) +  '/image.jpg', shell=True, check=True)

        except subprocess.CalledProcessError as e:
                print(e)

        else:
                // 5. 保存したファイルを読み込む。
                // from PIL import Imageが必要。

                photo = Image.open(os.path.dirname(os.path.abspath(__file__)) + '/image.jpg');
                image_io = io.BytesIO()
                photo.save(image_io, format='JPEG')

                image_io.seek(0)

        try:

                // 6. twythonを使ってtweetする。

                formattedDateTime = datetime.now().strftime("%Y/%m/%d %H:%M:%S")
                image_ids = twitter.upload_media(media=image_io)
                twitter.update_status(status="Captured at {time}".format(time=datetime.now().strftime("%Y/%m/%d %H:%M:%S")), media_ids=[image_ids['media_id']])

        except TwythonError as e:
                print(e)


if __name__ == '__main__':
        tweet()

ハマったポイント

読み込んだ画像を、upload_media()に指定すると失敗する。

キャプチャまではできていて、Tweetするタイミングで400 (Bad Request)が返却され失敗した。

(twitterSample) raspberrypi% python twitterSample.py

--- Opening /dev/video0...
Trying source module v4l2...
/dev/video0 opened.
No input was specified, using the first.
--- Capturing frame...
Skipping 20 frames...
Capturing 1 frames...
Captured 21 frames in 0.80 seconds. (26 fps)
--- Processing captured image...
Writing JPEG image to '/home/pi/code/git/twitterSample/image.jpg'.
Twitter API returned a 400 (Bad Request), An error occurred processing your request.

コードはtwythonのサンプルコードを元に書いていたので、
サンプルコードを見直すと以下の注意書きを発見。 これに気づいた時はサンプルよく見ろよーとツッコミ。

# If you do not seek(0), the image will be at the end of the file and
# unable to be read
image_io.seek(0)

Posting a Status with an Editing Image

python3で書いているとそんなモジュール無いYOと怒られる

ここは仕方がないので、出てきたエラーをコピーして "python3 出てきたエラー"で検索して都度置き換え。

コードの置き場所とbotの紹介

Code
Twitter

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?